Esempio n. 1
0
NTSTATUS
FatFsdDeviceControl (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the FSD part of Device control operations

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the
        file exists

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The FSD status for the IRP

--*/

{
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel;

#ifdef	__ND_FAT__

	PIO_STACK_LOCATION	irpSp = IoGetCurrentIrpStackLocation( Irp );

	if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL && FatData.DiskFileSystemDeviceObject == (PDEVICE_OBJECT)VolumeDeviceObject) {

		switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {

		case IOCTL_REGISTER_NDFS_CALLBACK: {

			PNDFS_CALLBACK	inputBuffer			= (PNDFS_CALLBACK)Irp->AssociatedIrp.SystemBuffer;
			ULONG			inputBufferLength	= irpSp->Parameters.DeviceIoControl.InputBufferLength;


			if( inputBufferLength != sizeof( VolumeDeviceObject->NdfsCallback ) ) {

				Status = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
				Irp->IoStatus.Information = 0;
				break;
			} 
			
			DebugTrace2( 0, Dbg2, ("NtfsFsdDispatch: IOCTL_REGISTER_NDFS_CALLBACK, size = %d\n", inputBuffer->Size) );		

			RtlCopyMemory( &VolumeDeviceObject->NdfsCallback, inputBuffer, sizeof(VolumeDeviceObject->NdfsCallback) );

			Status = Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = 0;
			
			break;
		}
	
		case IOCTL_UNREGISTER_NDFS_CALLBACK:

			DebugTrace2( 0, Dbg2, ("NtfsFsdDispatch: IOCTL_UNREGISTER_NDFS_CALLBACK\n") );		

			RtlZeroMemory( &VolumeDeviceObject->NdfsCallback, sizeof(VolumeDeviceObject->NdfsCallback) );

			Status = Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = 0;

			break;

		case IOCTL_SHUTDOWN: {
			
			PLIST_ENTRY				vcbListEntry;

			DebugTrace2( 0, Dbg2, ("NtfsFsdDispatch: IOCTL_SHUTDOWN\n") );		

	        for (vcbListEntry = FatData.VcbQueue.Flink;
			     vcbListEntry != &FatData.VcbQueue;
				 vcbListEntry = vcbListEntry->Flink) {

				PVCB					vcb = NULL;
#ifdef __ND_FAT_PRIMARY__
				PLIST_ENTRY				primarySessionListEntry;
#endif
				PVOLUME_DEVICE_OBJECT	volDo = NULL;


				DebugTrace2( 0, Dbg2, ("NtfsFsdDispatch: volDo = %p, KeGetCurrentIrql() = %d\n", volDo, KeGetCurrentIrql()) );		

				vcb = CONTAINING_RECORD(vcbListEntry, VCB, VcbLinks);
				volDo = CONTAINING_RECORD( vcb, VOLUME_DEVICE_OBJECT, Vcb );

				//DbgPrint( "NtfsFsdDispatch: ND_FAT_DEVICE_FLAG_SHUTDOWN\n" );		
				SetFlag( volDo->NdFatFlags, ND_FAT_DEVICE_FLAG_SHUTDOWN );

		
#ifdef __ND_FAT_PRIMARY__

				for (primarySessionListEntry = volDo->PrimarySessionQueue.Flink;
					 primarySessionListEntry != &volDo->PrimarySessionQueue; ) {

					PPRIMARY_SESSION primarySession;

					primarySession = CONTAINING_RECORD( primarySessionListEntry, PRIMARY_SESSION, ListEntry );
					primarySessionListEntry = primarySessionListEntry->Flink;
					PrimarySession_Reference( primarySession );
		
					PrimarySession_FileSystemShutdown( primarySession );

					RemoveEntryList( &primarySession->ListEntry );
					InitializeListHead(  &primarySession->ListEntry );
					PrimarySession_Dereference( primarySession );
				}
#endif
			}

			Status = Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = 0;
			DebugTrace2( 0, Dbg2, ("NtfsFsdDispatch: IOCTL_SHUTDOWN return\n") );		

			break;
		}

		default:
				
			ASSERT( FALSE );
			Status = Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
			Irp->IoStatus.Information = 0;
		}

		IoCompleteRequest( Irp, IO_DISK_INCREMENT );
		return Status;
	}

	//if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL && 
	//	IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode == IOCTL_INSERT_PRIMARY_SESSION) {

    //    return NtfsFsdDispatchSwitch( NULL, Irp, FALSE );
	//}

#endif

    DebugTrace(+1, Dbg, "FatFsdDeviceControl\n", 0);

    FsRtlEnterFileSystem();

    TopLevel = FatIsIrpTopLevel( Irp );

    try {

#ifdef __ND_FAT__

		if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_DEVICE_CONTROL && 
			IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode == IOCTL_INSERT_PRIMARY_SESSION) {

			IrpContext = FatCreateIrpContext( Irp, FALSE );
		
		} else {

			IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ));
		}



#else
		IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ));
#endif

        Status = FatCommonDeviceControl( IrpContext, Irp );

    } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

        //
        //  We had some trouble trying to perform the requested
        //  operation, so we'll abort the I/O request with
        //  the error status that we get back from the
        //  execption code
        //

        Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
    }

    if (TopLevel) { IoSetTopLevelIrp( NULL ); }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

    DebugTrace(-1, Dbg, "FatFsdDeviceControl -> %08lx\n", Status);

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    return Status;
}
Esempio n. 2
0
VOID
CdFspDispatch (
    IN PIRP_CONTEXT IrpContext
    )

/*++

Routine Description:

    This is the main FSP thread routine that is executed to receive
    and dispatch IRP requests.  Each FSP thread begins its execution here.
    There is one thread created at system initialization time and subsequent
    threads created as needed.

Arguments:

    IrpContext - IrpContext for a request to process.

Return Value:

    None

--*/

