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

📄 irpfile.c

📁 Shadow SDT的应用
💻 C
📖 第 1 页 / 共 3 页
字号:

   //分配一个IRP
   Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
   if(Irp == NULL) 
   	  return STATUS_INSUFFICIENT_RESOURCES;

   KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );

   RtlZeroMemory(FileInformation, Length);

   Irp->UserEvent = &kEvent;
   Irp->UserIosb = IoStatusBlock;      //输出参数
   Irp->UserBuffer = FileInformation;  //I/O缓冲区的用户空间地址
   Irp->Tail.Overlay.Thread = PsGetCurrentThread();  //获取当前线程
   Irp->Tail.Overlay.OriginalFileObject = FileObject;
   Irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;

   IrpSp = IoGetNextIrpStackLocation(Irp);
   IrpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
   IrpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
   IrpSp->FileObject = FileObject;
   IrpSp->Flags = SL_RESTART_SCAN;
   IrpSp->Parameters.QueryDirectory.Length = Length;     //输入参数
   IrpSp->Parameters.QueryDirectory.FileName = FileName; //输入参数
   IrpSp->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;//输入参数

   IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);

   ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp); //IoCallDriver最好自己实现
   if (ntStatus == STATUS_PENDING)
      KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);

   return IoStatusBlock->Status;

}

/*
NTSTATUS
IrpDirectoryQuery(
	IN PFILE_OBJECT FileObject,
	IN FILE_INFORMATION_CLASS FileInformationClass,
	OUT PVOID Buffer,
	IN ULONG Length
	)
{
	NTSTATUS status;
	KEVENT event;
	PIRP irp;
	IO_STATUS_BLOCK ioStatus;
	PIO_STACK_LOCATION irpSp;
	PDEVICE_OBJECT deviceObject;
	PQUERY_DIRECTORY queryDirectory;

	if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
		return STATUS_UNSUCCESSFUL;

	deviceObject = FileObject->Vpb->DeviceObject;
	KeInitializeEvent(&event, SynchronizationEvent, FALSE);
	irp = IoAllocateIrp(deviceObject->StackSize, FALSE);

	if (irp == NULL)
		return STATUS_INSUFFICIENT_RESOURCES;

	irp->Flags = IRP_INPUT_OPERATION | IRP_BUFFERED_IO;
	irp->RequestorMode = KernelMode;
	irp->UserEvent = &event;
	irp->UserIosb = &ioStatus;
	irp->UserBuffer = Buffer;
	irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
	irp->Tail.Overlay.OriginalFileObject = FileObject;
	irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
  //irp->Pointer = FileObject;

	irpSp = IoGetNextIrpStackLocation(irp);
	irpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
	irpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
	irpSp->DeviceObject = deviceObject;
	irpSp->FileObject = FileObject;

	queryDirectory = (PQUERY_DIRECTORY)&irpSp->Parameters; //PQUERY_DIRECTORY
	queryDirectory->Length = Length; //ULONG Length
	queryDirectory->FileName = NULL; //PUNICODE_STRING FileName;
	queryDirectory->FileInformationClass = FileInformationClass; //FILE_INFORMATION_CLASS FileInformationClass;
	queryDirectory->FileIndex = 0;   //ULONG

	IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
	status = IoCallDriver(deviceObject, irp);

	if (status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
		status = ioStatus.Status;
	}

	return status;
}
*/

//IRP_MJ_QUERY_INFORMATION
//NtQueryInformationFile
//取得文件信息
NTSTATUS 
IrpQueryInformationFile(
   IN PFILE_OBJECT  FileObject,
   OUT PIO_STATUS_BLOCK  IoStatusBlock,
   OUT PVOID  FileInformation,
   IN ULONG  Length,
   IN FILE_INFORMATION_CLASS  FileInformationClass )
{
   NTSTATUS ntStatus;
   PIRP Irp;
   KEVENT kEvent;
   PIO_STACK_LOCATION IrpSp;

   if ( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
      return STATUS_UNSUCCESSFUL;

   Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
   if( Irp == NULL ) 
   	  return STATUS_INSUFFICIENT_RESOURCES;

   KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );
   RtlZeroMemory( FileInformation, Length );
   
   Irp->AssociatedIrp.SystemBuffer = FileInformation; //输出参数
   Irp->UserEvent = &kEvent;
   Irp->UserIosb = IoStatusBlock;
   Irp->RequestorMode = KernelMode;
   Irp->Tail.Overlay.Thread = PsGetCurrentThread();
   Irp->Tail.Overlay.OriginalFileObject = FileObject;

   IrpSp = IoGetNextIrpStackLocation(Irp);
   IrpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
   IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
   IrpSp->FileObject = FileObject;
   IrpSp->Parameters.QueryFile.Length = Length;   //输入参数
   IrpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;  //输入参数

   IoSetCompletionRoutine( Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE );

   ntStatus = IoCallDriver( FileObject->Vpb->DeviceObject, Irp );
   if ( ntStatus == STATUS_PENDING )
      KeWaitForSingleObject( &kEvent, Executive, KernelMode, TRUE, 0 );

   return IoStatusBlock->Status;
}


