⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 specialiofunction.cpp

📁 一个过滤层文件系统驱动的完整代码,实现了文件的加密,操作截获等
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	ExInterlockedAddUlong((unsigned long *)&RealDevice->ReferenceCount, 1, IopDatabaseLock);

	if (Vpb)
	{
		KIRQL Irql;

		ASSERT(FlagOn(Vpb->Flags, VPB_MOUNTED) && !FlagOn(Vpb->Flags, VPB_LOCKED));

		//
		// Increment Vpb's reference count, if one exists.
		//

		IoAcquireVpbSpinLock(&Irql);
		Vpb->ReferenceCount++;
		IoReleaseVpbSpinLock(Irql);
	}
}



NTSTATUS
FsTPMQueryInformationFile (
						IN PVCB Vcb,
						IN PFILE_OBJECT FileObject,
						IN FILE_INFORMATION_CLASS FileInformationClass,
						OUT PVOID FileInformation,
						IN ULONG Length,
						OUT PULONG ResultLength
						)
{
	PDEVICE_OBJECT DeviceObject =  Vcb->NextLowerDevice;
	PFAST_IO_DISPATCH FastIoDispatch = 	DeviceObject->DriverObject->FastIoDispatch;
	NTSTATUS Status;
	KEVENT Event;
	IO_STATUS_BLOCK IoStatus;
	PIRP Irp;
	PIO_STACK_LOCATION NextIrpSp;

		//
		// Try to do this request through the FastIo if possible.
		//

		if (FastIoDispatch &&
			(FileInformationClass ==  FileBasicInformation && 	FastIoDispatch->FastIoQueryBasicInfo) ||
			(FileInformationClass ==  FileStandardInformation && FastIoDispatch->FastIoQueryStandardInfo)) 
		{

			//
			// Call some FastIo routine and remember its return value.
			//

			BOOLEAN Done;

			if (FileInformationClass ==  FileBasicInformation)
			{
				Done =  FastIoDispatch->FastIoQueryBasicInfo( FileObject,TRUE,(PFILE_BASIC_INFORMATION)FileInformation,&IoStatus,DeviceObject );
			}

			else
			{
				Done =  FastIoDispatch->FastIoQueryStandardInfo( FileObject,TRUE,(PFILE_STANDARD_INFORMATION)FileInformation,&IoStatus,DeviceObject );
			}

			//
			// If we are done return to the caller with request's status.
			//

			if (Done)
			{
				*ResultLength =  IoStatus.Information;
				return IoStatus.Status;
			}
		}

		//
		// Now we must go through the standard IRP path so
		// initialize event on which we will occasionaly wait.
		//

		KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

		//
		// Allocate the IRP with appropriate number of stack locations.
		//

		Irp =  IoAllocateIrp(DeviceObject->StackSize, FALSE);

		if (!Irp)
		{
			return STATUS_INSUFFICIENT_RESOURCES;
		}

		//
		// Set basic fields in Irp like an OriginalFileObject, Thread and so on.
		// Also Flags are set to make this request synchronous and buffered.
		//

		Irp->Tail.Overlay.OriginalFileObject =  FileObject;
		Irp->Tail.Overlay.Thread =  PsGetCurrentThread();

		Irp->RequestorMode =  KernelMode;
		Irp->UserIosb =  &IoStatus;
		Irp->UserEvent =  &Event;

		SetFlag(Irp->Flags, IRP_SYNCHRONOUS_API | IRP_BUFFERED_IO);

		//
		// Set basic fields in the next stack location like a MajorFunction
		// and FileObject.
		//

		NextIrpSp =  IoGetNextIrpStackLocation(Irp);

		NextIrpSp->MajorFunction =  IRP_MJ_QUERY_INFORMATION;
		NextIrpSp->FileObject =  FileObject;

		//
		// Set caller's parameters for this request like Length, Buffer
		// and FileInformationClass.
		//

		NextIrpSp->Parameters.QueryFile.Length =  Length;
		NextIrpSp->Parameters.QueryFile.FileInformationClass =  FileInformationClass;

		Irp->AssociatedIrp.SystemBuffer =  FileInformation;

		//
		// Before we call the FSD to process this request we must set
		// completion routine which will be responsible to free the Irp
		// and to do some little postprocessing.
		//

		IoSetCompletionRoutine( Irp,FsTPMSynchronousApiCompletion,NULL,TRUE,TRUE,TRUE );

		//
		// Call the File System Driver to do the task requested by caller.
		//	

		Status =  IoCallDriver(DeviceObject, Irp);

		if (Status ==  STATUS_PENDING)
		{
			(VOID)KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);

			Status =  IoStatus.Status;
		}

		//
		// Return to our caller with request's status.
		//

		*ResultLength =  IoStatus.Information;
		return Status;
}