{
    THREAD_CONTEXT ThreadContext;
    NTSTATUS Status;

    PIRP Irp = IrpContext->Irp;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

    PVOLUME_DEVICE_OBJECT VolDo = NULL;

    //
    //  If this request has an associated volume device object, remember it.
    //

    if (IrpSp->FileObject != NULL) {

        VolDo = CONTAINING_RECORD( IrpSp->DeviceObject,
                                   VOLUME_DEVICE_OBJECT,
                                   DeviceObject );
    }

    //
    //  Now case on the function code.  For each major function code,
    //  either call the appropriate worker routine.  This routine that
    //  we call is responsible for completing the IRP, and not us.
    //  That way the routine can complete the IRP and then continue
    //  post processing as required.  For example, a read can be
    //  satisfied right away and then read can be done.
    //
    //  We'll do all of the work within an exception handler that
    //  will be invoked if ever some underlying operation gets into
    //  trouble.
    //

    while ( TRUE ) {

        //
        //  Set all the flags indicating we are in the Fsp.
        //

        SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS );

        FsRtlEnterFileSystem();

        CdSetThreadContext( IrpContext, &ThreadContext );

        while (TRUE) {

            try {

                //
                //  Reinitialize for the next try at completing this
                //  request.
                //

                Status =
                IrpContext->ExceptionStatus = STATUS_SUCCESS;

                //
                //  Initialize the Io status field in the Irp.
                //

                Irp->IoStatus.Status = STATUS_SUCCESS;
                Irp->IoStatus.Information = 0;

                //
                //  Case on the major irp code.
                //

                switch (IrpContext->MajorFunction) {

                case IRP_MJ_CREATE :

                    CdCommonCreate( IrpContext, Irp );
                    break;

                case IRP_MJ_CLOSE :

                    ASSERT( FALSE );
                    break;

                case IRP_MJ_READ :

                    CdCommonRead( IrpContext, Irp );
                    break;

                case IRP_MJ_QUERY_INFORMATION :

                    CdCommonQueryInfo( IrpContext, Irp );
                    break;

                case IRP_MJ_SET_INFORMATION :

                    CdCommonQueryInfo( IrpContext, Irp );
                    break;

                case IRP_MJ_QUERY_VOLUME_INFORMATION :

                    CdCommonQueryVolInfo( IrpContext, Irp );
                    break;

                case IRP_MJ_DIRECTORY_CONTROL :

                    CdCommonDirControl( IrpContext, Irp );
                    break;

                case IRP_MJ_FILE_SYSTEM_CONTROL :

                    CdCommonFsControl( IrpContext, Irp );
                    break;

                case IRP_MJ_DEVICE_CONTROL :

                    CdCommonDevControl( IrpContext, Irp );
                    break;

                case IRP_MJ_LOCK_CONTROL :

                    CdCommonLockControl( IrpContext, Irp );
                    break;

                case IRP_MJ_CLEANUP :

                    CdCommonCleanup( IrpContext, Irp );
                    break;

                default :

                    Status = STATUS_INVALID_DEVICE_REQUEST;
                    CdCompleteRequest( IrpContext, Irp, Status );
                }

            } except( CdExceptionFilter( IrpContext, GetExceptionInformation() )) {

                Status = CdProcessException( IrpContext, Irp, GetExceptionCode() );
            }

            //
            //  Break out of the loop if we didn't get CANT_WAIT.
            //

            if (Status != STATUS_CANT_WAIT) { break; }

            //
            //  We are retrying this request.  Cleanup the IrpContext for the retry.
            //

            SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
            CdCleanupIrpContext( IrpContext, FALSE );
        }

        FsRtlExitFileSystem();

        //
        //  If there are any entries on this volume's overflow queue, service
        //  them.
        //

        if (VolDo != NULL) {

            KIRQL SavedIrql;
            PVOID Entry = NULL;

            //
            //  We have a volume device object so see if there is any work
            //  left to do in its overflow queue.
            //

            KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql );

            if (VolDo->OverflowQueueCount > 0) {

                //
                //  There is overflow work to do in this volume so we'll
                //  decrement the Overflow count, dequeue the IRP, and release
                //  the Event
                //

                VolDo->OverflowQueueCount -= 1;

                Entry = RemoveHeadList( &VolDo->OverflowQueue );
            }

            KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql );

            //
            //  There wasn't an entry, break out of the loop and return to
            //  the Ex Worker thread.
            //

            if (Entry == NULL) { break; }

            //
            //  Extract the IrpContext , Irp, set wait to TRUE, and loop.
            //

            IrpContext = CONTAINING_RECORD( Entry,
                                            IRP_CONTEXT,
                                            WorkQueueItem.List );

            Irp = IrpContext->Irp;
            IrpSp = IoGetCurrentIrpStackLocation( Irp );

            continue;
        }

        break;
    }

    //
    //  Decrement the PostedRequestCount if there was a volume device object.
    //

    if (VolDo) {

        InterlockedDecrement( &VolDo->PostedRequestCount );
    }

    return;
}
Esempio n. 3
0
BOOLEAN
UdfFastQueryNetworkInfo (
    IN PFILE_OBJECT FileObject,
    IN BOOLEAN Wait,
    OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
    OUT PIO_STATUS_BLOCK IoStatus,
    IN PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This routine is for the fast query call for network file information.

Arguments:

    FileObject - Supplies the file object used in this operation

    Wait - Indicates if we are allowed to wait for the information

    Buffer - Supplies the output buffer to receive the basic information

    IoStatus - Receives the final status of the operation

Return Value:

    BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
        needs to take the long route.

--*/

{
    BOOLEAN Result = FALSE;
    TYPE_OF_OPEN TypeOfOpen;

    PFCB Fcb;
    PCCB Ccb;

    PAGED_CODE();

    ASSERT_FILE_OBJECT( FileObject );

    FsRtlEnterFileSystem();

    //
    //  Decode the file object to find the type of open and the data
    //  structures.
    //

    TypeOfOpen = UdfDecodeFileObject( FileObject, &Fcb, &Ccb );

    //
    //  We only support this request on user file or directory objects.
    //

    if (TypeOfOpen != UserFileOpen && TypeOfOpen != UserDirectoryOpen) {

        FsRtlExitFileSystem();
        return FALSE;
    }

    //
    //  Acquire the file shared to access the Fcb.
    //

    if (!ExAcquireResourceShared( Fcb->Resource, Wait )) {

        FsRtlExitFileSystem();
        return FALSE;
    }

    //
    //  Use a try-finally to facilitate cleanup.
    //

    try {

        //
        //  Only deal with 'good' Fcb's.
        //

        if (UdfVerifyFcbOperation( NULL, Fcb )) {

            //
            //  Fill in the input buffer from the Fcb fields.
            //

            Buffer->CreationTime = Fcb->Timestamps.CreationTime;
            Buffer->LastWriteTime =
            Buffer->ChangeTime =  Fcb->Timestamps.ModificationTime;
            Buffer->LastAccessTime = Fcb->Timestamps.AccessTime;

            Buffer->FileAttributes = Fcb->FileAttributes | UdfGetExtraFileAttributes( Ccb );

            //
            //  Check whether this is a directory.
            //

            if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {

                Buffer->AllocationSize.QuadPart =
                Buffer->EndOfFile.QuadPart = 0;

            } else {

                Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart;
                Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart;
            }

            //
            //  Update the IoStatus block with the size of this data.
            //

            IoStatus->Status = STATUS_SUCCESS;
            IoStatus->Information = sizeof( FILE_NETWORK_OPEN_INFORMATION );

            Result = TRUE;
        }

    } finally {

        ExReleaseResource( Fcb->Resource );

        FsRtlExitFileSystem();
    }

    return Result;
}
Esempio n. 4
0
NTSTATUS
NtfsFsdQuerySecurityInfo (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the FSD part of the Query Security Information API
    calls.

Arguments:

    VolumeDeviceObject - Supplies the device object to use.

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The Fsd status for the Irp

--*/

{
    TOP_LEVEL_CONTEXT TopLevelContext;
    PTOP_LEVEL_CONTEXT ThreadTopLevelContext;

    NTSTATUS Status = STATUS_SUCCESS;
    PIRP_CONTEXT IrpContext = NULL;

    ASSERT_IRP( Irp );

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    PAGED_CODE();

    DebugTrace( +1, Dbg, ("NtfsFsdQuerySecurityInfo\n") );

    //
    //  Call the common query Information routine
    //

    FsRtlEnterFileSystem();

    ThreadTopLevelContext = NtfsSetTopLevelIrp( &TopLevelContext, FALSE, FALSE );

    do {

        try {

            //
            //  We are either initiating this request or retrying it.
            //

            if (IrpContext == NULL) {

                IrpContext = NtfsCreateIrpContext( Irp, CanFsdWait( Irp ) );
                NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext );

            } else if (Status == STATUS_LOG_FILE_FULL) {

                NtfsCheckpointForLogFileFull( IrpContext );
            }

            Status = NtfsCommonQuerySecurityInfo( IrpContext, Irp );
            break;

        } except(NtfsExceptionFilter( IrpContext, GetExceptionInformation() )) {

            //
            //  We had some trouble trying to perform the requested
            //  operation, so we'll abort the I/O request with
            //  the error status that we get back from the
            //  execption code
            //

            Status = NtfsProcessException( IrpContext, Irp, GetExceptionCode() );
        }

    } while (Status == STATUS_CANT_WAIT ||
             Status == STATUS_LOG_FILE_FULL);

    if (ThreadTopLevelContext == &TopLevelContext) {
        NtfsRestoreTopLevelIrp( ThreadTopLevelContext );
    }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

    DebugTrace( -1, Dbg, ("NtfsFsdQuerySecurityInfo -> %08lx\n", Status) );

    return Status;
}
Esempio n. 5
0
File: pnp.c Progetto: GYGit/reactos
NTSTATUS STDCALL drv_pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
    device_extension* Vcb = DeviceObject->DeviceExtension;
    NTSTATUS Status;
    BOOL top_level;

    FsRtlEnterFileSystem();

    top_level = is_top_level(Irp);
    
    Status = STATUS_NOT_IMPLEMENTED;
    
    switch (IrpSp->MinorFunction) {
        case IRP_MN_CANCEL_REMOVE_DEVICE:
            Status = pnp_cancel_remove_device(DeviceObject, Irp);
            break;

        case IRP_MN_QUERY_REMOVE_DEVICE:
            Status = pnp_query_remove_device(DeviceObject, Irp);
            break;

        case IRP_MN_REMOVE_DEVICE:
            Status = pnp_remove_device(DeviceObject, Irp);
            break;

        case IRP_MN_START_DEVICE:
            Status = pnp_start_device(DeviceObject, Irp);
            break;

        case IRP_MN_SURPRISE_REMOVAL:
            Status = pnp_surprise_removal(DeviceObject, Irp);
            break;

        default:
            TRACE("passing minor function 0x%x on\n", IrpSp->MinorFunction);
            
            IoSkipCurrentIrpStackLocation(Irp);
            Status = IoCallDriver(Vcb->devices[0].devobj, Irp);
            goto end;
    }

// //     Irp->IoStatus.Status = Status;
// //     Irp->IoStatus.Information = 0;
// 
//     IoSkipCurrentIrpStackLocation(Irp);
//     
//     Status = IoCallDriver(Vcb->devices[0].devobj, Irp);
// 
// //     IoCompleteRequest(Irp, IO_NO_INCREMENT);

    Irp->IoStatus.Status = Status;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
end:
    if (top_level) 
        IoSetTopLevelIrp(NULL);
    
    FsRtlExitFileSystem();

    return Status;
}
Esempio n. 6
0
BOOLEAN
Ext2FastIoCheckIfPossible (
    IN PFILE_OBJECT         FileObject,
    IN PLARGE_INTEGER       FileOffset,
    IN ULONG                Length,
    IN BOOLEAN              Wait,
    IN ULONG                LockKey,
    IN BOOLEAN              CheckForReadOperation,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject
)
{
    BOOLEAN          bPossible = FastIoIsNotPossible;
    PEXT2_FCB        Fcb;
    PEXT2_CCB        Ccb;
    LARGE_INTEGER    lLength;

    lLength.QuadPart = Length;

    __try {

        FsRtlEnterFileSystem();

        __try {

            if (IsExt2FsDevice(DeviceObject)) {
                __leave;
            }

            Fcb = (PEXT2_FCB) FileObject->FsContext;
            if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
                __leave;
            }

            ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
                   (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

            if (IsDirectory(Fcb)) {
                __leave;
            }

            Ccb = (PEXT2_CCB) FileObject->FsContext2;
            if (Ccb == NULL) {
                __leave;
            }

            if (CheckForReadOperation) {

                bPossible = FsRtlFastCheckLockForRead(
                                &Fcb->FileLockAnchor,
                                FileOffset,
                                &lLength,
                                LockKey,
                                FileObject,
                                PsGetCurrentProcess());

            } else {

                if (!(IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) ||
                        IsFlagOn(Fcb->Vcb->Flags, VCB_WRITE_PROTECTED))) {
                    bPossible = FsRtlFastCheckLockForWrite(
                                    &Fcb->FileLockAnchor,
                                    FileOffset,
                                    &lLength,
                                    LockKey,
                                    FileObject,
                                    PsGetCurrentProcess());
                }
            }

#if EXT2_DEBUG
            DEBUG(DL_INF, ("Ext2FastIIOCheckPossible: %s %s %wZ\n",
                           Ext2GetCurrentProcessName(),
                           "FASTIO_CHECK_IF_POSSIBLE",
                           &Fcb->Mcb->FullName
                          ));

            DEBUG(DL_INF, (
                      "Ext2FastIIOCheckPossible: Offset: %I64xg Length: %xh Key: %u %s %s\n",
                      FileOffset->QuadPart,
                      Length,
                      LockKey,
                      (CheckForReadOperation ? "CheckForReadOperation:" :
                       "CheckForWriteOperation:"),
                      (bPossible ? "Succeeded" : "Failed")));
#endif

        } __except (EXCEPTION_EXECUTE_HANDLER) {
            bPossible = FastIoIsNotPossible;
        }

    } __finally {

        FsRtlExitFileSystem();
    }

    return bPossible;
}
Esempio n. 7
0
BOOLEAN
Ext2FastIoQueryNetworkOpenInfo (
    IN PFILE_OBJECT         FileObject,
    IN BOOLEAN              Wait,
    IN OUT PFILE_NETWORK_OPEN_INFORMATION PFNOI,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject
)
{
    BOOLEAN     bResult = FALSE;

    PEXT2_FCB   Fcb = NULL;

    BOOLEAN FcbResourceAcquired = FALSE;

    __try {

        FsRtlEnterFileSystem();

        if (IsExt2FsDevice(DeviceObject)) {
            IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Fcb = (PEXT2_FCB) FileObject->FsContext;
        if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
            DbgBreak();
            IoStatus->Status = STATUS_INVALID_PARAMETER;
            __leave;
        }

        ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
               (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

#if EXT2_DEBUG
        DEBUG(DL_INF, (
                  "%-31s %wZ\n",
                  "FASTIO_QUERY_NETWORK_OPEN_INFO",
                  &Fcb->Mcb->FullName
              ));
#endif

        if (FileObject->FsContext2) {
            __leave;
        }

        if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) {

            if (!ExAcquireResourceSharedLite(
                        &Fcb->MainResource,
                        Wait
                    )) {
                __leave;
            }

            FcbResourceAcquired = TRUE;
        }

        if (IsDirectory(Fcb)) {
            PFNOI->AllocationSize.QuadPart = 0;
            PFNOI->EndOfFile.QuadPart = 0;
        } else {
            PFNOI->AllocationSize = Fcb->Header.AllocationSize;
            PFNOI->EndOfFile      = Fcb->Header.FileSize;
        }

        PFNOI->FileAttributes = Fcb->Mcb->FileAttr;
        if (PFNOI->FileAttributes == 0) {
            PFNOI->FileAttributes = FILE_ATTRIBUTE_NORMAL;
        }

        if (IsRoot(Fcb)) {
            PFNOI->CreationTime =
                PFNOI->LastAccessTime =
                    PFNOI->LastWriteTime =
                        PFNOI->ChangeTime = Ext2NtTime(0);
        } else {
            PFNOI->CreationTime   = Fcb->Mcb->CreationTime;
            PFNOI->LastAccessTime = Fcb->Mcb->LastAccessTime;
            PFNOI->LastWriteTime  = Fcb->Mcb->LastWriteTime;
            PFNOI->ChangeTime     = Fcb->Mcb->ChangeTime;
        }

        bResult = TRUE;

        IoStatus->Status = STATUS_SUCCESS;
        IoStatus->Information = sizeof(FILE_NETWORK_OPEN_INFORMATION);

    } __finally {

        if (FcbResourceAcquired) {
            ExReleaseResourceLite(&Fcb->MainResource);
        }

        FsRtlExitFileSystem();
    }

    return bResult;
}
Esempio n. 8
0
VOID
SecondaryTryClose (
	IN PSECONDARY	Secondary
	)
{
	IRP_CONTEXT			irpContext;

	BOOLEAN				secondaryResourceAcquired = FALSE;
	BOOLEAN				acquiredVcb = FALSE;
	BOOLEAN				wait;


	DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles start\n") );

	try {

		RtlZeroMemory( &irpContext, sizeof(IRP_CONTEXT) );
		SetFlag( irpContext.Flags, IRP_CONTEXT_FLAG_WAIT );
		SetFlag( irpContext.NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );
		irpContext.Vcb = &Secondary->VolDo->Vcb;

		secondaryResourceAcquired = SecondaryAcquireResourceSharedLite( &irpContext, 
																		&Secondary->VolDo->Resource, 
																		FALSE );
		if (secondaryResourceAcquired == FALSE)
			leave;
		
		wait = BooleanFlagOn( irpContext.Flags, IRP_CONTEXT_FLAG_WAIT );

		acquiredVcb = FatAcquireExclusiveVcb( &irpContext, irpContext. Vcb );

		if (acquiredVcb == FALSE)
			leave;

		FsRtlEnterFileSystem();
		FatFspClose( &Secondary->VolDo->Vcb );
		FsRtlExitFileSystem();

		DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles FatFspClose, Secondary->VolDo->Vcb.SecondaryOpenCount = %d\n", 
							    Secondary->VolDo->Vcb.SecondaryOpenFileCount) );

		SetFlag( irpContext.NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_TRY_CLOSE_FILES );

		Secondary_TryCloseFilExts( Secondary );

	} finally {

		ClearFlag( irpContext.NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_TRY_CLOSE_FILES );

		if (acquiredVcb)
			FatReleaseVcb( &irpContext, irpContext.Vcb );
		
		DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles exit\n") );

		ExAcquireFastMutex( &Secondary->FastMutex );		
		Secondary->TryCloseActive = FALSE;
		ExReleaseFastMutex( &Secondary->FastMutex );

		if (secondaryResourceAcquired)
			SecondaryReleaseResourceLite( NULL, &Secondary->VolDo->Resource );

		Secondary_Dereference( Secondary );
	}

	return;
}
Esempio n. 9
0
static NTSTATUS
CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
                 PIRP Irp)
{
    PDEVICE_EXTENSION DeviceExt;
    PIO_STACK_LOCATION Stack;
    NTSTATUS Status;
    CDINFO CdInfo;
    PLIST_ENTRY Entry;
    PFCB Fcb;
    PVPB VpbToVerify;

    DPRINT1 ("CdfsVerifyVolume() called\n");

    DeviceExt = DeviceObject->DeviceExtension;

    Stack = IoGetCurrentIrpStackLocation (Irp);
    VpbToVerify = Stack->Parameters.VerifyVolume.Vpb;

    FsRtlEnterFileSystem();
    ExAcquireResourceExclusiveLite (&DeviceExt->VcbResource,
        TRUE);

    if (!(VpbToVerify->RealDevice->Flags & DO_VERIFY_VOLUME))
    {
        DPRINT1 ("Volume has been verified!\n");
        ExReleaseResourceLite (&DeviceExt->VcbResource);
        FsRtlExitFileSystem();
        return STATUS_SUCCESS;
    }

    DPRINT1("Device object %p  Device to verify %p\n", DeviceObject, VpbToVerify->RealDevice);

    Status = CdfsGetVolumeData(VpbToVerify->RealDevice,
        &CdInfo);
    if (NT_SUCCESS(Status) &&
        CdInfo.SerialNumber == VpbToVerify->SerialNumber &&
        CdInfo.VolumeLabelLength == VpbToVerify->VolumeLabelLength &&
        !wcsncmp(CdInfo.VolumeLabel, VpbToVerify->VolumeLabel, CdInfo.VolumeLabelLength))
    {
        DPRINT1 ("Same volume!\n");

        /* FIXME: Flush and purge metadata */

        Status = STATUS_SUCCESS;
    }
    else
    {
        DPRINT1 ("Different volume!\n");

        /* FIXME: force volume dismount */
        Entry = DeviceExt->FcbListHead.Flink;
        while (Entry != &DeviceExt->FcbListHead)
        {
            Fcb = (PFCB)CONTAINING_RECORD(Entry, FCB, FcbListEntry);
            DPRINT1("OpenFile %wZ  RefCount %ld\n", &Fcb->PathName, Fcb->RefCount);

            Entry = Entry->Flink;
        }

        Status = STATUS_WRONG_VOLUME;
    }

    VpbToVerify->RealDevice->Flags &= ~DO_VERIFY_VOLUME;

    ExReleaseResourceLite (&DeviceExt->VcbResource);
    FsRtlExitFileSystem();

    return Status;
}
Esempio n. 10
0
NTSTATUS
DokanDispatchClose(
	__in PDEVICE_OBJECT DeviceObject,
	__in PIRP Irp
	)

/*++

Routine Description:

	This device control dispatcher handles create & close IRPs.

Arguments:

	DeviceObject - Context for the activity.
	Irp 		 - The device control argument block.

Return Value:

	NTSTATUS

--*/
{
	PDokanVCB			vcb;
	PIO_STACK_LOCATION	irpSp;
	NTSTATUS			status = STATUS_INVALID_PARAMETER;
	PFILE_OBJECT		fileObject;
	PDokanCCB			ccb;
	PEVENT_CONTEXT		eventContext;
	ULONG				eventLength;
	PDokanFCB			fcb;

	PAGED_CODE();

	__try {

		FsRtlEnterFileSystem();

		DDbgPrint("==> DokanClose\n");
	
		irpSp = IoGetCurrentIrpStackLocation(Irp);
		fileObject = irpSp->FileObject;

		if (fileObject == NULL) {
			DDbgPrint("  fileObject is NULL\n");
			status = STATUS_SUCCESS;
			__leave;
		}

		DDbgPrint("  ProcessId %lu\n", IoGetRequestorProcessId(Irp));
		DokanPrintFileName(fileObject);

		vcb = DeviceObject->DeviceExtension;

		if (GetIdentifierType(vcb) != VCB ||
			!DokanCheckCCB(vcb->Dcb, fileObject->FsContext2)) {

			if (fileObject->FsContext2) {
				ccb = fileObject->FsContext2;
				ASSERT(ccb != NULL);

				fcb = ccb->Fcb;
				ASSERT(fcb != NULL);

				DDbgPrint("   Free CCB:%X\n", ccb);
				DokanFreeCCB(ccb);

				DokanFreeFCB(fcb);
			}

			status = STATUS_SUCCESS;
			__leave;
		}

		ccb = fileObject->FsContext2;
		ASSERT(ccb != NULL);

		fcb = ccb->Fcb;
		ASSERT(fcb != NULL);

		eventLength = sizeof(EVENT_CONTEXT) + fcb->FileName.Length;
		eventContext = AllocateEventContext(vcb->Dcb, Irp, eventLength, ccb);

		if (eventContext == NULL) {
			//status = STATUS_INSUFFICIENT_RESOURCES;
			DDbgPrint("   eventContext == NULL\n");
			DDbgPrint("   Free CCB:%X\n", ccb);
			DokanFreeCCB(ccb);
			DokanFreeFCB(fcb);
			status = STATUS_SUCCESS;
			__leave;
		}

		eventContext->Context = ccb->UserContext;
		DDbgPrint("   UserContext:%X\n", (ULONG)ccb->UserContext);

		// copy the file name to be closed
		eventContext->Close.FileNameLength = fcb->FileName.Length;
		RtlCopyMemory(eventContext->Close.FileName, fcb->FileName.Buffer, fcb->FileName.Length);

		DDbgPrint("   Free CCB:%X\n", ccb);
		DokanFreeCCB(ccb);

		DokanFreeFCB(fcb);

		// Close can not be pending status
		// don't register this IRP
		//status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext->SerialNumber, 0);

		// inform it to user-mode
		DokanEventNotification(&vcb->Dcb->NotifyEvent, eventContext);

		status = STATUS_SUCCESS;

	} __finally {

		if (status != STATUS_PENDING) {
			Irp->IoStatus.Status = status;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
		}

		DDbgPrint("<== DokanClose\n");

		FsRtlExitFileSystem();
	}

	return status;
}
Esempio n. 11
0
NTSTATUS NTAPI
VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
   NTSTATUS Status;
   PLIST_ENTRY ListEntry;
   PDEVICE_EXTENSION DeviceExt;
   ULONG eocMark;

   DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp);

   FsRtlEnterFileSystem();

   /* FIXME: block new mount requests */

   if (DeviceObject == VfatGlobalData->DeviceObject)
   {
      Irp->IoStatus.Status = STATUS_SUCCESS;
      ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
      ListEntry = VfatGlobalData->VolumeListHead.Flink;
      while (ListEntry != &VfatGlobalData->VolumeListHead)
      {
         DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry);
         ListEntry = ListEntry->Flink;

	 ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
         if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
         {
            /* set clean shutdown bit */
            Status = GetNextCluster(DeviceExt, 1, &eocMark);
            if (NT_SUCCESS(Status))
            {
               eocMark |= DeviceExt->CleanShutBitMask;
               if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark)))
                  DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
            }
         }
         Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
         if (NT_SUCCESS(Status))
         {
            Status = VfatDiskShutDown(DeviceExt);
            if (!NT_SUCCESS(Status))
	       DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
         }
         else
         {
	    DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
	 }
         ExReleaseResourceLite(&DeviceExt->DirResource);

         /* FIXME: Unmount the logical volume */

         if (!NT_SUCCESS(Status))
            Irp->IoStatus.Status = Status;
      }
      ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);

      /* FIXME: Free all global acquired resources */

      Status = Irp->IoStatus.Status;
   }
   else
   {
      Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
      Status = STATUS_INVALID_DEVICE_REQUEST;
   }

   Irp->IoStatus.Information = 0;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);

   FsRtlExitFileSystem();

   return(Status);
}
Esempio n. 12
0
BOOLEAN
FatFastUnlockAllByKey (
    IN PFILE_OBJECT FileObject,
    PVOID ProcessId,
    ULONG Key,
    OUT PIO_STATUS_BLOCK IoStatus,
    IN PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This is a call back routine for doing the fast unlock all by key call.

Arguments:

    FileObject - Supplies the file object used in this operation

    ProcessId - Supplies the process ID used in this operation

    Key - Supplies the key used in this operation

    Status - Receives the Status if this operation is successful

Return Value:

    BOOLEAN - TRUE if this operation completed and FALSE if caller
        needs to take the long route.

--*/

{
    BOOLEAN Results;
    PVCB Vcb;
    PFCB Fcb;
    PCCB Ccb;

    DebugTrace(+1, Dbg, "FatFastUnlockAllByKey\n", 0);

    IoStatus->Information = 0;

    //
    //  Decode the type of file object we're being asked to process and make sure
    //  it is only a user file open.
    //

    if (FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ) != UserFileOpen) {

        IoStatus->Status = STATUS_INVALID_PARAMETER;

        DebugTrace(-1, Dbg, "FatFastUnlockAll -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
        return TRUE;
    }

    //
    //  Acquire exclusive access to the Fcb this operation can always wait
    //

    FsRtlEnterFileSystem();

    (VOID) ExAcquireResourceShared( Fcb->Header.Resource, TRUE );

    try {

        //
        //  We check whether we can proceed based on the state of the file oplocks.
        //

        if (!FsRtlOplockIsFastIoPossible( &(Fcb)->Specific.Fcb.Oplock )) {

            try_return( Results = FALSE );
        }

        //
        //  Now call the FsRtl routine to do the actual processing of the
        //  Lock request.  The call will always succeed.
        //

        Results = TRUE;
        IoStatus->Status = FsRtlFastUnlockAllByKey( &Fcb->Specific.Fcb.FileLock,
                                                    FileObject,
                                                    ProcessId,
                                                    Key,
                                                    NULL );

        //
        //  Set the flag indicating if Fast I/O is possible
        //

        Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );

    try_exit:  NOTHING;
    } finally {

        DebugUnwind( FatFastUnlockAllByKey );

        //
        //  Release the Fcb, and return to our caller
        //

        ExReleaseResource( (Fcb)->Header.Resource );

        FsRtlExitFileSystem();

        DebugTrace(-1, Dbg, "FatFastUnlockAllByKey -> %08lx\n", Results);
    }

    return Results;
}
Esempio n. 13
0
BOOLEAN
FatFastLock (
    IN PFILE_OBJECT FileObject,
    IN PLARGE_INTEGER FileOffset,
    IN PLARGE_INTEGER Length,
    PEPROCESS ProcessId,
    ULONG Key,
    BOOLEAN FailImmediately,
    BOOLEAN ExclusiveLock,
    OUT PIO_STATUS_BLOCK IoStatus,
    IN PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This is a call back routine for doing the fast lock call.

Arguments:

    FileObject - Supplies the file object used in this operation

    FileOffset - Supplies the file offset used in this operation

    Length - Supplies the length used in this operation

    ProcessId - Supplies the process ID used in this operation

    Key - Supplies the key used in this operation

    FailImmediately - Indicates if the request should fail immediately
        if the lock cannot be granted.

    ExclusiveLock - Indicates if this is a request for an exclusive or
        shared lock

    IoStatus - Receives the Status if this operation is successful

Return Value:

    BOOLEAN - TRUE if this operation completed and FALSE if caller
        needs to take the long route.

--*/

{
    BOOLEAN Results;
    PVCB Vcb;
    PFCB Fcb;
    PCCB Ccb;

    DebugTrace(+1, Dbg, "FatFastLock\n", 0);

    //
    //  Decode the type of file object we're being asked to process and make
    //  sure it is only a user file open.
    //

    if (FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ) != UserFileOpen) {

        IoStatus->Status = STATUS_INVALID_PARAMETER;
        IoStatus->Information = 0;

        DebugTrace(-1, Dbg, "FatFastLock -> TRUE (STATUS_INVALID_PARAMETER)\n", 0);
        return TRUE;
    }

    //
    //  Acquire exclusive access to the Fcb this operation can always wait
    //

    FsRtlEnterFileSystem();

    // BUGBUG: kenr
    // (VOID) ExAcquireResourceShared( Fcb->Header.Resource, TRUE );

    try {

        //
        //  We check whether we can proceed
        //  based on the state of the file oplocks.
        //

        if (!FsRtlOplockIsFastIoPossible( &(Fcb)->Specific.Fcb.Oplock )) {

            try_return( Results = FALSE );
        }

        //
        //  Now call the FsRtl routine to do the actual processing of the
        //  Lock request
        //

        if (Results = FsRtlFastLock( &Fcb->Specific.Fcb.FileLock,
                                     FileObject,
                                     FileOffset,
                                     Length,
                                     ProcessId,
                                     Key,
                                     FailImmediately,
                                     ExclusiveLock,
                                     IoStatus,
                                     NULL,
                                     FALSE )) {

            //
            //  Set the flag indicating if Fast I/O is possible
            //

            Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
        }

    try_exit:  NOTHING;
    } finally {

        DebugUnwind( FatFastLock );

        //
        //  Release the Fcb, and return to our caller
        //

        // BUGBUG: kenr
        //    ExReleaseResource( (Fcb)->Header.Resource );

        FsRtlExitFileSystem();

        DebugTrace(-1, Dbg, "FatFastLock -> %08lx\n", Results);
    }

    return Results;
}
Esempio n. 14
0
NTSTATUS
FatFsdPnp (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the FSD part of PnP operations

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the
        file exists

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The FSD status for the IRP

--*/

{
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel;
    BOOLEAN Wait;

    DebugTrace(+1, Dbg, "FatFsdPnp\n", 0);

    FsRtlEnterFileSystem();

    TopLevel = FatIsIrpTopLevel( Irp );

    try {

        //
        //  We expect there to never be a fileobject, in which case we will always
        //  wait.  Since at the moment we don't have any concept of pending Pnp
        //  operations, this is a bit nitpicky.
        //
        
        if (IoGetCurrentIrpStackLocation( Irp )->FileObject == NULL) {

            Wait = TRUE;

        } else {

            Wait = CanFsdWait( Irp );
        }

        IrpContext = FatCreateIrpContext( Irp, Wait );

        Status = FatCommonPnp( IrpContext, Irp );

    } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

        //
        //  We had some trouble trying to perform the requested
        //  operation, so we'll abort the I/O request with
        //  the error status that we get back from the
        //  execption code
        //

        Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
    }

    if (TopLevel) { IoSetTopLevelIrp( NULL ); }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

    DebugTrace(-1, Dbg, "FatFsdPnp -> %08lx\n", Status);

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    return Status;
}
Esempio n. 15
0
BOOLEAN
Ext2FastIoQueryStandardInfo (
    IN PFILE_OBJECT                 FileObject,
    IN BOOLEAN                      Wait,
    OUT PFILE_STANDARD_INFORMATION  Buffer,
    OUT PIO_STATUS_BLOCK            IoStatus,
    IN PDEVICE_OBJECT               DeviceObject
)
{

    BOOLEAN     Status = FALSE;
    PEXT2_VCB   Vcb;
    PEXT2_FCB   Fcb;
    BOOLEAN     FcbMainResourceAcquired = FALSE;

    __try {

        FsRtlEnterFileSystem();

        __try {

            if (IsExt2FsDevice(DeviceObject)) {
                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                __leave;
            }

            Fcb = (PEXT2_FCB) FileObject->FsContext;
            if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB)  {
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                __leave;
            }

            ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
                   (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

#if EXT2_DEBUG
            DEBUG(DL_INF, (
                      "Ext2FastIoQueryStandardInfo: %s %s %wZ\n",
                      Ext2GetCurrentProcessName(),
                      "FASTIO_QUERY_STANDARD_INFO",
                      &Fcb->Mcb->FullName ));
#endif
            Vcb = Fcb->Vcb;

            if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) {
                if (!ExAcquireResourceSharedLite(
                            &Fcb->MainResource,
                            Wait        )) {
                    __leave;
                }
                FcbMainResourceAcquired = TRUE;
            }

            RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION));

            /*
            typedef struct _FILE_STANDARD_INFORMATION {
            LARGE_INTEGER   AllocationSize;
            LARGE_INTEGER   EndOfFile;
            ULONG           NumberOfLinks;
            BOOLEAN         DeletePending;
            BOOLEAN         Directory;
            } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
            */

            Buffer->NumberOfLinks = Fcb->Inode->i_nlink;
            Buffer->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);

            if (IsDirectory(Fcb)) {
                Buffer->Directory = IsDirectory(Fcb);
                Buffer->AllocationSize.QuadPart = 0;
                Buffer->EndOfFile.QuadPart = 0;
            } else {
                Buffer->Directory = FALSE;
                Buffer->AllocationSize = Fcb->Header.AllocationSize;
                Buffer->EndOfFile = Fcb->Header.FileSize;
            }

            IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
            IoStatus->Status = STATUS_SUCCESS;