NTSTATUS
IRPQueryInformationFile(
   IN PFILE_OBJECT FileObject,
	 OUT PVOID FileInformation,
	 IN ULONG Length,
	 IN FILE_INFORMATION_CLASS FileInformationClass)
{
	 NTSTATUS status;
	 KEVENT event;
	 PIRP irp;
	 IO_STATUS_BLOCK ioStatus;
	 PIO_STACK_LOCATION irpSp;
	 PDEVICE_OBJECT deviceObject;

	 if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
	 	  return STATUS_UNSUCCESSFUL;

	 deviceObject = FileObject->Vpb->DeviceObject;
	 KeInitializeEvent(&event, SynchronizationEvent, FALSE);
	 irp = IoAllocateIrp(deviceObject->StackSize, FALSE);

	 if (irp == NULL)
		  return STATUS_INSUFFICIENT_RESOURCES;

	 irp->Flags = IRP_BUFFERED_IO;
	 irp->AssociatedIrp.SystemBuffer = FileInformation;
	 irp->RequestorMode = KernelMode;
	 irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
	 irp->UserEvent = &event;
	 irp->UserIosb = &ioStatus;
	 irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
	 irp->Tail.Overlay.OriginalFileObject = FileObject;

	 irpSp = IoGetNextIrpStackLocation(irp);
 	 irpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
	 irpSp->DeviceObject = deviceObject;
	 irpSp->FileObject = FileObject;
	 irpSp->Parameters.QueryFile.Length = Length;
	 irpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;

	 IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
	 status = IoCallDriver(deviceObject, irp);

	 if (status == STATUS_PENDING)
		 KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);

	 return ioStatus.Status;
}
 
 
//IRP_MJ_SET_INFORMATION
//NtSetInformationFile
//设置文件信息:删除,改名,改属性
NTSTATUS
IrpSetInformationFile(
   IN PFILE_OBJECT  FileObject,
   OUT PIO_STATUS_BLOCK  IoStatusBlock,
   IN PVOID  FileInformation,
   IN ULONG  Length,
   IN FILE_INFORMATION_CLASS  FileInformationClass,
   IN BOOLEAN  ReplaceIfExists)