//
//
//

NTSTATUS
FsTPMSetInformationFile (
					  IN PVCB Vcb,
					  IN PFILE_OBJECT FileObject,
					  IN FILE_INFORMATION_CLASS FileInformationClass,
					  IN PVOID FileInformation,
					  IN ULONG Length
					  )
{
	PDEVICE_OBJECT DeviceObject =  Vcb->NextLowerDevice;
	NTSTATUS Status;
	KEVENT Event;
	IO_STATUS_BLOCK IoStatus;
	PIRP Irp;
	PIO_STACK_LOCATION NextIrpSp;

	//
	// Initialize event on which we will occasionaly wait.
	//

	KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

	//
	// Allocate the IRP with appropriate number of stack locations.
	//

	Irp =  IoAllocateIrp(DeviceObject->StackSize, FALSE);

	if (!Irp)
	{
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	//
	// Set basic fields in Irp like an OriginalFileObject, Thread and so on.
	// Also Flags are set to make this request synchronous and buffered.
	//

	Irp->Tail.Overlay.OriginalFileObject =  FileObject;
	Irp->Tail.Overlay.Thread =  PsGetCurrentThread();

	Irp->RequestorMode =  KernelMode;
	Irp->UserIosb =  &IoStatus;
	Irp->UserEvent =  &Event;

	SetFlag(Irp->Flags, IRP_SYNCHRONOUS_API | IRP_BUFFERED_IO);

	//
	// Set basic fields in the next stack location like a MajorFunction
	// and FileObject.
	//

	NextIrpSp =  IoGetNextIrpStackLocation(Irp);

	NextIrpSp->MajorFunction =  IRP_MJ_SET_INFORMATION;
	NextIrpSp->FileObject =  FileObject;

	//
	// Set caller's parameters for this request like Length, Buffer
	// and FileInformationClass.
	//

	NextIrpSp->Parameters.SetFile.Length =  Length;
	NextIrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;

	Irp->AssociatedIrp.SystemBuffer =  FileInformation;

	//
	// Do some preprocessing for Rename and Link requests.
	//

	ASSERT((FileInformationClass <=  FileMaximumInformation) &&
		(FileInformationClass !=  FileModeInformation) &&
		(FileInformationClass !=  FileObjectIdInformation) &&
		(FileInformationClass !=  FileMoveClusterInformation));

	if (FileInformationClass ==  FileRenameInformation ||
		FileInformationClass ==  FileLinkInformation) 
	{

		PFILE_RENAME_INFORMATION RenameInfo =  (PFILE_RENAME_INFORMATION)FileInformation;

		ASSERT(RenameInfo->FileNameLength !=  0 && RenameInfo->RootDirectory ==  NULL);
		NextIrpSp->Parameters.SetFile.ReplaceIfExists =  RenameInfo->ReplaceIfExists;
	}

	//
	// Before we call the FSD to process this request we must set
	// completion routine which will be responsible to free the Irp
	// and to do some little postprocessing.
	//

	IoSetCompletionRoutine( Irp,FsTPMSynchronousApiCompletion,NULL,TRUE,TRUE,TRUE );

	//
	// Call the File System Driver to do the task requested by caller.
	//

	Status =  IoCallDriver(DeviceObject, Irp);

	if (Status ==  STATUS_PENDING)
	{
		(VOID)KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);

		Status =  IoStatus.Status;
	}

	//
	// Return to our caller with request's status.
	//	

	return Status;
}

//
//
//

NTSTATUS
FsTPMSynchronousApiCompletion (
							IN PDEVICE_OBJECT DeviceObject,
							IN PIRP Irp,
							IN PVOID Context
							)
{
	//ASSERT(DeviceObject ==  NULL && Context ==  NULL);

	//
	// If there is an AuxiliaryBuffer we have to free it.
	//

	if (Irp->Tail.Overlay.AuxiliaryBuffer !=  NULL)
	{
		ExFreePool(Irp->Tail.Overlay.AuxiliaryBuffer);
	}

	//
	// If there is a Mdl associated we have to deal with it
	//

	if (Irp->MdlAddress)
	{
		PMDL Mdl;
		KdPrint(("AGFS: Buffered requests should not have an MDL!\n"));
		KdBreakPoint();

		//
		//
		//

		Mdl =  Irp->MdlAddress;

		while (Mdl !=  NULL)
		{
			MmUnlockPages(Mdl);

			Mdl =  Mdl->Next;
		}

		IoFreeMdl(Irp->MdlAddress);
	}

	//
	// We must copy the IoStatus to UserIosb and set
	// the user event so the caller wakes up.
	//

	*Irp->UserIosb =  Irp->IoStatus;

	ASSERT(Irp->UserEvent !=  NULL);
	KeSetEvent(Irp->UserEvent, EVENT_INCREMENT, FALSE);

	//
	// Finally free the Irp.
	//

	IoFreeIrp(Irp);

	//
	// Prevent the IoCompleteRequest to do anything with
	// this already freed Irp.
	//

	return STATUS_MORE_PROCESSING_REQUIRED;
}

#define  try_return(X)  X; goto try_exit
NTSTATUS
FsTPMCreateFile (
			  IN PVCB Vcb,
			  IN ACCESS_MASK DesiredAccess,
			  IN POBJECT_ATTRIBUTES ObjectAttributes,
			  IN PLARGE_INTEGER AllocationSize OPTIONAL,
			  IN ULONG FileAttributes,
			  IN ULONG ShareAccess,
			  IN ULONG Disposition,
			  IN ULONG CreateOptions,
			  IN PVOID EaBuffer OPTIONAL,
			  IN ULONG EaLength,
			  IN ULONG Options,
			  OUT ULONG *Information,
			  OUT	PFILE_OBJECT FileObject,
			  OUT HANDLE *FileHandle OPTIONAL
			  )
{
	PIRP Irp = NULL;
	PFILE_OBJECT NewFileObject = NULL;
	PDEVICE_OBJECT RealDevice = Vcb->RealDevice;
	PDEVICE_OBJECT DeviceObject = Vcb->NextLowerDevice;
	//	PVPB Vpb;
	IO_SECURITY_CONTEXT SecurityContext;
	ACCESS_STATE AccessState;
	PIO_STACK_LOCATION NextIrpSp;
	IO_STATUS_BLOCK IoStatus;
	OBJECT_ATTRIBUTES ObjAttr;
	NTSTATUS Status;
	KEVENT Event;
	LARGE_INTEGER AllocSize;

	BOOLEAN CreatedAccessState =  FALSE;

	// <<<<<<<<<<<<<<<<<<<<<<<Notice>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	// I have no document to introduce AUXDATA
	// Smith, Joel said: Note the pAuxData variable.  
	//					 Obviously, a 1k nonpaged buffer is overkill, but I haven't 
	//					 yet bothered to try to figure out what SeCreateAccessState 
	//			     	 puts in here.
	//	 But I have seen another articles which said AUX_DATA just used to 
	// describe that the AUX device, you can see afximpl.h and 
	// http://www.sources.ru/cpp/mfc/t3552.htm .
	//
	ULONG *pAuxData=(ULONG*)ExAllocatePool(NonPagedPool, 1024); 
	memset(pAuxData, 0, 1024); 


	__try
	{
		//
		// Build AccessState for this create request.
		//

		Status =  SeCreateAccessState( &AccessState,pAuxData,DesiredAccess,IoGetFileObjectGenericMapping() );

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

		CreatedAccessState =  TRUE;

		//
		// Initialize event on which we will occasionaly wait.
		//

		KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

		//
		// Allocate an IRP with appropriate number of stack locations.
		//

		Irp =  IoAllocateIrp(DeviceObject->StackSize, FALSE);

		if (!Irp)
		{
			try_return(Status =  STATUS_INSUFFICIENT_RESOURCES);
		}

		//
		// Fill in basic Irp fields like a Thread, RequestorMode and Flags.
		//

		Irp->Tail.Overlay.Thread =  PsGetCurrentThread();
		Irp->RequestorMode =  KernelMode;
		SetFlag(Irp->Flags, IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API);

		//
		// Fill in the SecurityContext for this create request.
		//

		SecurityContext.SecurityQos = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
		SecurityContext.AccessState =  &AccessState;
		SecurityContext.DesiredAccess =  DesiredAccess;
		SecurityContext.FullCreateOptions =  CreateOptions;

		//
		// Fill in basic fields in the next stack location.
		//

		NextIrpSp =  IoGetNextIrpStackLocation(Irp);

		NextIrpSp->Control =  0;
		NextIrpSp->MajorFunction =  IRP_MJ_CREATE;
		NextIrpSp->Flags =  (UCHAR)Options;

		if (!FlagOn(ObjectAttributes->Attributes, OBJ_CASE_INSENSITIVE))
		{
			SetFlag(NextIrpSp->Flags, SL_CASE_SENSITIVE);
		}

		//
		// Fill in the AllocationSize and EaBuffer.
		//

		AllocSize.QuadPart =  AllocationSize ? AllocationSize->QuadPart : 0;

		Irp->Overlay.AllocationSize.QuadPart =  AllocSize.QuadPart;
		Irp->AssociatedIrp.SystemBuffer =  EaBuffer;

		//
		// Fill in request parameters in next stack location.
		//

		NextIrpSp->Parameters.Create.Options =  (CreateOptions & 0xFFFFFF) | (Disposition << 24);
		NextIrpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
		NextIrpSp->Parameters.Create.ShareAccess =  (USHORT)ShareAccess;
		NextIrpSp->Parameters.Create.SecurityContext =  &SecurityContext;
		NextIrpSp->Parameters.Create.EaLength =  EaLength;

		//
		// Fill in other fields in Irp.
		//

		Irp->UserIosb =  &IoStatus;
		Irp->UserEvent =  &Event;

		Irp->MdlAddress =  NULL;
		Irp->PendingReturned =  FALSE;
		Irp->Cancel =  FALSE;
		Irp->CancelRoutine =  NULL;
		Irp->Tail.Overlay.AuxiliaryBuffer =  NULL;

		//
		// Create new file object.
		//

		InitializeObjectAttributes(&ObjAttr, NULL,ObjectAttributes->Attributes, 0, NULL);

		Status =  ObCreateObject( KernelMode, *IoFileObjectType,&ObjAttr,KernelMode,0,sizeof(FILE_OBJECT),0,0,(void**)&NewFileObject );

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

		//
		// Zero the file object and initialize type and size.
		//
		RtlZeroMemory(NewFileObject, sizeof(FILE_OBJECT));

		NewFileObject->Type =  IO_TYPE_FILE;
		NewFileObject->Size =  sizeof(FILE_OBJECT);

		//
		// Fill in the RelatedFileObject as a RootDirectory.
		//

		NewFileObject->RelatedFileObject = (PFILE_OBJECT)ObjectAttributes->RootDirectory;

		//
		// Initialize some more things when the file is for synchronous access.
		//

		if (FlagOn(CreateOptions, FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
		{
			SetFlag(NewFileObject->Flags, FO_SYNCHRONOUS_IO);

			if (FlagOn(CreateOptions, FILE_SYNCHRONOUS_IO_ALERT))
			{
				SetFlag(NewFileObject->Flags, FO_ALERTABLE_IO);
			}

			KeInitializeEvent(&NewFileObject->Lock, SynchronizationEvent, FALSE);

			NewFileObject->Waiters =  0;
			NewFileObject->CurrentByteOffset.QuadPart =  0;
		}

		//
		// Set some file object flags with respect to CreateOptions.
		//


		if (FlagOn(CreateOptions, FILE_NO_INTERMEDIATE_BUFFERING))
		{
			SetFlag(NewFileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING);
		}

		if (FlagOn(CreateOptions, FILE_WRITE_THROUGH))
		{	
			SetFlag(NewFileObject->Flags, FO_WRITE_THROUGH);
		}

		if (FlagOn(CreateOptions, FILE_SEQUENTIAL_ONLY))
		{
			SetFlag(NewFileObject->Flags, FO_SEQUENTIAL_ONLY);
		}

		if (!FlagOn(ObjectAttributes->Attributes, OBJ_CASE_INSENSITIVE))
		{
			SetFlag(NewFileObject->Flags, FO_OPENED_CASE_SENSITIVE);
		}

		//
		// Initialize the DeviceObject field in file object.
		//

		NewFileObject->DeviceObject =  RealDevice;

		//
		// If the caller requests no handle we must insert the
		// file object at this time.
		//

		if (FileHandle ==  NULL)
		{
			HANDLE Handle;

			//
			// Insert the file object to the Object Manager
			// requesting one additional reference.
			//

			Status =  ObInsertObject( NewFileObject,NULL,DesiredAccess,1,(PVOID*)&NewFileObject,&Handle );

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

			//
			// Close the handle (one reference remains).
			//

			Status =  NtClose(Handle);
			ASSERT(NT_SUCCESS(Status));

			ClearFlag(NewFileObject->Flags, FO_HANDLE_CREATED);
		}

		//
		// Associate the NewFileObject with the Irp
		//

		Irp->Tail.Overlay.OriginalFileObject =  NewFileObject;
		NextIrpSp->FileObject =  NewFileObject;

		//
		// If the ObjectAttributes contains some name we must
		// make a copy for the file object.
		//

		if (ObjectAttributes->ObjectName->Length)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -