Win7对目标文件夹进行访问控制

在minifilter框架下,对目标文件夹进行访问控制。

/*++

Copyright (c) 1999 - 2002  Microsoft Corporation

Module Name:

passThrough.c

Abstract:

This is the main module of the passThrough miniFilter driver.
This filter hooks all IO operations for both pre and post operation
callbacks.  The filter passes through the operations.

Environment:

Kernel mode

--*/

#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>
#include <ntddscsi.h>		
#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")


PFLT_FILTER gFilterHandle;
ULONG_PTR OperationStatusCtx = 1;

#define PTDBG_TRACE_ROUTINES            0x00000001
#define PTDBG_TRACE_OPERATION_STATUS    0x00000002

ULONG gTraceFlags = 0;

#define PT_DBG_PRINT( _dbgLevel, _string )          \
	(FlagOn(gTraceFlags,(_dbgLevel)) ?              \
	DbgPrint _string :                          \
	((int)0))

/*************************************************************************
Prototypes
*************************************************************************/

DRIVER_INITIALIZE DriverEntry;
NTSTATUS
	DriverEntry (
	__in PDRIVER_OBJECT DriverObject,
	__in PUNICODE_STRING RegistryPath
	);

NTSTATUS
	PtInstanceSetup (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in FLT_INSTANCE_SETUP_FLAGS Flags,
	__in DEVICE_TYPE VolumeDeviceType,
	__in FLT_FILESYSTEM_TYPE VolumeFilesystemType
	);

VOID
	PtInstanceTeardownStart (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in FLT_INSTANCE_TEARDOWN_FLAGS Flags
	);

VOID
	PtInstanceTeardownComplete (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in FLT_INSTANCE_TEARDOWN_FLAGS Flags
	);

NTSTATUS
	PtUnload (
	__in FLT_FILTER_UNLOAD_FLAGS Flags
	);

NTSTATUS
	PtInstanceQueryTeardown (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
	);

FLT_PREOP_CALLBACK_STATUS
	PtPreOperationPassThrough (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
	);

VOID
	PtOperationStatusCallback (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in PFLT_IO_PARAMETER_BLOCK ParameterSnapshot,
	__in NTSTATUS OperationStatus,
	__in PVOID RequesterContext
	);

FLT_POSTOP_CALLBACK_STATUS
	PtPostOperationPassThrough (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in_opt PVOID CompletionContext,
	__in FLT_POST_OPERATION_FLAGS Flags
	);

FLT_PREOP_CALLBACK_STATUS
	PtPreOperationNoPostOperationPassThrough (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
	);

BOOLEAN
	PtDoRequestOperationStatus(
	__in PFLT_CALLBACK_DATA Data
	);

//IRP_MJ_CREATE control function
FLT_PREOP_CALLBACK_STATUS
	PtPreOperationCreateControl (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
	);
FLT_POSTOP_CALLBACK_STATUS
	PtPostOperationCreateControl (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in_opt PVOID CompletionContext,
	__in FLT_POST_OPERATION_FLAGS Flags
	);
//
//  Assign text sections for each routine.
//

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, PtUnload)
#pragma alloc_text(PAGE, PtInstanceQueryTeardown)
#pragma alloc_text(PAGE, PtInstanceSetup)
#pragma alloc_text(PAGE, PtInstanceTeardownStart)
#pragma alloc_text(PAGE, PtInstanceTeardownComplete)
#endif

//
//  operation registration
//

CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
	{ IRP_MJ_CREATE,
	0,
	PtPreOperationCreateControl,
	PtPostOperationCreateControl },
	{ IRP_MJ_OPERATION_END }
};

//
//  This defines what we want to filter with FltMgr
//

CONST FLT_REGISTRATION FilterRegistration = {

	sizeof( FLT_REGISTRATION ),         //  Size
	FLT_REGISTRATION_VERSION,           //  Version
	0,                                  //  Flags

	NULL,                               //  Context
	Callbacks,                          //  Operation callbacks

	PtUnload,                           //  MiniFilterUnload

	PtInstanceSetup,                    //  InstanceSetup
	PtInstanceQueryTeardown,            //  InstanceQueryTeardown
	PtInstanceTeardownStart,            //  InstanceTeardownStart
	PtInstanceTeardownComplete,         //  InstanceTeardownComplete

	NULL,                               //  GenerateFileName
	NULL,                               //  GenerateDestinationFileName
	NULL                                //  NormalizeNameComponent

};

PWCHAR prefixName = L"invisible";
ULONG prefixLength = 9;

NTSTATUS
	PtInstanceSetup (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in FLT_INSTANCE_SETUP_FLAGS Flags,
	__in DEVICE_TYPE VolumeDeviceType,
	__in FLT_FILESYSTEM_TYPE VolumeFilesystemType
	)
	/*++

	Routine Description:

	This routine is called whenever a new instance is created on a volume. This
	gives us a chance to decide if we need to attach to this volume or not.

	If this routine is not defined in the registration structure, automatic
	instances are alwasys created.

	Arguments:

	FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
	opaque handles to this filter, instance and its associated volume.

	Flags - Flags describing the reason for this attach request.

	Return Value:

	STATUS_SUCCESS - attach
	STATUS_FLT_DO_NOT_ATTACH - do not attach

	--*/
{
	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( Flags );
	UNREFERENCED_PARAMETER( VolumeDeviceType );
	UNREFERENCED_PARAMETER( VolumeFilesystemType );

	PAGED_CODE();

	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!PtInstanceSetup: Entered\n") );

	return STATUS_SUCCESS;
}


NTSTATUS
	PtInstanceQueryTeardown (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
	)
	/*++

	Routine Description:

	This is called when an instance is being manually deleted by a
	call to FltDetachVolume or FilterDetach thereby giving us a
	chance to fail that detach request.

	If this routine is not defined in the registration structure, explicit
	detach requests via FltDetachVolume or FilterDetach will always be
	failed.

	Arguments:

	FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
	opaque handles to this filter, instance and its associated volume.

	Flags - Indicating where this detach request came from.

	Return Value:

	Returns the status of this operation.

	--*/
{
	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( Flags );

	PAGED_CODE();

	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!PtInstanceQueryTeardown: Entered\n") );

	return STATUS_SUCCESS;
}


VOID
	PtInstanceTeardownStart (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in FLT_INSTANCE_TEARDOWN_FLAGS Flags
	)
	/*++

	Routine Description:

	This routine is called at the start of instance teardown.

	Arguments:

	FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
	opaque handles to this filter, instance and its associated volume.

	Flags - Reason why this instance is been deleted.

	Return Value:

	None.

	--*/
{
	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( Flags );

	PAGED_CODE();

	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!PtInstanceTeardownStart: Entered\n") );
}


VOID
	PtInstanceTeardownComplete (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in FLT_INSTANCE_TEARDOWN_FLAGS Flags
	)
	/*++

	Routine Description:

	This routine is called at the end of instance teardown.

	Arguments:

	FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
	opaque handles to this filter, instance and its associated volume.

	Flags - Reason why this instance is been deleted.

	Return Value:

	None.

	--*/
{
	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( Flags );

	PAGED_CODE();

	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!PtInstanceTeardownComplete: Entered\n") );
}


/*************************************************************************
MiniFilter initialization and unload routines.
*************************************************************************/

NTSTATUS
	DriverEntry (
	__in PDRIVER_OBJECT DriverObject,
	__in PUNICODE_STRING RegistryPath
	)
	/*++

	Routine Description:

	This is the initialization routine for this miniFilter driver.  This
	registers with FltMgr and initializes all global data structures.

	Arguments:

	DriverObject - Pointer to driver object created by the system to
	represent this driver.

	RegistryPath - Unicode string identifying where the parameters for this
	driver are located in the registry.

	Return Value:

	Returns STATUS_SUCCESS.

	--*/
{
	NTSTATUS status;

	UNREFERENCED_PARAMETER( RegistryPath );

	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!DriverEntry: Entered\n") );

	//
	//  Register with FltMgr to tell it our callback routines
	//

	status = FltRegisterFilter( DriverObject,
		&FilterRegistration,
		&gFilterHandle );

	ASSERT( NT_SUCCESS( status ) );

	if (NT_SUCCESS( status )) {

		//
		//  Start filtering i/o
		//

		status = FltStartFiltering( gFilterHandle );

		if (!NT_SUCCESS( status )) {

			FltUnregisterFilter( gFilterHandle );
		}
	}
	KdPrint(("hello driver!"));
	return status;
}