{
   NTSTATUS ntStatus;
   PIRP Irp;
   KEVENT kEvent;
   PIO_STACK_LOCATION IrpSp;

   if ( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
     return STATUS_UNSUCCESSFUL;

   Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
   if( Irp == NULL ) 
      return STATUS_INSUFFICIENT_RESOURCES;

   KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );

   Irp->AssociatedIrp.SystemBuffer = FileInformation; 
   Irp->UserEvent = &kEvent;
   Irp->UserIosb = IoStatusBlock;  
   Irp->RequestorMode = KernelMode;
   Irp->Tail.Overlay.Thread = PsGetCurrentThread();
   Irp->Tail.Overlay.OriginalFileObject = FileObject; 

   IrpSp = IoGetNextIrpStackLocation(Irp);
   IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
   IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
   IrpSp->FileObject = FileObject;
   IrpSp->Parameters.SetFile.ReplaceIfExists = ReplaceIfExists; 
   IrpSp->Parameters.SetFile.FileObject = FileObject;
   IrpSp->Parameters.SetFile.AdvanceOnly = FALSE; 
   IrpSp->Parameters.SetFile.Length = Length;      
   IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass; 

   IoSetCompletionRoutine( Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE );

   ntStatus = IoCallDriver( FileObject->Vpb->DeviceObject, Irp );
   if (ntStatus == STATUS_PENDING)
      KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);

   return IoStatusBlock->Status;
}

 
//IRP_MJ_READ
//NtReadFile
//读文件
NTSTATUS IrpReadFile(
   IN PFILE_OBJECT  FileObject,
   OUT PIO_STATUS_BLOCK  IoStatusBlock,
   OUT PVOID  Buffer,
   IN ULONG  Length,
   IN PLARGE_INTEGER  ByteOffset  OPTIONAL)
{
   NTSTATUS ntStatus;
   PIRP Irp;
   KEVENT kEvent;
   PIO_STACK_LOCATION IrpSp;

   if( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
      return STATUS_UNSUCCESSFUL;

   if( ByteOffset == NULL )
   {
      if( !(FileObject->Flags & FO_SYNCHRONOUS_IO) )
         return STATUS_INVALID_PARAMETER;

      ByteOffset = &FileObject->CurrentByteOffset;
   }

   Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
   if( Irp == NULL ) 
      return STATUS_INSUFFICIENT_RESOURCES;

   RtlZeroMemory( Buffer, Length );

   //FileObject->DeviceObject->Flags指定这个设备的缓冲区策略DO_BUFFER_IO、DO_DIRECT_IO
   if( FileObject->DeviceObject->Flags & DO_BUFFERED_IO )
   {
   	  //如果驱动程序执行缓冲I/O,指向系统空间缓冲区的指针
      Irp->AssociatedIrp.SystemBuffer = Buffer;
   }
   else if( FileObject->DeviceObject->Flags & DO_DIRECT_IO )
   {
      //如果设备执行直接I/O,指向用户空间缓冲区的内存描述符列表的指针
      Irp->MdlAddress = IoAllocateMdl( Buffer, Length, 0, 0, 0 );
      if ( Irp->MdlAddress == NULL )
      {
         IoFreeIrp(Irp);
         return STATUS_INSUFFICIENT_RESOURCES;
      }
      MmBuildMdlForNonPagedPool( Irp->MdlAddress );
   }
   else
   {
      Irp->UserBuffer = Buffer;
   }

   KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );

   Irp->UserEvent = &kEvent;
   Irp->UserIosb = IoStatusBlock;
   Irp->RequestorMode = KernelMode;
   Irp->Flags = IRP_READ_OPERATION;
   Irp->Tail.Overlay.Thread = PsGetCurrentThread();
   Irp->Tail.Overlay.OriginalFileObject = FileObject; //输入的文件对象

   IrpSp = IoGetNextIrpStackLocation(Irp);
   IrpSp->MajorFunction = IRP_MJ_READ;
   IrpSp->MinorFunction = IRP_MN_NORMAL;
   IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
   IrpSp->FileObject = FileObject;
   IrpSp->Parameters.Read.Length = Length;
   IrpSp->Parameters.Read.ByteOffset = *ByteOffset;

   //接着要考虑如果IRP不能及时完成,会异步的返回的情况,我们安装一个CompletionRoutine,
   //在CompletionRoutine里面设置一个事件为已激活,
   //通知我们的主线程读取或者写入操作已经完成。
   IoSetCompletionRoutine( Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE );

   ntStatus = IoCallDriver( FileObject->Vpb->DeviceObject, Irp );
   if ( ntStatus == STATUS_PENDING )
      KeWaitForSingleObject( &kEvent, Executive, KernelMode, TRUE, 0 );

   return IoStatusBlock->Status;
}


NTSTATUS
IRPReadFile(
	IN PFILE_OBJECT FileObject,
	IN PLARGE_INTEGER ByteOffset OPTIONAL,
	IN ULONG Length,
	OUT PVOID Buffer,
	OUT PIO_STATUS_BLOCK IoStatusBlock
	)
{
	NTSTATUS status;
	KEVENT event;
	PIRP irp;
	PIO_STACK_LOCATION irpSp;
	PDEVICE_OBJECT deviceObject;

	if (ByteOffset == NULL)
	{
		if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
			return STATUS_INVALID_PARAMETER;

		ByteOffset = &FileObject->CurrentByteOffset;
	}

	if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
		return STATUS_UNSUCCESSFUL;

	deviceObject = FileObject->Vpb->DeviceObject;
	irp = IoAllocateIrp(deviceObject->StackSize, FALSE);

	if (irp == NULL)
		return STATUS_INSUFFICIENT_RESOURCES;

	irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL);

	if (irp->MdlAddress == NULL)
	{
		IoFreeIrp(irp);
		return STATUS_INSUFFICIENT_RESOURCES;;
	}

	MmBuildMdlForNonPagedPool(irp->MdlAddress);

	irp->Flags = IRP_READ_OPERATION;
	irp->RequestorMode = KernelMode;
	irp->UserIosb = IoStatusBlock;
	irp->UserEvent = &event;
	irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
	irp->Tail.Overlay.OriginalFileObject = FileObject;

	irpSp = IoGetNextIrpStackLocation(irp);
	irpSp->MajorFunction = IRP_MJ_READ;
	irpSp->MinorFunction = IRP_MN_NORMAL;
	irpSp->DeviceObject = deviceObject;
	irpSp->FileObject = FileObject;
	irpSp->Parameters.Read.Length = Length;
	irpSp->Parameters.Read.ByteOffset = *ByteOffset;

	KeInitializeEvent(&event, SynchronizationEvent, FALSE);
	IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
	status = IoCallDriver(deviceObject, irp);

	if (status == STATUS_PENDING)
		status = KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);

	return status;
}

 
//IRP_MJ_WRITE
//NtWriteFile
//写文件
NTSTATUS 
IrpWriteFile(
   IN PFILE_OBJECT  FileObject,
   OUT PIO_STATUS_BLOCK  IoStatusBlock,
   IN PVOID  Buffer,
   IN ULONG  Length,
   IN PLARGE_INTEGER  ByteOffset  OPTIONAL)
{
   NTSTATUS ntStatus;
   PIRP Irp;
   KEVENT kEvent;
   PIO_STACK_LOCATION IrpSp;

   if ( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
       return STATUS_UNSUCCESSFUL;

   if ( ByteOffset == NULL )
   {
      if ( !(FileObject->Flags & FO_SYNCHRONOUS_IO) )
         return STATUS_INVALID_PARAMETER;
      ByteOffset = &FileObject->CurrentByteOffset;
   }

   Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
   if ( Irp == NULL ) 
   	  return STATUS_INSUFFICIENT_RESOURCES;

   if( FileObject->DeviceObject->Flags & DO_BUFFERED_IO )
   {
      Irp->AssociatedIrp.SystemBuffer = Buffer;
   }
   else
   {
      Irp->MdlAddress = IoAllocateMdl( Buffer, Length, 0, 0, 0 );
      if (Irp->MdlAddress == NULL)
      {
         IoFreeIrp(Irp);
         return STATUS_INSUFFICIENT_RESOURCES;
      }
      MmBuildMdlForNonPagedPool( Irp->MdlAddress );
   }

   KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );

   Irp->UserEvent = &kEvent;
   Irp->UserIosb = IoStatusBlock;
   Irp->RequestorMode = KernelMode;
   Irp->Flags = IRP_WRITE_OPERATION;
   Irp->Tail.Overlay.Thread = PsGetCurrentThread();
   Irp->Tail.Overlay.OriginalFileObject = FileObject;

   IrpSp = IoGetNextIrpStackLocation(Irp);
   IrpSp->MajorFunction = IRP_MJ_WRITE;
   IrpSp->MinorFunction = IRP_MN_NORMAL;
   IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
   IrpSp->FileObject = FileObject;
   IrpSp->Parameters.Write.Length = Length;
   IrpSp->Parameters.Write.ByteOffset = *ByteOffset;

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

   ntStatus = IoCallDriver( FileObject->Vpb->DeviceObject, Irp );
   if ( ntStatus == STATUS_PENDING )
      KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, NULL);

   return IoStatusBlock->Status;
}


NTSTATUS
IRPWriteFile(
   IN PFILE_OBJECT FileObject,
	 IN PLARGE_INTEGER ByteOffset OPTIONAL,
	 IN ULONG Length,
	 IN PVOID Buffer,
	 OUT PIO_STATUS_BLOCK IoStatusBlock )
{
	 NTSTATUS status;
	 KEVENT event;
	 PIRP Irp;
	 PIO_STACK_LOCATION IrpSp;
	 PDEVICE_OBJECT deviceObject;

	 if (ByteOffset == NULL)
	 {
		  if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
			  return STATUS_INVALID_PARAMETER;

		  ByteOffset = &FileObject->CurrentByteOffset;
	 }

	 if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
		  return STATUS_UNSUCCESSFUL;

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

	 if (Irp == NULL)
		  return STATUS_INSUFFICIENT_RESOURCES;

	 Irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL);

	 if (Irp->MdlAddress == NULL)
	 {
		  IoFreeIrp(Irp);
		  return STATUS_INSUFFICIENT_RESOURCES;;
	 }

	 MmBuildMdlForNonPagedPool(Irp->MdlAddress);

	 Irp->Flags = IRP_WRITE_OPERATION;
	 Irp->RequestorMode = KernelMode;
	 Irp->UserIosb = IoStatusBlock;
	 Irp->UserEvent = &event;
	 Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
	 Irp->Tail.Overlay.OriginalFileObject = FileObject;

	 IrpSp = IoGetNextIrpStackLocation(Irp);

⌨️ 快捷键说明

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