📄 cdooperations.c
字号:
/*++
Copyright (c) 1999 - 2002 Microsoft Corporation
Module Name:
operations.c
Abstract:
This is the CDO i/o operations module of the kernel mode filter driver implementing
CDO sample
Environment:
Kernel mode
--*/
#include "pch.h"
#include <dontuse.h>
//
// Assign text sections for each routine.
//
#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, CdoCreateControlDeviceObject)
#pragma alloc_text( PAGE, CdoDeleteControlDeviceObject)
#pragma alloc_text( PAGE, CdoMajorFunction)
#pragma alloc_text( PAGE, CdoHandlePrivateOpen)
#pragma alloc_text( PAGE, CdoHandlePrivateCleanup)
#pragma alloc_text( PAGE, CdoHandlePrivateClose)
#pragma alloc_text( PAGE, CdoHandlePrivateFsControl)
#pragma alloc_text( PAGE, CdoFastIoCheckIfPossible)
#pragma alloc_text( PAGE, CdoFastIoRead)
#pragma alloc_text( PAGE, CdoFastIoWrite)
#pragma alloc_text( PAGE, CdoFastIoQueryBasicInfo)
#pragma alloc_text( PAGE, CdoFastIoQueryStandardInfo)
#pragma alloc_text( PAGE, CdoFastIoLock)
#pragma alloc_text( PAGE, CdoFastIoUnlockSingle)
#pragma alloc_text( PAGE, CdoFastIoUnlockAll)
#pragma alloc_text( PAGE, CdoFastIoUnlockAllByKey)
#pragma alloc_text( PAGE, CdoFastIoDeviceControl)
#pragma alloc_text( PAGE, CdoFastIoQueryNetworkOpenInfo)
#pragma alloc_text( PAGE, CdoFastIoMdlRead)
#pragma alloc_text( NONPAGED, CdoFastIoMdlReadComplete)
#pragma alloc_text( PAGE, CdoFastIoPrepareMdlWrite)
#pragma alloc_text( NONPAGED, CdoFastIoMdlWriteComplete)
#pragma alloc_text( PAGE, CdoFastIoReadCompressed)
#pragma alloc_text( PAGE, CdoFastIoWriteCompressed)
#pragma alloc_text( NONPAGED, CdoFastIoMdlReadCompleteCompressed)
#pragma alloc_text( NONPAGED, CdoFastIoMdlWriteCompleteCompressed)
#pragma alloc_text( PAGE, CdoFastIoQueryOpen)
#pragma alloc_text( PAGE, CdoHandlePrivateOpen )
#pragma alloc_text( PAGE, CdoHandlePrivateCleanup )
#pragma alloc_text( PAGE, CdoHandlePrivateClose )
#pragma alloc_text( PAGE, CdoHandlePrivateFsControl )
#endif
//
// Fast IO dispatch routines
//
FAST_IO_DISPATCH CdoFastIoDispatch =
{
sizeof(FAST_IO_DISPATCH),
CdoFastIoCheckIfPossible, // CheckForFastIo
CdoFastIoRead, // FastIoRead
CdoFastIoWrite, // FastIoWrite
CdoFastIoQueryBasicInfo, // FastIoQueryBasicInfo
CdoFastIoQueryStandardInfo, // FastIoQueryStandardInfo
CdoFastIoLock, // FastIoLock
CdoFastIoUnlockSingle, // FastIoUnlockSingle
CdoFastIoUnlockAll, // FastIoUnlockAll
CdoFastIoUnlockAllByKey, // FastIoUnlockAllByKey
CdoFastIoDeviceControl, // FastIoDeviceControl
NULL, // AcquireFileForNtCreateSection
NULL, // ReleaseFileForNtCreateSection
NULL, // FastIoDetachDevice
CdoFastIoQueryNetworkOpenInfo, // FastIoQueryNetworkOpenInfo
NULL, // AcquireForModWrite
CdoFastIoMdlRead, // MdlRead
CdoFastIoMdlReadComplete, // MdlReadComplete
CdoFastIoPrepareMdlWrite, // PrepareMdlWrite
CdoFastIoMdlWriteComplete, // MdlWriteComplete
CdoFastIoReadCompressed, // FastIoReadCompressed
CdoFastIoWriteCompressed, // FastIoWriteCompressed
CdoFastIoMdlReadCompleteCompressed, // MdlReadCompleteCompressed
CdoFastIoMdlWriteCompleteCompressed, // MdlWriteCompleteCompressed
CdoFastIoQueryOpen, // FastIoQueryOpen
NULL, // ReleaseForModWrite
NULL, // AcquireForCcFlush
NULL, // ReleaseForCcFlush
};
NTSTATUS
CdoCreateControlDeviceObject(
__inout PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
This routine handles the IRPs that are directed to the control
device object.
Arguments:
DriverObject - driver object for this driver
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
UNICODE_STRING nameString;
ULONG i;
//
// Create our control device object
//
DebugTrace( DEBUG_TRACE_CDO_CREATE_DELETE,
("[Cdo]: Creating CDO ... \n") );
RtlInitUnicodeString( &nameString, CONTROL_DEVICE_OBJECT_NAME );
status = IoCreateDevice( DriverObject,
0,
&nameString,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&Globals.FilterControlDeviceObject);
if ( !NT_SUCCESS( status ) ) {
DebugTrace( DEBUG_TRACE_CDO_CREATE_DELETE | DEBUG_TRACE_ERROR,
("[Cdo]: Failure to create CDO. IoCreateDevice failed with status 0x%x. \n",
status) );
return status;
}
//
// Initialize the driver object with this driver's entry points.
// Most are simply passed through to some other device driver.
//
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
DriverObject->MajorFunction[i] = CdoMajorFunction;
}
DriverObject->FastIoDispatch = &CdoFastIoDispatch;
DebugTrace( DEBUG_TRACE_CDO_CREATE_DELETE,
("[Cdo]: Creating CDO successful\n") );
return STATUS_SUCCESS;
}
VOID
CdoDeleteControlDeviceObject(
VOID
)
/*++
Routine Description:
This routine deletes the control device object.
Arguments:
None
Return Value:
None
--*/
{
//
// Delete our control device object
//
DebugTrace( DEBUG_TRACE_CDO_CREATE_DELETE,
("[Cdo]: Deleting CDO ... \n") );
IoDeleteDevice( Globals.FilterControlDeviceObject );
DebugTrace( DEBUG_TRACE_CDO_CREATE_DELETE,
("[Cdo]: Deleting CDO successful\n") );
}
NTSTATUS
CdoMajorFunction(
__inout PDEVICE_OBJECT DeviceObject,
__inout PIRP Irp
)
/*++
Routine Description:
This routine handles the IRPs that are directed to the control
device object.
Arguments:
DeviceObject - control device object
Irp - the current Irp to process
Return Value:
Returns STATUS_INVALID_DEVICE_REQUEST if the CDO doesn't support that request
type, or the appropriate status otherwise.
--*/
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;
UNREFERENCED_PARAMETER( DeviceObject );
PAGED_CODE();
ASSERT( IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ) );
//
// default to success
//
status = STATUS_SUCCESS;
irpSp = IoGetCurrentIrpStackLocation(Irp);
DebugTrace( DEBUG_TRACE_CDO_ALL_OPERATIONS,
("[Cdo]: CdoMajorFunction entry ( Irp = %p, irpSp->MajorFunction = 0x%x )\n",
Irp,
irpSp->MajorFunction) );
switch (irpSp->MajorFunction) {
//
// IRP_MJ_CREATE is called to create a new HANDLE on CDO
//
case IRP_MJ_CREATE:
{
//
// Handle our private open
//
status = CdoHandlePrivateOpen(Irp);
Irp->IoStatus.Status = status;
if(NT_SUCCESS(status))
{
//
// If successful, return the file was opened
//
Irp->IoStatus.Information = FILE_OPENED;
}
else
{
Irp->IoStatus.Information = 0;
}
IoCompleteRequest( Irp, IO_NO_INCREMENT );
break;
}
//
// IRP_MJ_CLOSE is called when all references are gone.
// Note: this operation can not be failed. It must succeed.
//
case IRP_MJ_CLOSE:
{
CdoHandlePrivateClose( Irp );
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
break;
}
//
// IRP_MJ_DEVICE_CONTROL is how most user-mode api's drop into here
//
case IRP_MJ_FILE_SYSTEM_CONTROL:
{
ULONG Operation;
ULONG OutputBufferLength;
ULONG InputBufferLength;
PVOID InputBuffer;
PVOID OutputBuffer;
Operation = irpSp->Parameters.FileSystemControl.FsControlCode;
InputBufferLength = irpSp->Parameters.FileSystemControl.InputBufferLength;
OutputBufferLength = irpSp->Parameters.FileSystemControl.OutputBufferLength;
InputBuffer = Irp->AssociatedIrp.SystemBuffer;
OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
//
// The caller will update the IO status block
//
status = CdoHandlePrivateFsControl (DeviceObject,
Operation,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
&Irp->IoStatus,
Irp );
break;
}
//
// IRP_MJ_CLEANUP is called when all handles are closed
// Note: this operation can not be failed. It must succeed.
//
case IRP_MJ_CLEANUP:
{
CdoHandlePrivateCleanup( Irp );
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
break;
}
default:
{
//
// unsupported!
//
DebugTrace( DEBUG_TRACE_CDO_ALL_OPERATIONS | DEBUG_TRACE_ERROR,
("[Cdo]: Unsupported Major Function 0x%x ( Irp = %p )\n",
irpSp->MajorFunction,
Irp) );
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
status = STATUS_INVALID_DEVICE_REQUEST;
}
}
DebugTrace( DEBUG_TRACE_CDO_ALL_OPERATIONS,
("[Cdo]: CdoMajorFunction exit ( Irp = %p, irpSp->MajorFunction = 0x%x, status = 0x%x )\n",
Irp,
irpSp->MajorFunction,
status) );
return status;
}
NTSTATUS
CdoHandlePrivateOpen(
__in PIRP Irp
)
/*++
Routine Description:
This routine handles create IRPs that are directed to the control
device object.
Arguments:
Irp - the current Irp to process
Return Value:
Returns STATUS_DEVICE_ALREADY_ATTACHED if the CDO has already been opened
Returns STATUS_SUCCESS otherwise
Note:
This sample supports only one outstanding create on the CDO at a time
--*/
{
NTSTATUS status;
UNREFERENCED_PARAMETER( Irp );
PAGED_CODE();
DebugTrace( DEBUG_TRACE_CDO_SUPPORTED_OPERATIONS,
("[Cdo]: CdoHandlePrivateOpen entry ( Irp = %p )\n",
Irp) );
CdoAcquireResourceExclusive( &Globals.Resource );
if (FlagOn( Globals.Flags, GLOBAL_DATA_F_CDO_OPEN_HANDLE ) ||
FlagOn( Globals.Flags, GLOBAL_DATA_F_CDO_OPEN_REF )) {
//
// Sanity - if we have a handle open against this CDO
// we must have an outstanding reference as well
//
ASSERT( !FlagOn( Globals.Flags, GLOBAL_DATA_F_CDO_OPEN_HANDLE ) ||
FlagOn( Globals.Flags, GLOBAL_DATA_F_CDO_OPEN_REF ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -