NT4/private/ntos/cntfs/devctrl.c
2020-09-30 17:12:29 +02:00

272 lines
5.1 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
DevCtrl.c
Abstract:
This module implements the Device Control routines for Ntfs called by
the dispatch driver.
Author:
Gary Kimura [GaryKi] 28-May-1991
Revision History:
--*/
#include "NtfsProc.h"
//
// The local debug trace level
//
#define Dbg (DEBUG_TRACE_DEVCTRL)
//
// Local procedure prototypes
//
NTSTATUS
DeviceControlCompletionRoutine (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Contxt
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, NtfsCommonDeviceControl)
#pragma alloc_text(PAGE, NtfsFsdDeviceControl)
#endif
NTSTATUS
NtfsFsdDeviceControl (
IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine implements the FSD part of Device Control.
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
--*/
{
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, ("NtfsFsdDeviceControl\n") );
//
// Call the common Device Control 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 = NtfsCommonDeviceControl( 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, ("NtfsFsdDeviceControl -> %08lx\n", Status) );
return Status;
}
NTSTATUS
NtfsCommonDeviceControl (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
)
/*++
Routine Description:
This is the common routine for Device Control called by both the fsd and fsp
threads.
Arguments:
Irp - Supplies the Irp to process
Return Value:
NTSTATUS - The return status for the operation
--*/
{
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp;
PIO_STACK_LOCATION NextIrpSp;
PFILE_OBJECT FileObject;
TYPE_OF_OPEN TypeOfOpen;
PVCB Vcb;
PFCB Fcb;
PSCB Scb;
PCCB Ccb;
ASSERT_IRP_CONTEXT( IrpContext );
ASSERT_IRP( Irp );
PAGED_CODE();
//
// Get the current Irp stack location
//
IrpSp = IoGetCurrentIrpStackLocation( Irp );
DebugTrace( +1, Dbg, ("NtfsCommonDeviceControl\n") );
DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) );
DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) );
//
// Extract and decode the file object
//
FileObject = IrpSp->FileObject;
TypeOfOpen = NtfsDecodeFileObject( IrpContext, FileObject, &Vcb, &Fcb, &Scb, &Ccb, TRUE );
//
// The only type of opens we accept are user volume opens.
//
if (TypeOfOpen != UserVolumeOpen) {
NtfsCompleteRequest( &IrpContext, &Irp, STATUS_INVALID_PARAMETER );
DebugTrace( -1, Dbg, ("NtfsCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER) );
return STATUS_INVALID_PARAMETER;
}
//
// Get the next stack location, and copy over the stack parameter
// information
//
NextIrpSp = IoGetNextIrpStackLocation( Irp );
*NextIrpSp = *IrpSp;
//
// Send the request.
//
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
//
// Free the IrpContext and return to the caller.
//
NtfsDeleteIrpContext( &IrpContext );
DebugTrace( -1, Dbg, ("NtfsCommonDeviceControl -> %08lx\n", Status) );
return Status;
}
//
// Local support routine
//
NTSTATUS
DeviceControlCompletionRoutine (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Contxt
)
{
UNREFERENCED_PARAMETER( DeviceObject );
UNREFERENCED_PARAMETER( Contxt );
//
// Add the hack-o-ramma to fix formats.
//
if ( Irp->PendingReturned ) {
IoMarkIrpPending( Irp );
}
return STATUS_SUCCESS;
}