#if EXT2_DEBUG
            DEBUG(DL_INF, ( "Ext2FastIoQueryStandInfo: AllocatieonSize = %I64xh FileSize = %I64xh\n",
                            Buffer->AllocationSize.QuadPart, Buffer->EndOfFile.QuadPart));
#endif
            Status =  TRUE;

        } __except (EXCEPTION_EXECUTE_HANDLER) {
            IoStatus->Status = GetExceptionCode();
        }

    } __finally {

        if (FcbMainResourceAcquired) {
            ExReleaseResourceLite(&Fcb->MainResource);
        }

        FsRtlExitFileSystem();
    }

#if EXT2_DEBUG
    if (Status == FALSE) {
        DEBUG(DL_INF, (
                  "Ext2FastIoQueryStandardInfo: %s %s Status: FALSE ***\n",
                  Ext2GetCurrentProcessName(),
                  "FASTIO_QUERY_STANDARD_INFO"            ));
    } else if (IoStatus->Status != STATUS_SUCCESS) {
        DEBUG(DL_INF, (
                  "Ext2FastIoQueryStandardInfo: %s %s Status: %#x ***\n",
                  Ext2GetCurrentProcessName(),
                  "FASTIO_QUERY_STANDARD_INFO",
                  IoStatus->Status            ));
    }
#endif

    return Status;
}
Esempio n. 16
0
VOID
FatFspDispatch (
    _In_ PVOID Context
    )

/*++

Routine Description:

    This is the main FSP thread routine that is executed to receive
    and dispatch IRP requests.  Each FSP thread begins its execution here.
    There is one thread created at system initialization time and subsequent
    threads created as needed.

Arguments:


    Context - Supplies the thread id.

Return Value:

    None - This routine never exits

--*/

{
    NTSTATUS Status = STATUS_SUCCESS;


    PIRP Irp;
    PIRP_CONTEXT IrpContext;
    PIO_STACK_LOCATION IrpSp;
    BOOLEAN VcbDeleted;
    BOOLEAN  ExceptionCompletedIrp = FALSE;

    PVOLUME_DEVICE_OBJECT VolDo;

    UCHAR MajorFunction = 0;

    PAGED_CODE();

    IrpContext = (PIRP_CONTEXT)Context;

    Irp = IrpContext->OriginatingIrp;

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  Now because we are the Fsp we will force the IrpContext to
    //  indicate true on Wait.
    //

    SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT | IRP_CONTEXT_FLAG_IN_FSP);

    //
    //  If this request has an associated volume device object, remember it.
    //

    if ( IrpSp->FileObject != NULL ) {

        VolDo = CONTAINING_RECORD( IrpSp->DeviceObject,
                                   VOLUME_DEVICE_OBJECT,
                                   DeviceObject );
    } else {

        VolDo = NULL;
    }

    //
    //  Now case on the function code.  For each major function code,
    //  either call the appropriate FSP routine or case on the minor
    //  function and then call the FSP routine.  The FSP routine that
    //  we call is responsible for completing the IRP, and not us.
    //  That way the routine can complete the IRP and then continue
    //  post processing as required.  For example, a read can be
    //  satisfied right away and then read can be done.
    //
    //  We'll do all of the work within an exception handler that
    //  will be invoked if ever some underlying operation gets into
    //  trouble (e.g., if FatReadSectorsSync has trouble).
    //

    while ( TRUE ) {

        ExceptionCompletedIrp = FALSE;
                
        DebugTrace(0, Dbg, "FatFspDispatch: Irp = %p\n", Irp);

        //
        //  If this Irp was top level, note it in our thread local storage.
        //

        FsRtlEnterFileSystem();

        if ( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) ) {

            IoSetTopLevelIrp( (PIRP)FSRTL_FSP_TOP_LEVEL_IRP );

        } else {

            IoSetTopLevelIrp( Irp );
        }

        MajorFunction = IrpContext->MajorFunction;

        try {

            switch ( MajorFunction ) {

                //
                //  For Create Operation,
                //

                case IRP_MJ_CREATE:

                    Status = FatCommonCreate( IrpContext, Irp );
                    break;

                //
                //  For close operations.  We do a little kludge here in case
                //  this close causes a volume to go away.  It will NULL the
                //  VolDo local variable so that we will not try to look at
                //  the overflow queue.
                //

                case IRP_MJ_CLOSE:

                {
                    PVCB Vcb;
                    PFCB Fcb;
                    PCCB Ccb;
                    TYPE_OF_OPEN TypeOfOpen;

                    //
                    //  Extract and decode the file object
                    //

                    TypeOfOpen = FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Fcb, &Ccb );

                    //
                    //  Do the close.  We have a slightly different format
                    //  for this call because of the async closes.
                    //

                    Status = FatCommonClose( Vcb,
                                             Fcb,
                                             Ccb,
                                             TypeOfOpen,
                                             TRUE,
                                             TRUE,
                                             &VcbDeleted );

                    //
                    //  If the VCB was deleted, do not try to access it later.
                    //

                    if (VcbDeleted) {

                        VolDo = NULL;
                    }

                    NT_ASSERT(Status == STATUS_SUCCESS);

                    FatCompleteRequest( IrpContext, Irp, Status );

                    break;
                }

                //
                //  For read operations
                //

                case IRP_MJ_READ:

                    (VOID) FatCommonRead( IrpContext, Irp );
                    break;

                //
                //  For write operations,
                //

                case IRP_MJ_WRITE:

                    (VOID) FatCommonWrite( IrpContext, Irp );
                    break;

                //
                //  For Query Information operations,
                //

                case IRP_MJ_QUERY_INFORMATION:

                    (VOID) FatCommonQueryInformation( IrpContext, Irp );
                    break;

                //
                //  For Set Information operations,
                //

                case IRP_MJ_SET_INFORMATION:

                    (VOID) FatCommonSetInformation( IrpContext, Irp );
                    break;

                //
                //  For Query EA operations,
                //

                case IRP_MJ_QUERY_EA:

                    (VOID) FatCommonQueryEa( IrpContext, Irp );
                    break;

                //
                //  For Set EA operations,
                //

                case IRP_MJ_SET_EA:

                    (VOID) FatCommonSetEa( IrpContext, Irp );
                    break;

                //
                //  For Flush buffers operations,
                //

                case IRP_MJ_FLUSH_BUFFERS:

                    (VOID) FatCommonFlushBuffers( IrpContext, Irp );
                    break;

                //
                //  For Query Volume Information operations,
                //

                case IRP_MJ_QUERY_VOLUME_INFORMATION:

                    (VOID) FatCommonQueryVolumeInfo( IrpContext, Irp );
                    break;

                //
                //  For Set Volume Information operations,
                //

                case IRP_MJ_SET_VOLUME_INFORMATION:

                    (VOID) FatCommonSetVolumeInfo( IrpContext, Irp );
                    break;

                //
                //  For File Cleanup operations,
                //

                case IRP_MJ_CLEANUP:

                    (VOID) FatCommonCleanup( IrpContext, Irp );
                    break;

                //
                //  For Directory Control operations,
                //

                case IRP_MJ_DIRECTORY_CONTROL:

                    (VOID) FatCommonDirectoryControl( IrpContext, Irp );
                    break;

                //
                //  For File System Control operations,
                //

                case IRP_MJ_FILE_SYSTEM_CONTROL:

                    (VOID) FatCommonFileSystemControl( IrpContext, Irp );
                    break;

                //
                //  For Lock Control operations,
                //

                case IRP_MJ_LOCK_CONTROL:

                    (VOID) FatCommonLockControl( IrpContext, Irp );
                    break;

                //
                //  For Device Control operations,
                //

                case IRP_MJ_DEVICE_CONTROL:

                    (VOID) FatCommonDeviceControl( IrpContext, Irp );
                    break;

                //
                //  For the Shutdown operation,
                //

                case IRP_MJ_SHUTDOWN:

                    (VOID) FatCommonShutdown( IrpContext, Irp );
                    break;

                //
                //  For plug and play operations.
                //

                case IRP_MJ_PNP:

                    //
                    //  I don't believe this should ever occur, but allow for the unexpected.
                    //

                    (VOID) FatCommonPnp( IrpContext, Irp );
                    break;

                //
                //  For any other major operations, return an invalid
                //  request.
                //

                default:

                    FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
                    break;

            }

        } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

            //
            //  We had some trouble trying to perform the requested
            //  operation, so we'll abort the I/O request with
            //  the error status that we get back from the
            //  execption code.
            //

            (VOID) FatProcessException( IrpContext, Irp, GetExceptionCode() );
            ExceptionCompletedIrp = TRUE;
        }

        IoSetTopLevelIrp( NULL );

        FsRtlExitFileSystem();


        if (MajorFunction == IRP_MJ_CREATE && !ExceptionCompletedIrp && Status != STATUS_PENDING) {
            
            //
            // Creates are completed here. IrpContext is also freed here.
            //

            FatCompleteRequest( IrpContext, Irp, Status );            
        }

        //
        //  If there are any entries on this volume's overflow queue, service
        //  them.
        //

        if ( VolDo != NULL ) {

            PVOID Entry;

            //
            //  We have a volume device object so see if there is any work
            //  left to do in its overflow queue.
            //

            Entry = FatRemoveOverflowEntry( VolDo );

            //
            //  There wasn't an entry, break out of the loop and return to
            //  the Ex Worker thread.
            //

            if ( Entry == NULL ) {

                break;
            }

            //
            //  Extract the IrpContext, Irp, and IrpSp, and loop.
            //

            IrpContext = CONTAINING_RECORD( Entry,
                                            IRP_CONTEXT,
                                            WorkQueueItem.List );

            SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT | IRP_CONTEXT_FLAG_IN_FSP);

            Irp = IrpContext->OriginatingIrp;

            IrpSp = IoGetCurrentIrpStackLocation( Irp );

            continue;

        } else {

            break;
        }
    }

    return;
}
Esempio n. 17
0
BOOLEAN
Ext2FastIoLock (
    IN PFILE_OBJECT         FileObject,
    IN PLARGE_INTEGER       FileOffset,
    IN PLARGE_INTEGER       Length,
    IN PEPROCESS            Process,
    IN ULONG                Key,
    IN BOOLEAN              FailImmediately,
    IN BOOLEAN              ExclusiveLock,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject
)
{
    BOOLEAN     Status = FALSE;
    PEXT2_FCB   Fcb;

    __try {

        FsRtlEnterFileSystem();

        __try {

            if (IsExt2FsDevice(DeviceObject)) {
                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                __leave;
            }

            Fcb = (PEXT2_FCB) FileObject->FsContext;
            if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                __leave;
            }

            ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
                   (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

            if (IsDirectory(Fcb)) {
                DbgBreak();
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                __leave;
            }
#if EXT2_DEBUG
            DEBUG(DL_INF, (
                      "Ext2FastIoLock: %s %s %wZ\n",
                      Ext2GetCurrentProcessName(),
                      "FASTIO_LOCK",
                      &Fcb->Mcb->FullName        ));

            DEBUG(DL_INF, (
                      "Ext2FastIoLock: Offset: %I64xh Length: %I64xh Key: %u %s%s\n",
                      FileOffset->QuadPart,
                      Length->QuadPart,
                      Key,
                      (FailImmediately ? "FailImmediately " : ""),
                      (ExclusiveLock ? "ExclusiveLock " : "") ));
#endif

            if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) {
                __leave;
            }

            Status = FsRtlFastLock(
                         &Fcb->FileLockAnchor,
                         FileObject,
                         FileOffset,
                         Length,
                         Process,
                         Key,
                         FailImmediately,
                         ExclusiveLock,
                         IoStatus,
                         NULL,
                         FALSE);

            if (Status) {
                Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
            }

        } __except (EXCEPTION_EXECUTE_HANDLER) {
            IoStatus->Status = GetExceptionCode();
        }

    } __finally {

        FsRtlExitFileSystem();
    }