NTSTATUS
	PtUnload (
	__in FLT_FILTER_UNLOAD_FLAGS Flags
	)
	/*++

	Routine Description:

	This is the unload routine for this miniFilter driver. This is called
	when the minifilter is about to be unloaded. We can fail this unload
	request if this is not a mandatory unloaded indicated by the Flags
	parameter.

	Arguments:

	Flags - Indicating if this is a mandatory unload.

	Return Value:

	Returns the final status of this operation.

	--*/
{
	UNREFERENCED_PARAMETER( Flags );

	PAGED_CODE();
	KdPrint(("hello drive1r! unload "));
	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!PtUnload: Entered\n") );

	FltUnregisterFilter( gFilterHandle );

	return STATUS_SUCCESS;
}


/*************************************************************************
MiniFilter callback routines.
*************************************************************************/
FLT_PREOP_CALLBACK_STATUS
	PtPreOperationPassThrough (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
	)
	/*++

	Routine Description:

	This routine is the main pre-operation dispatch routine for this
	miniFilter. Since this is just a simple passThrough miniFilter it
	does not do anything with the callbackData but rather return
	FLT_PREOP_SUCCESS_WITH_CALLBACK thereby passing it down to the next
	miniFilter in the chain.

	This is non-pageable because it could be called on the paging path

	Arguments:

	Data - Pointer to the filter callbackData that is passed to us.

	FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
	opaque handles to this filter, instance, its associated volume and
	file object.

	CompletionContext - The context for the completion routine for this
	operation.

	Return Value:

	The return value is the status of the operation.

	--*/
{
	NTSTATUS status;

	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( CompletionContext );

	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!PtPreOperationPassThrough: Entered\n") );
	KdPrint(("hello pre!"));
	//
	//  See if this is an operation we would like the operation status
	//  for.  If so request it.
	//
	//  NOTE: most filters do NOT need to do this.  You only need to make
	//        this call if, for example, you need to know if the oplock was
	//        actually granted.
	//

	if (PtDoRequestOperationStatus( Data )) {

		status = FltRequestOperationStatusCallback( Data,
			PtOperationStatusCallback,
			(PVOID)(++OperationStatusCtx) );
		if (!NT_SUCCESS(status)) {

			PT_DBG_PRINT( PTDBG_TRACE_OPERATION_STATUS,
				("PassThrough!PtPreOperationPassThrough: FltRequestOperationStatusCallback Failed, status=%08x\n",
				status) );
		}
	}

	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}



VOID
	PtOperationStatusCallback (
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in PFLT_IO_PARAMETER_BLOCK ParameterSnapshot,
	__in NTSTATUS OperationStatus,
	__in PVOID RequesterContext
	)
	/*++

	Routine Description:

	This routine is called when the given operation returns from the call
	to IoCallDriver.  This is useful for operations where STATUS_PENDING
	means the operation was successfully queued.  This is useful for OpLocks
	and directory change notification operations.

	This callback is called in the context of the originating thread and will
	never be called at DPC level.  The file object has been correctly
	referenced so that you can access it.  It will be automatically
	dereferenced upon return.

	This is non-pageable because it could be called on the paging path

	Arguments:

	FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
	opaque handles to this filter, instance, its associated volume and
	file object.

	RequesterContext - The context for the completion routine for this
	operation.

	OperationStatus -

	Return Value:

	The return value is the status of the operation.

	--*/
{
	UNREFERENCED_PARAMETER( FltObjects );

	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!PtOperationStatusCallback: Entered\n") );
	KdPrint(("hello driver callbacks!"));
	PT_DBG_PRINT( PTDBG_TRACE_OPERATION_STATUS,
		("PassThrough!PtOperationStatusCallback: Status=%08x ctx=%p IrpMj=%02x.%02x \"%s\"\n",
		OperationStatus,
		RequesterContext,
		ParameterSnapshot->MajorFunction,
		ParameterSnapshot->MinorFunction,
		FltGetIrpName(ParameterSnapshot->MajorFunction)) );
}


FLT_PREOP_CALLBACK_STATUS
	PtPreOperationNoPostOperationPassThrough (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
	)
	/*++

	Routine Description:

	This routine is the main pre-operation dispatch routine for this
	miniFilter. Since this is just a simple passThrough miniFilter it
	does not do anything with the callbackData but rather return
	FLT_PREOP_SUCCESS_WITH_CALLBACK thereby passing it down to the next
	miniFilter in the chain.

	This is non-pageable because it could be called on the paging path

	Arguments:

	Data - Pointer to the filter callbackData that is passed to us.

	FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
	opaque handles to this filter, instance, its associated volume and
	file object.

	CompletionContext - The context for the completion routine for this
	operation.

	Return Value:

	The return value is the status of the operation.

	--*/
{
	UNREFERENCED_PARAMETER( Data );
	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( CompletionContext );

	PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
		("PassThrough!PtPreOperationNoPostOperationPassThrough: Entered\n") );
	KdPrint(("hello d2234river!"));
	return FLT_PREOP_SUCCESS_NO_CALLBACK;
}


BOOLEAN
	PtDoRequestOperationStatus(
	__in PFLT_CALLBACK_DATA Data
	)
	/*++

	Routine Description:

	This identifies those operations we want the operation status for.  These
	are typically operations that return STATUS_PENDING as a normal completion
	status.

	Arguments:

	Return Value:

	TRUE - If we want the operation status
	FALSE - If we don't

	--*/
{
	PFLT_IO_PARAMETER_BLOCK iopb = Data->Iopb;

	//
	//  return boolean state based on which operations we are interested in
	//

	return (BOOLEAN)

		//
		//  Check for oplock operations
		//

		(((iopb->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
		((iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_FILTER_OPLOCK)  ||
		(iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_BATCH_OPLOCK)   ||
		(iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_1) ||
		(iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2)))

		||

		//
		//    Check for directy change notification
		//

		((iopb->MajorFunction == IRP_MJ_DIRECTORY_CONTROL) &&
		(iopb->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY))
		);
}
BOOLEAN NPUnicodeStringToChar(PUNICODE_STRING UniName, char Name[])
{
	ANSI_STRING	AnsiName;			
	NTSTATUS	ntstatus;
	char*		nameptr;			

	__try {	    		   		    		
		ntstatus = RtlUnicodeStringToAnsiString(&AnsiName, UniName, TRUE);		

		if (AnsiName.Length < 260) {
			nameptr = (PCHAR)AnsiName.Buffer;
			//Convert into upper case and copy to buffer
			strcpy(Name, _strupr(nameptr));						    	    
			//DbgPrint("NPUnicodeStringToChar : %s\n", Name);	
		}		  	
		RtlFreeAnsiString(&AnsiName);		 
	} 
	__except(EXCEPTION_EXECUTE_HANDLER) {
		DbgPrint("NPUnicodeStringToChar EXCEPTION_EXECUTE_HANDLER\n");	
		return FALSE;
	}
	return TRUE;
}     

FLT_PREOP_CALLBACK_STATUS
	PtPreOperationCreateControl (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
	)
{
	char FileName[1024]={"X:"};
	NTSTATUS status;
	PFLT_FILE_NAME_INFORMATION nameinfo;


	UNREFERENCED_PARAMETER( Data );
	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( CompletionContext);
	PAGED_CODE();

	//KdPrint(("ok"));
	_try
	{
		status = FltGetFileNameInformation(Data,FLT_FILE_NAME_NORMALIZED|FLT_FILE_NAME_QUERY_DEFAULT,&nameinfo);
		if (NT_SUCCESS(status))
		{
			FltParseFileNameInformation(nameinfo);
			if(NPUnicodeStringToChar(&nameinfo->Name, FileName))
			{
				if(strstr(FileName,"WQ"))
				{
					DbgPrint("filename %s",FileName);
					Data->IoStatus.Status = STATUS_ACCESS_DENIED;
					//Data->IoStatus.Information = 0;
					FltReleaseFileNameInformation( nameinfo );
					return FLT_PREOP_COMPLETE;	
				}
			}
		}
		FltReleaseFileNameInformation( nameinfo );      

	}
	_except(EXCEPTION_EXECUTE_HANDLER)
	{
		KdPrint(("Create Control Exception"));
	}
	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}


FLT_POSTOP_CALLBACK_STATUS
	PtPostOperationCreateControl (
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__in_opt PVOID CompletionContext,
	__in FLT_POST_OPERATION_FLAGS Flags
	)
{
	return FLT_POSTOP_FINISHED_PROCESSING;
}

编译环境为Windows win7  X86 checked build environment

编译source、makefile 安装inf与上一篇中相同。

此驱动不是特别稳定,有时候会抛出异常,利用dbgview可以看到,后续再改进。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值