#if EXT2_DEBUG
    if (Status == FALSE) {
        DEBUG(DL_ERR, (
                  "Ext2FastIoLock: %s %s *** Status: FALSE ***\n",
                  (PUCHAR) Process + ProcessNameOffset,
                  "FASTIO_LOCK"
              ));
    } else if (IoStatus->Status != STATUS_SUCCESS) {
        DEBUG(DL_ERR, (
                  "Ext2FastIoLock: %s %s *** Status: %s (%#x) ***\n",
                  (PUCHAR) Process + ProcessNameOffset,
                  "FASTIO_LOCK",
                  Ext2NtStatusToString(IoStatus->Status),
                  IoStatus->Status
              ));
    }
#endif

    return Status;
}
Esempio n. 18
0
NTSTATUS
FatFsdRead (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
)

/*++

Routine Description:

    This is the driver entry to the common read routine for NtReadFile calls.
    For synchronous requests, the CommonRead is called with Wait == TRUE,
    which means the request will always be completed in the current thread,
    and never passed to the Fsp.  If it is not a synchronous request,
    CommonRead is called with Wait == FALSE, which means the request
    will be passed to the Fsp only if there is a need to block.

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the
        file being Read exists

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The FSD status for the IRP

--*/

{
    PFCB Fcb;
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel;

    DebugTrace(+1, Dbg, "FatFsdRead\n", 0);

    //
    //  Call the common Read routine, with blocking allowed if synchronous
    //

    FsRtlEnterFileSystem();

    //
    //  We are first going to do a quick check for paging file IO.
    //

    Fcb = (PFCB)(IoGetCurrentIrpStackLocation(Irp)->FileObject->FsContext);

    if ((NodeType(Fcb) == FAT_NTC_FCB) &&
            FlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE)) {

        //
        //  Do the usual STATUS_PENDING things.
        //

        IoMarkIrpPending( Irp );

        //
        //  If there is not enough stack to do this read, then post this
        //  read to the overflow queue.
        //

        if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) {

            KEVENT Event;
            PAGING_FILE_OVERFLOW_PACKET Packet;

            Packet.Irp = Irp;
            Packet.Fcb = Fcb;

            KeInitializeEvent( &Event, NotificationEvent, FALSE );

            FsRtlPostPagingFileStackOverflow( &Packet, &Event, FatOverflowPagingFileRead );

            //
            //  And wait for the worker thread to complete the item
            //

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

        } else {

            //
            //  Perform the actual IO, it will be completed when the io finishes.
            //

            FatPagingFileIo( Irp, Fcb );
        }

        FsRtlExitFileSystem();

        return STATUS_PENDING;
    }

    try {

        TopLevel = FatIsIrpTopLevel( Irp );

        IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );

        //
        //  If this is an Mdl complete request, don't go through
        //  common read.
        //

        if ( FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE) ) {

            DebugTrace(0, Dbg, "Calling FatCompleteMdl\n", 0 );
            try_return( Status = FatCompleteMdl( IrpContext, Irp ));
        }

        //
        //  We can't handle DPC calls yet, post it.
        //

        if ( FlagOn(IrpContext->MinorFunction, IRP_MN_DPC) ) {

            DebugTrace(0, Dbg, "Passing DPC call to Fsp\n", 0 );
            try_return( Status = FatFsdPostRequest( IrpContext, Irp ));
        }

        //
        //  Check if we have enough stack space to process this request.  If there
        //  isn't enough then we will pass the request off to the stack overflow thread.
        //

        if ((IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) &&
                ((NodeType(Fcb) == FAT_NTC_FCB) ||
                 (NodeType(Fcb) == FAT_NTC_DCB) ||
                 (NodeType(Fcb) == FAT_NTC_ROOT_DCB))) {

            DebugTrace(0, Dbg, "Passing StackOverflowRead off\n", 0 );
            try_return( Status = FatPostStackOverflowRead( IrpContext, Irp, Fcb ) );
        }

        Status = FatCommonRead( IrpContext, Irp );

try_exit:
        NOTHING;
    }
    except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

        //
        //  We had some trouble trying to perform the requested
        //  operation, so we'll abort the I/O request with
        //  the error status that we get back from the
        //  execption code
        //

        Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
    }

    if (TopLevel) {
        IoSetTopLevelIrp( NULL );
    }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

    DebugTrace(-1, Dbg, "FatFsdRead -> %08lx\n", Status);

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    return Status;
}
Esempio n. 19
0
BOOLEAN
Ext2FastIoUnlockAllByKey (
    IN PFILE_OBJECT         FileObject,
    IN PEPROCESS            Process,
    IN ULONG                Key,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject
)
{
    BOOLEAN     Status = FALSE;
    PEXT2_FCB   Fcb;

    __try {

        FsRtlEnterFileSystem();

        __try {

            if (IsExt2FsDevice(DeviceObject)) {
                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                __leave;
            }

            Fcb = (PEXT2_FCB) FileObject->FsContext;
            if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
                DbgBreak();
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                __leave;
            }

            ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
                   (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

            if (IsDirectory(Fcb)) {
                DbgBreak();
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                __leave;
            }

#if EXT2_DEBUG
            DEBUG(DL_INF, (
                      "Ext2FastIoUnlockAllByKey: %s %s %wZ\n",
                      (PUCHAR) Process + ProcessNameOffset,
                      "FASTIO_UNLOCK_ALL_BY_KEY",
                      &Fcb->Mcb->FullName
                  ));

            DEBUG(DL_INF, (
                      "Ext2FastIoUnlockAllByKey: Key: %u\n",
                      Key
                  ));
#endif

            if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) {
                __leave;
            }

            IoStatus->Status = FsRtlFastUnlockAllByKey(
                                   &Fcb->FileLockAnchor,
                                   FileObject,
                                   Process,
                                   Key,
                                   NULL
                               );

            IoStatus->Information = 0;
            Status =  TRUE;

            Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);

        } __except (EXCEPTION_EXECUTE_HANDLER) {
            IoStatus->Status = GetExceptionCode();
        }

    } __finally {

        FsRtlExitFileSystem();
    }

#if EXT2_DEBUG
    if (Status == FALSE) {

        DEBUG(DL_ERR, (
                  "Ext2FastIoUnlockAllByKey: %s %s *** Status: FALSE ***\n",
                  (PUCHAR) Process + ProcessNameOffset,
                  "FASTIO_UNLOCK_ALL_BY_KEY"
              ));
    } else if (IoStatus->Status != STATUS_SUCCESS) {

        DEBUG(DL_ERR, (
                  "Ext2FastIoUnlockAllByKey: %s %s *** Status: %s (%#x) ***\n",
                  (PUCHAR) Process + ProcessNameOffset,
                  "FASTIO_UNLOCK_ALL_BY_KEY",
                  Ext2NtStatusToString(IoStatus->Status),
                  IoStatus->Status
              ));
    }
#endif

    return Status;
}
Esempio n. 20
0
NTSTATUS
DokanDispatchFileSystemControl(
	__in PDEVICE_OBJECT DeviceObject,
	__in PIRP Irp
	)
{
	NTSTATUS			status = STATUS_INVALID_PARAMETER;
	PIO_STACK_LOCATION	irpSp;
	PDokanVCB			vcb;

	PAGED_CODE();

	__try {
		FsRtlEnterFileSystem();

		DDbgPrint("==> DokanFileSystemControl\n");
		DDbgPrint("  ProcessId %lu\n", IoGetRequestorProcessId(Irp));

		vcb = DeviceObject->DeviceExtension;
		if (GetIdentifierType(vcb) != VCB) {
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		irpSp = IoGetCurrentIrpStackLocation(Irp);

		switch(irpSp->MinorFunction) {
		case IRP_MN_KERNEL_CALL:
			DDbgPrint("	 IRP_MN_KERNEL_CALL\n");
			break;

		case IRP_MN_LOAD_FILE_SYSTEM:
			DDbgPrint("	 IRP_MN_LOAD_FILE_SYSTEM\n");
			break;

		case IRP_MN_MOUNT_VOLUME:
			{
				PVPB vpb;
				DDbgPrint("	 IRP_MN_MOUNT_VOLUME\n");
				if (irpSp->Parameters.MountVolume.DeviceObject != vcb->Dcb->DeviceObject) {
					DDbgPrint("   Not DokanDiskDevice\n");
					status = STATUS_INVALID_PARAMETER;
				}
				vpb = irpSp->Parameters.MountVolume.Vpb;
				vpb->DeviceObject = vcb->DeviceObject;
				vpb->RealDevice = vcb->DeviceObject;
				vpb->Flags |= VPB_MOUNTED;
				vpb->VolumeLabelLength = wcslen(VOLUME_LABEL) * sizeof(WCHAR);
				RtlStringCchCopyW(vpb->VolumeLabel, sizeof(vpb->VolumeLabel) / sizeof(WCHAR), VOLUME_LABEL);
				vpb->SerialNumber = 0x19831116;
				status = STATUS_SUCCESS;
			}
			break;

		case IRP_MN_USER_FS_REQUEST:
			DDbgPrint("	 IRP_MN_USER_FS_REQUEST\n");
			status = DokanUserFsRequest(DeviceObject, Irp);
			break;

		case IRP_MN_VERIFY_VOLUME:
			DDbgPrint("	 IRP_MN_VERIFY_VOLUME\n");
			break;

		default:
			DDbgPrint("  unknown %d\n", irpSp->MinorFunction);
			status = STATUS_INVALID_PARAMETER;
			break;

		}

	} __finally {
		
		Irp->IoStatus.Status = status;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);

		DokanPrintNTStatus(status);
		DDbgPrint("<== DokanFileSystemControl\n");

		FsRtlExitFileSystem();
	}

	return status;
}
Esempio n. 21
0
NTSTATUS
DokanDispatchFlush(
	__in PDEVICE_OBJECT DeviceObject,
	__in PIRP Irp
	)
{
	PIO_STACK_LOCATION	irpSp;
	PFILE_OBJECT		fileObject;
	PVOID				buffer;
	NTSTATUS			status = STATUS_INVALID_PARAMETER;
	PDokanFCB			fcb;
	PDokanCCB			ccb;
	PDokanVCB			vcb;
	PEVENT_CONTEXT		eventContext;
	ULONG				eventLength;

	PAGED_CODE();
	
	__try {
		FsRtlEnterFileSystem();

		DDbgPrint("==> DokanFlush\n");

		irpSp		= IoGetCurrentIrpStackLocation(Irp);
		fileObject	= irpSp->FileObject;

		if (fileObject == NULL) {
			DDbgPrint("  fileObject == NULL\n");
			status = STATUS_SUCCESS;
			__leave;
		}

		vcb = DeviceObject->DeviceExtension;
		if (GetIdentifierType(vcb) != VCB ||
			!DokanCheckCCB(vcb->Dcb, fileObject->FsContext2)) {
			status = STATUS_SUCCESS;
			__leave;
		}


		DDbgPrint("  FileName:%wZ\n", &fileObject->FileName);

		ccb = fileObject->FsContext2;
		ASSERT(ccb != NULL);

		fcb = ccb->Fcb;
		ASSERT(fcb != NULL);

		eventLength = sizeof(EVENT_CONTEXT) + fcb->FileName.Length;
		eventContext = AllocateEventContext(vcb->Dcb, Irp, eventLength, ccb);

		if (eventContext == NULL) {
			status = STATUS_INSUFFICIENT_RESOURCES;
			__leave;
		}

		eventContext->Context = ccb->UserContext;
		DDbgPrint("   get Context %X\n", (ULONG)ccb->UserContext);

		// copy file name to be flushed
		eventContext->Flush.FileNameLength = fcb->FileName.Length;
		RtlCopyMemory(eventContext->Flush.FileName, fcb->FileName.Buffer, fcb->FileName.Length);

		CcUninitializeCacheMap(fileObject, NULL, NULL);
		//fileObject->Flags &= FO_CLEANUP_COMPLETE;

		// register this IRP to waiting IRP list and make it pending status
		status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext);

	} __finally {

		// if status is not pending, must complete current IRPs
		if (status != STATUS_PENDING) {
			Irp->IoStatus.Status = status;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			DokanPrintNTStatus(status);
		} else {
			DDbgPrint("  STATUS_PENDING\n");
		}

		DDbgPrint("<== DokanFlush\n");

		FsRtlExitFileSystem();
	}

	return status;
}
Esempio n. 22
0
BOOLEAN
Ext2FastIoWrite (
    IN PFILE_OBJECT         FileObject,
    IN PLARGE_INTEGER       FileOffset,
    IN ULONG                Length,
    IN BOOLEAN              Wait,
    IN ULONG                LockKey,
    OUT PVOID               Buffer,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject)
{
    PEXT2_FCB   Fcb = NULL;
    BOOLEAN     Status = FALSE;
    BOOLEAN     Locked = FALSE;

    Fcb = (PEXT2_FCB) FileObject->FsContext;
    if (Fcb == NULL)
        return FALSE;

    __try {

        FsRtlEnterFileSystem();

        ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
               (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

        if (IsVcbReadOnly(Fcb->Vcb)) {
            __leave;
        }

        if (!ExAcquireResourceSharedLite(Fcb->Header.Resource, Wait)) {
            __leave;
        }
        Locked = TRUE;

        if (IsWritingToEof(*FileOffset) ||
            Fcb->Header.ValidDataLength.QuadPart < FileOffset->QuadPart + Length ||
            Fcb->Header.FileSize.QuadPart < FileOffset->QuadPart + Length ) {
            Status = FALSE;
            __leave;
        }

        if (Locked) {
            ExReleaseResourceLite(Fcb->Header.Resource);
            Locked = FALSE;
        }

        Status = FsRtlCopyWrite(FileObject, FileOffset, Length, Wait,
                                LockKey, Buffer, IoStatus, DeviceObject);
        if (Status) {
            if (IoStatus)
                Length = (ULONG)IoStatus->Information;
        }

    } __finally {

        if (Locked) {
            ExReleaseResourceLite(Fcb->Header.Resource);
        }

        FsRtlExitFileSystem();
    }

    DEBUG(DL_IO, ("Ext2FastIoWrite: %wZ Offset: %I64xh Length: %xh Key: %xh Status=%d\n",
                  &Fcb->Mcb->ShortName,  FileOffset->QuadPart, Length, LockKey, Status));

    return Status;
}
Esempio n. 23
0
VOID
NTAPI
NpCancelDataQueueIrp(IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
{
    PNP_DATA_QUEUE DataQueue;
    PNP_DATA_QUEUE_ENTRY DataEntry;
    LIST_ENTRY DeferredList;
    PSECURITY_CLIENT_CONTEXT ClientSecurityContext;
    BOOLEAN CompleteWrites, FirstEntry;

    if (DeviceObject) IoReleaseCancelSpinLock(Irp->CancelIrql);

    InitializeListHead(&DeferredList);

    DataQueue = Irp->Tail.Overlay.DriverContext[2];
    ClientSecurityContext = NULL;

    if (DeviceObject)
    {
        FsRtlEnterFileSystem();
        NpAcquireExclusiveVcb();
    }

    DataEntry = Irp->Tail.Overlay.DriverContext[3];
    if (DataEntry)
    {
        if (DataEntry->QueueEntry.Blink == &DataQueue->Queue)
        {
            DataQueue->ByteOffset = 0;
            FirstEntry = TRUE;
        }
        else
        {
            FirstEntry = FALSE;
        }

        RemoveEntryList(&DataEntry->QueueEntry);

        ClientSecurityContext = DataEntry->ClientSecurityContext;

        CompleteWrites = TRUE;
        if (DataQueue->QueueState != WriteEntries ||
            DataQueue->QuotaUsed < DataQueue->Quota ||
            !DataEntry->QuotaInEntry)
        {
            CompleteWrites = FALSE;
        }

        DataQueue->BytesInQueue -= DataEntry->DataSize;
        DataQueue->QuotaUsed -= DataEntry->QuotaInEntry;
        --DataQueue->EntriesInQueue;

        if (IsListEmpty(&DataQueue->Queue))
        {
            DataQueue->QueueState = Empty;
            ASSERT(DataQueue->BytesInQueue == 0);
            ASSERT(DataQueue->EntriesInQueue == 0);
            ASSERT(DataQueue->QuotaUsed == 0);
        }
        else
        {
            if (FirstEntry)
            {
                NpGetNextRealDataQueueEntry(DataQueue, &DeferredList);
            }
            if (CompleteWrites)
            {
                NpCompleteStalledWrites(DataQueue, &DeferredList);
            }
        }
    }

    if (DeviceObject)
    {
        NpReleaseVcb();
        FsRtlExitFileSystem();
    }

    if (DataEntry) ExFreePool(DataEntry);

    NpFreeClientSecurityContext(ClientSecurityContext);
    Irp->IoStatus.Status = STATUS_CANCELLED;
    IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);

    NpCompleteDeferredIrps(&DeferredList);
}
Esempio n. 24
0
NTSTATUS
DokanDispatchQueryInformation(
	__in PDEVICE_OBJECT DeviceObject,
	__in PIRP Irp
   )
{
	NTSTATUS				status = STATUS_NOT_IMPLEMENTED;
	PIO_STACK_LOCATION		irpSp;
	PFILE_OBJECT			fileObject;
	PDokanCCB				ccb;
	PDokanFCB				fcb;
	PDokanVCB				vcb;
	ULONG					info = 0;
	ULONG					eventLength;
	PEVENT_CONTEXT			eventContext;


	//PAGED_CODE();
	
	__try {
		FsRtlEnterFileSystem();

		DDbgPrint("==> DokanQueryInformation\n");

		irpSp			= IoGetCurrentIrpStackLocation(Irp);
		fileObject		= irpSp->FileObject;

		DDbgPrint("  FileInfoClass %d\n", irpSp->Parameters.QueryFile.FileInformationClass);
		DDbgPrint("  ProcessId %lu\n", IoGetRequestorProcessId(Irp));

		if (fileObject == NULL) {
			DDbgPrint("  fileObject == NULL\n");
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		DokanPrintFileName(fileObject);

		/*
		if (fileObject->FsContext2 == NULL &&
			fileObject->FileName.Length == 0) {
			// volume open?
			status = STATUS_SUCCESS;
			__leave;
		}*/
		vcb = DeviceObject->DeviceExtension;
		if (GetIdentifierType(vcb) != VCB ||
			!DokanCheckCCB(vcb->Dcb, fileObject->FsContext2)) {
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		ccb	= (PDokanCCB)fileObject->FsContext2;
		ASSERT(ccb != NULL);

		fcb = ccb->Fcb;
		ASSERT(fcb != NULL);

		switch (irpSp->Parameters.QueryFile.FileInformationClass) {
		case FileBasicInformation:
			DDbgPrint("  FileBasicInformation\n");
			break;  
		case FileInternalInformation:
			DDbgPrint("  FileInternalInformation\n");
			break;
		case FileEaInformation:
			DDbgPrint("  FileEaInformation\n");
			break;          
		case FileStandardInformation:
			DDbgPrint("  FileStandardInformation\n");
			break;
		case FileAllInformation:
			DDbgPrint("  FileAllInformation\n");
			break;
		case FileAlternateNameInformation:
			DDbgPrint("  FileAlternateNameInformation\n");
			break;
		case FileAttributeTagInformation:
			DDbgPrint("  FileAttributeTagInformation\n");
			break;
		case FileCompressionInformation:
			DDbgPrint("  FileCompressionInformation\n");
			break;
		case FileNameInformation:
			{
				PFILE_NAME_INFORMATION nameInfo;

				DDbgPrint("  FileNameInformation\n");
	
				if (irpSp->Parameters.QueryFile.Length < sizeof(FILE_NAME_INFORMATION)
					+ fcb->FileName.Length) {

					status = STATUS_INSUFFICIENT_RESOURCES;
				
				} else {
					
					nameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
					ASSERT(nameInfo != NULL);

					nameInfo->FileNameLength = fcb->FileName.Length;
					RtlCopyMemory(nameInfo->FileName, fcb->FileName.Buffer, fcb->FileName.Length);
					info = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + fcb->FileName.Length;
					status = STATUS_SUCCESS;
				}
				__leave;
			}
			break;
		case FileNetworkOpenInformation:
			DDbgPrint("  FileNetworkOpenInformation\n");
			break;
		case FilePositionInformation:
			{
				PFILE_POSITION_INFORMATION posInfo;
			
				DDbgPrint("  FilePositionInformation\n");

                if (irpSp->Parameters.QueryFile.Length < sizeof(FILE_POSITION_INFORMATION)) {
                    status = STATUS_INFO_LENGTH_MISMATCH;

                }
                else {
                    posInfo = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
                    ASSERT(posInfo != NULL);

                    RtlZeroMemory(posInfo, sizeof(FILE_POSITION_INFORMATION));

                    if (fileObject->CurrentByteOffset.QuadPart < 0)
                    {
                        status = STATUS_INVALID_PARAMETER;
                    }
                    else
                    {
                        // set the current file offset
                        posInfo->CurrentByteOffset = fileObject->CurrentByteOffset;

                        info = sizeof(FILE_POSITION_INFORMATION);
                        status = STATUS_SUCCESS;
                    }
                }
				__leave;
			}
			break;
		case FileStreamInformation:
			DDbgPrint("  FileStreamInformation\n");
			break;
		default:
			DDbgPrint("  unknown type:%d\n", irpSp->Parameters.QueryFile.FileInformationClass);
			break;
		}


		// if it is not treadted in swich case

		// calculate the length of EVENT_CONTEXT
		// sum of it's size and file name length
		eventLength = sizeof(EVENT_CONTEXT) + fcb->FileName.Length;

		eventContext = AllocateEventContext(vcb->Dcb, Irp, eventLength, ccb);
				
		if (eventContext == NULL) {
			status = STATUS_INSUFFICIENT_RESOURCES;
			__leave;
		}
			
		eventContext->Context = ccb->UserContext;
		//DDbgPrint("   get Context %X\n", (ULONG)ccb->UserContext);

		eventContext->File.FileInformationClass =
			irpSp->Parameters.QueryFile.FileInformationClass;

		// bytes length which is able to be returned
		eventContext->File.BufferLength = irpSp->Parameters.QueryFile.Length;

		// copy file name to EventContext from FCB
		eventContext->File.FileNameLength = fcb->FileName.Length;
		RtlCopyMemory(eventContext->File.FileName,
						fcb->FileName.Buffer,
						fcb->FileName.Length);

		// register this IRP to pending IPR list
		status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);

	} __finally {

		if (status != STATUS_PENDING) {
			Irp->IoStatus.Status = status;
			Irp->IoStatus.Information = info;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			DokanPrintNTStatus(status);
		}

		DDbgPrint("<== DokanQueryInformation\n");

		FsRtlExitFileSystem();

	}

	return status;
}
Esempio n. 25
0
NTSTATUS
DokanDispatchWrite(
	__in PDEVICE_OBJECT DeviceObject,
	__in PIRP Irp
	)
{
	PIO_STACK_LOCATION	irpSp;
	PFILE_OBJECT		fileObject;
	NTSTATUS			status =STATUS_INVALID_PARAMETER;
	PEVENT_CONTEXT		eventContext;
	ULONG				eventLength;
	PDokanCCB			ccb;
	PDokanFCB			fcb;
	PDokanVCB			vcb;
	PVOID				buffer;
	ULONG				bufferLength;

	//PAGED_CODE();

	__try {

		FsRtlEnterFileSystem();

		DDbgPrint("==> DokanWrite");

		irpSp		= IoGetCurrentIrpStackLocation(Irp);
		fileObject	= irpSp->FileObject;

		if (fileObject == NULL) {
			DDbgPrint("  fileObject == NULL");
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		vcb = DeviceObject->DeviceExtension;

		if (GetIdentifierType(vcb) != VCB ||
			!DokanCheckCCB(vcb->Dcb, fileObject->FsContext2)) {
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		DDbgPrint("  ProcessId %lu\n", IoGetRequestorProcessId(Irp));
		DokanPrintFileName(fileObject);

		ccb			= fileObject->FsContext2;
		ASSERT(ccb != NULL);

		fcb			= ccb->Fcb;
		ASSERT(fcb != NULL);

		if (fcb->Flags & DOKAN_FILE_DIRECTORY) {
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		if (irpSp->Parameters.Write.Length == 0) {
			status = STATUS_SUCCESS;
			__leave;
		}

		if (Irp->MdlAddress) {
			DDbgPrint("  use MdlAddress");
			buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
		} else {
			DDbgPrint("  use UserBuffer");
			buffer = Irp->UserBuffer;
		}

		if (buffer == NULL) {
			DDbgPrint("  buffer == NULL");
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		// the length of EventContext is sum of length to write and length of file name
		eventLength = sizeof(EVENT_CONTEXT)
							+ irpSp->Parameters.Write.Length
							+ fcb->FileName.Length;

		eventContext = AllocateEventContext(vcb->Dcb, Irp, eventLength, ccb);

		// no more memory!
		if (eventContext == NULL) {
			status = STATUS_INSUFFICIENT_RESOURCES;
			__leave;
		}

		eventContext->Context = ccb->UserContext;
		//DDbgPrint("   get Context %X\n", (ULONG)ccb->UserContext);

		// When the length is bigger than usual event notitfication buffer,
		// saves pointer in DiverContext to copy EventContext after allocating
		// more bigger memory.
		Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_EVENT] = eventContext;
		
		if (Irp->Flags & IRP_PAGING_IO) {
			DDbgPrint("  Paging IO");
			eventContext->FileFlags |= DOKAN_PAGING_IO;
		}
		if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
			DDbgPrint("  Synchronous IO");
			eventContext->FileFlags |= DOKAN_SYNCHRONOUS_IO;
		}

		// offset of file to write
		eventContext->Write.ByteOffset = irpSp->Parameters.Write.ByteOffset;

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

			eventContext->FileFlags |= DOKAN_WRITE_TO_END_OF_FILE;
			DDbgPrint("  WriteOffset = end of file");
		}

		if ((fileObject->Flags & FO_SYNCHRONOUS_IO) &&
			((irpSp->Parameters.Write.ByteOffset.LowPart == FILE_USE_FILE_POINTER_POSITION) &&
			(irpSp->Parameters.Write.ByteOffset.HighPart == -1))) {
			// NOTE:
			// http://msdn.microsoft.com/en-us/library/ms795960.aspx
			// Do not check IrpSp->Parameters.Write.ByteOffset.QuadPart == 0
			// Probably the document is wrong.
			eventContext->Write.ByteOffset.QuadPart = fileObject->CurrentByteOffset.QuadPart;
		}

		// the size of buffer to write
		eventContext->Write.BufferLength = irpSp->Parameters.Write.Length;

		// the offset from the begining of structure
		// the contents to write will be copyed to this offset
		eventContext->Write.BufferOffset = FIELD_OFFSET(EVENT_CONTEXT, Write.FileName[0]) +
										fcb->FileName.Length + sizeof(WCHAR); // adds last null char

		// copies the content to write to EventContext
		RtlCopyMemory((PCHAR)eventContext + eventContext->Write.BufferOffset,
			buffer, irpSp->Parameters.Write.Length);

		// copies file name
		eventContext->Write.FileNameLength = fcb->FileName.Length;
		RtlCopyMemory(eventContext->Write.FileName, fcb->FileName.Buffer, fcb->FileName.Length);
		
		// When eventlength is less than event notification buffer,
		// returns it to user-mode using pending event.
		if (eventLength <= EVENT_CONTEXT_MAX_SIZE) {

			DDbgPrint("   Offset %d:%d, Length %d\n",
				irpSp->Parameters.Write.ByteOffset.HighPart,
				irpSp->Parameters.Write.ByteOffset.LowPart,
				irpSp->Parameters.Write.Length);

			// EventContext is no longer needed, clear it
			Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_EVENT] = 0;

			// register this IRP to IRP waiting list and make it pending status
			status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);

		// Resuests bigger memory
		// eventContext will be freed later using Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_EVENT]
		} else {
			// the length at lest file name can be stored
			ULONG	requestContextLength = max(sizeof(EVENT_CONTEXT), eventContext->Write.BufferOffset);
			PEVENT_CONTEXT requestContext = AllocateEventContext(vcb->Dcb, Irp, requestContextLength, ccb);

			// no more memory!
			if (requestContext == NULL) {
				status = STATUS_INSUFFICIENT_RESOURCES;
				Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_EVENT] = 0;
				DokanFreeEventContext(eventContext);
				__leave;
			}

			DDbgPrint("   Offset %d:%d, Length %d (request)\n",
				irpSp->Parameters.Write.ByteOffset.HighPart,
				irpSp->Parameters.Write.ByteOffset.LowPart,
				irpSp->Parameters.Write.Length);

			// copies from begining of EventContext to the end of file name
			RtlCopyMemory(requestContext, eventContext, eventContext->Write.BufferOffset);
			// puts actual size of RequestContext
			requestContext->Length = requestContextLength;
			// requsts enough size to copy EventContext
			requestContext->Write.RequestLength = eventLength;

			// regiters this IRP to IRP wainting list and make it pending status
			status = DokanRegisterPendingIrp(DeviceObject, Irp, requestContext, 0);
		}

	} __finally {

		// if status of IRP is not pending, must complete current IRP
		if (status != STATUS_PENDING) {
			Irp->IoStatus.Status = status;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			DokanPrintNTStatus(status);
		} else {
			DDbgPrint("  STATUS_PENDING");
		}

		DDbgPrint("<== DokanWrite");

		FsRtlExitFileSystem();

	}

	return status;
}
Esempio n. 26
0
NTSTATUS
DokanDispatchSetInformation(
	__in PDEVICE_OBJECT DeviceObject,
	__in PIRP Irp
   )
{

	NTSTATUS			status = STATUS_NOT_IMPLEMENTED;
	PIO_STACK_LOCATION  irpSp;
	PVOID				buffer;
	PFILE_OBJECT		fileObject;
	PDokanCCB			ccb;
	PDokanFCB			fcb;
	PDokanVCB			vcb;
	ULONG				eventLength;
	PFILE_OBJECT		targetFileObject;
	PEVENT_CONTEXT		eventContext;

	//PAGED_CODE();

    vcb = DeviceObject->DeviceExtension;

	__try {
		FsRtlEnterFileSystem();

		DDbgPrint("==> DokanSetInformationn\n");

		irpSp			= IoGetCurrentIrpStackLocation(Irp);
		fileObject		= irpSp->FileObject;
		
		if (fileObject == NULL) {
			DDbgPrint("  fileObject == NULL\n");
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}
		
		if (GetIdentifierType(vcb) != VCB ||
			!DokanCheckCCB(vcb->Dcb, fileObject->FsContext2)) {
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}
		
		ccb	= (PDokanCCB)fileObject->FsContext2;
		ASSERT(ccb != NULL);

		fcb = ccb->Fcb;
		ASSERT(fcb != NULL);

		DDbgPrint("  ProcessId %lu\n", IoGetRequestorProcessId(Irp));
		DokanPrintFileName(fileObject);

		buffer = Irp->AssociatedIrp.SystemBuffer;

		switch (irpSp->Parameters.SetFile.FileInformationClass) {
		case FileAllocationInformation:
			DDbgPrint("  FileAllocationInformation %lld\n",
						((PFILE_ALLOCATION_INFORMATION)buffer)->AllocationSize.QuadPart);
			break;
		case FileBasicInformation:
			DDbgPrint("  FileBasicInformation\n");
			break;
		case FileDispositionInformation:
			DDbgPrint("  FileDispositionInformation\n");
			break;
		case FileEndOfFileInformation:
			DDbgPrint("  FileEndOfFileInformation %lld\n",
						((PFILE_END_OF_FILE_INFORMATION)buffer)->EndOfFile.QuadPart);
			break;
		case FileLinkInformation:
			DDbgPrint("  FileLinkInformation\n");
			break;
		case FilePositionInformation:
			{
				PFILE_POSITION_INFORMATION posInfo;
				
				posInfo = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
				ASSERT(posInfo != NULL);

				DDbgPrint("  FilePositionInformation %lld\n",
								posInfo->CurrentByteOffset.QuadPart);
				fileObject->CurrentByteOffset = posInfo->CurrentByteOffset;

				status = STATUS_SUCCESS;

				__leave;
			}
			break;
		case FileRenameInformation:
			DDbgPrint("  FileRenameInformation\n");
			break;
		case FileValidDataLengthInformation:
			DDbgPrint("  FileValidDataLengthInformation\n");
			break;
		default:
			DDbgPrint("  unknown type:%d\n", irpSp->Parameters.SetFile.FileInformationClass);
			break;
		}


		//
		// when this IRP is not handled in swich case
		//

		// calcurate the size of EVENT_CONTEXT
		// it is sum of file name length and size of FileInformation
		eventLength = sizeof(EVENT_CONTEXT) + fcb->FileName.Length + 
						irpSp->Parameters.SetFile.Length;

		targetFileObject = irpSp->Parameters.SetFile.FileObject;

		if (targetFileObject) {
			DDbgPrint("  FileObject Specified %wZ\n", &(targetFileObject->FileName));
			eventLength += targetFileObject->FileName.Length;
		}

		eventContext = AllocateEventContext(vcb->Dcb, Irp, eventLength, ccb);
	
		if (eventContext == NULL) {
			status = STATUS_INSUFFICIENT_RESOURCES;
			__leave;
		}
	
		eventContext->Context = ccb->UserContext;

		eventContext->SetFile.FileInformationClass =
			irpSp->Parameters.SetFile.FileInformationClass;

		// the size of FileInformation
		eventContext->SetFile.BufferLength = irpSp->Parameters.SetFile.Length;

		// the offset from begining of structure to fill FileInfo
		eventContext->SetFile.BufferOffset = FIELD_OFFSET(EVENT_CONTEXT, SetFile.FileName[0]) +
												fcb->FileName.Length + sizeof(WCHAR); // the last null char
	
		// copy FileInformation
		RtlCopyMemory((PCHAR)eventContext + eventContext->SetFile.BufferOffset,
						Irp->AssociatedIrp.SystemBuffer,
						irpSp->Parameters.SetFile.Length);

		if (irpSp->Parameters.SetFile.FileInformationClass == FileRenameInformation ||
			irpSp->Parameters.SetFile.FileInformationClass == FileLinkInformation) {
			// We need to hanle FileRenameInformation separetly because the structure of FILE_RENAME_INFORMATION
			// has HANDLE type field, which size is different in 32 bit and 64 bit environment.
			// This cases problems when driver is 64 bit and user mode library is 32 bit.
			PFILE_RENAME_INFORMATION renameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;			
			PDOKAN_RENAME_INFORMATION renameContext = 
				(PDOKAN_RENAME_INFORMATION)((PCHAR)eventContext + eventContext->SetFile.BufferOffset);

			// This code assumes FILE_RENAME_INFORMATION and FILE_LINK_INFORMATION have
			// the same typse and fields.
			ASSERT(sizeof(FILE_RENAME_INFORMATION) == sizeof(FILE_LINK_INFORMATION));

			renameContext->ReplaceIfExists = renameInfo->ReplaceIfExists;
			renameContext->FileNameLength = renameInfo->FileNameLength;
			RtlCopyMemory(renameContext->FileName, renameInfo->FileName, renameInfo->FileNameLength);

			if (targetFileObject != NULL) {
				// if Parameters.SetFile.FileObject is specified, replase FILE_RENAME_INFO's file name by
				// FileObject's file name. The buffer size is already adjusted.
				DDbgPrint("  renameContext->FileNameLength %d\n", renameContext->FileNameLength);
				DDbgPrint("  renameContext->FileName %ws\n", renameContext->FileName);
				RtlZeroMemory(renameContext->FileName, renameContext->FileNameLength);
				RtlCopyMemory(renameContext->FileName, targetFileObject->FileName.Buffer, targetFileObject->FileName.Length);
				renameContext->FileNameLength = targetFileObject->FileName.Length;
			}
		}

		// copy the file name
		eventContext->SetFile.FileNameLength = fcb->FileName.Length;
		RtlCopyMemory(eventContext->SetFile.FileName,
						fcb->FileName.Buffer,
						fcb->FileName.Length);

		// register this IRP to waiting IRP list and make it pending status
		status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);

	} __finally {

		if (status != STATUS_PENDING) {
			Irp->IoStatus.Status = status;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			DokanPrintNTStatus(status);
		}


		DDbgPrint("<== DokanSetInformation\n");

		FsRtlExitFileSystem();
	}

	return status;
}
Esempio n. 27
0
NTSTATUS
FatFsdQueryVolumeInformation (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the Fsd part of the NtQueryVolumeInformation API
    call.

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the file
        being queried exists.

    Irp - Supplies the Irp being processed.

Return Value:

    NTSTATUS - The FSD status for the Irp.

--*/

{
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel;

    DebugTrace(+1, Dbg, "FatFsdQueryVolumeInformation\n", 0);

    //
    //  Call the common query routine, with blocking allowed if synchronous
    //

    FsRtlEnterFileSystem();

    TopLevel = FatIsIrpTopLevel( Irp );

    try {

        IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );

        Status = FatCommonQueryVolumeInfo( IrpContext, Irp );

    } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

        //
        //  We had some trouble trying to perform the requested
        //  operation, so we'll abort the I/O request with
        //  the error status that we get back from the
        //  execption code
        //

        Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
    }

    if (TopLevel) { IoSetTopLevelIrp( NULL ); }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

    DebugTrace(-1, Dbg, "FatFsdQueryVolumeInformation -> %08lx\n", Status);

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    return Status;
}
Esempio n. 28
0
BOOLEAN
Ext2FastIoQueryBasicInfo (
    IN PFILE_OBJECT             FileObject,
    IN BOOLEAN                  Wait,
    OUT PFILE_BASIC_INFORMATION Buffer,
    OUT PIO_STATUS_BLOCK        IoStatus,
    IN PDEVICE_OBJECT           DeviceObject)
{
    PEXT2_FCB   Fcb = NULL;
    BOOLEAN     Status = FALSE;
    BOOLEAN     FcbMainResourceAcquired = FALSE;

    __try {

        FsRtlEnterFileSystem();

        __try {

            if (IsExt2FsDevice(DeviceObject)) {
                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                __leave;
            }

            Fcb = (PEXT2_FCB) FileObject->FsContext;
            if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                __leave;
            }

            ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
                   (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
#if EXT2_DEBUG
            DEBUG(DL_INF, (
                      "Ext2FastIoQueryBasicInfo: %s %s %wZ\n",
                      Ext2GetCurrentProcessName(),
                      "FASTIO_QUERY_BASIC_INFO",
                      &Fcb->Mcb->FullName
                  ));
#endif
            if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) {
                if (!ExAcquireResourceSharedLite(
                            &Fcb->MainResource,
                            Wait)) {
                    __leave;
                }
                FcbMainResourceAcquired = TRUE;
            }

            RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION));

            /*
            typedef struct _FILE_BASIC_INFORMATION {
            LARGE_INTEGER   CreationTime;
            LARGE_INTEGER   LastAccessTime;
            LARGE_INTEGER   LastWriteTime;
            LARGE_INTEGER   ChangeTime;
            ULONG           FileAttributes;
            } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
            */

            if (IsRoot(Fcb)) {
                Buffer->CreationTime = Buffer->LastAccessTime =
                                           Buffer->LastWriteTime = Buffer->ChangeTime = Ext2NtTime(0);
            } else {
                Buffer->CreationTime = Fcb->Mcb->CreationTime;
                Buffer->LastAccessTime = Fcb->Mcb->LastAccessTime;
                Buffer->LastWriteTime = Fcb->Mcb->LastWriteTime;
                Buffer->ChangeTime = Fcb->Mcb->ChangeTime;
            }

            Buffer->FileAttributes = Fcb->Mcb->FileAttr;
            if (Buffer->FileAttributes == 0) {
                Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
            }

            IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
            IoStatus->Status = STATUS_SUCCESS;

            Status =  TRUE;

        } __except (EXCEPTION_EXECUTE_HANDLER) {
            IoStatus->Status = GetExceptionCode();
        }

    } __finally {

        if (FcbMainResourceAcquired) {
            ExReleaseResourceLite(&Fcb->MainResource);
        }

        FsRtlExitFileSystem();
    }

#if EXT2_DEBUG

    if (Status == FALSE) {

        DEBUG(DL_ERR, ("Ext2FastIoQueryBasicInfo: %s %s Status: FALSE ***\n",
                       Ext2GetCurrentProcessName(),
                       "FASTIO_QUERY_BASIC_INFO"));

    } else if (IoStatus->Status != STATUS_SUCCESS) {

        DEBUG(DL_ERR, (
                  "Ext2FastIoQueryBasicInfo: %s %s Status: %#x ***\n",
                  Ext2FastIoQueryBasicInfo,
                  "FASTIO_QUERY_BASIC_INFO",
                  IoStatus->Status
              ));
    }
#endif

    return Status;
}
Esempio n. 29
0
NTSTATUS
DokanDispatchDirectoryControl(
	__in PDEVICE_OBJECT DeviceObject,
	__in PIRP Irp
   )
{
	NTSTATUS			status		= STATUS_NOT_IMPLEMENTED;
	PFILE_OBJECT		fileObject;
	PIO_STACK_LOCATION	irpSp;
	PDokanVCB			vcb;

	//PAGED_CODE();

	__try {
		FsRtlEnterFileSystem();

		DDbgPrint("==> DokanDirectoryControl\n");

		irpSp		= IoGetCurrentIrpStackLocation(Irp);
		fileObject	= irpSp->FileObject;

		if (fileObject == NULL) {
			DDbgPrint("   fileObject is NULL\n");
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		vcb = DeviceObject->DeviceExtension;
		if (GetIdentifierType(vcb) != VCB ||
			!DokanCheckCCB(vcb->Dcb, fileObject->FsContext2)) {
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		DDbgPrint("  ProcessId %lu\n", IoGetRequestorProcessId(Irp));
		DokanPrintFileName(fileObject);

		if (irpSp->MinorFunction == IRP_MN_QUERY_DIRECTORY) {
			status = DokanQueryDirectory(DeviceObject, Irp);
	
		} else if( irpSp->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY) {
			status = DokanNotifyChangeDirectory(DeviceObject, Irp);
		} else {
			DDbgPrint("  invalid minor function\n");
			status = STATUS_INVALID_PARAMETER;
		}
	
	} __finally {

		if (status != STATUS_PENDING) {
			Irp->IoStatus.Status = status;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
		}

		DokanPrintNTStatus(status);
		DDbgPrint("<== DokanDirectoryControl\n");

		FsRtlExitFileSystem();
	}

	return status;
}
Esempio n. 30
0
BOOLEAN
CdFastQueryStdInfo (
    __in PFILE_OBJECT FileObject,
    __in BOOLEAN Wait,
    __out PFILE_STANDARD_INFORMATION Buffer,
    __out PIO_STATUS_BLOCK IoStatus,
    __in PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This routine is for the fast query call for standard file information.

Arguments:

    FileObject - Supplies the file object used in this operation

    Wait - Indicates if we are allowed to wait for the information

    Buffer - Supplies the output buffer to receive the basic information

    IoStatus - Receives the final status of the operation

Return Value:

    BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
        needs to take the long route.

--*/

{
    BOOLEAN Result = FALSE;
    TYPE_OF_OPEN TypeOfOpen;

    PFCB Fcb;

    PAGED_CODE();

    UNREFERENCED_PARAMETER( DeviceObject );

    ASSERT_FILE_OBJECT( FileObject );

    FsRtlEnterFileSystem();

    //
    //  Decode the file object to find the type of open and the data
    //  structures.
    //

    TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb );

    //
    //  We only support this request on initialized user file or directory objects.
    //

    if ((TypeOfOpen != UserFileOpen) &&
        ((TypeOfOpen != UserDirectoryOpen) || !FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED ))) {

        FsRtlExitFileSystem();
        return FALSE;
    }

    //
    //  Acquire the file shared to access the Fcb.
    //

    if (!ExAcquireResourceSharedLite( Fcb->Resource, Wait )) {

        FsRtlExitFileSystem();
        return FALSE;
    }

    //
    //  Use a try-finally to facilitate cleanup.
    //

    try {

        //
        //  Only deal with 'good' Fcb's.
        //

        if (CdVerifyFcbOperation( NULL, Fcb )) {

            //
            //  Check whether this is a directory.
            //

            if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {

                Buffer->AllocationSize.QuadPart =
                Buffer->EndOfFile.QuadPart = 0;

                Buffer->Directory = TRUE;

            } else {

                Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart;
                Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart;

                Buffer->Directory = FALSE;
            }

            Buffer->NumberOfLinks = 1;
            Buffer->DeletePending = FALSE;

            //
            //  Update the IoStatus block with the size of this data.
            //

            IoStatus->Status = STATUS_SUCCESS;
            IoStatus->Information = sizeof( FILE_STANDARD_INFORMATION );

            Result = TRUE;
        }

    } finally {

        ExReleaseResourceLite( Fcb->Resource );

        FsRtlExitFileSystem();
    }

    return Result;
}