IRP 乱杂谈

避坑指南:OpenWebUI+SearXNG联网搜索的5个常见配置错误及解决方法 本文详细解析了OpenWebUI与SearXNG整合过程中常见的5个配置错误及解决方案,包括JSON格式配置陷阱、国内搜索引擎缺失、连续搜索失效等问题。通过实战验证的优化策略,帮助开发者避免性能下降和功能异常,提升大模型与搜索引擎的协同效率。 阅读详情

IRP 乱杂谈

作者: JIURL

                主页: http://jiurl.yeah.net

   


IRP 是 I/O request packet 的缩写,即 I/O 请求包。驱动与驱动之间通过 IRP 进行通信。而使用驱动的应用层调用的 CreatFile,ReadFile,WriteFile,DeviceIoControl 等函数,说到底也是使用 IRP 和驱动进行通信。

一个 IRP 由两部分组成。首先是头部或者叫包的固定部分,是一个 IRP 结构。紧跟在这个头部之后的是 I/O stack locations ,这是一个 IO_STACK_LOCATION 结构的数组,这个数组中元素的个数是根据情况而定的,由 IoAllocateIrp( IN CCHAR StackSize , IN BOOLEAN ChargeQuota ) 时的参数 StackSize 决定。而 StackSize 通常由 IRP 发往的目标 DEVICE_OBJECT 的 +30 char StackSize 决定。而这个 StackSize 是由设备对象连入所在的设备栈时,根据在设备栈中位置决定的。我们先看看 IRP 结构和 IO_STACK_LOCATION 结构的定义。

IRP 结构定义如下

struct _IRP (sizeof=112)
+00 int16 Type
+02 uint16 Size
+04 struct _MDL *MdlAddress
+08 uint32 Flags
+0c union __unnamed14 AssociatedIrp
+0c struct _IRP *MasterIrp
+0c int32 IrpCount
+0c void *SystemBuffer
+10 struct _LIST_ENTRY ThreadListEntry
+10 struct _LIST_ENTRY *Flink
+14 struct _LIST_ENTRY *Blink
+18 struct _IO_STATUS_BLOCK IoStatus
+18 int32 Status
+18 void *Pointer
+1c uint32 Information
+20 char RequestorMode
+21 byte PendingReturned
+22 char StackCount
+23 char CurrentLocation
+24 byte Cancel
+25 byte CancelIrql
+26 char ApcEnvironment
+27 byte AllocationFlags
+28 struct _IO_STATUS_BLOCK *UserIosb
+2c struct _KEVENT *UserEvent
+30 union __unnamed15 Overlay
+30 struct __unnamed16 AsynchronousParameters
+30 function *UserApcRoutine
+34 void *UserApcContext
+30 union _LARGE_INTEGER AllocationSize
+30 uint32 LowPart
+34 int32 HighPart
+30 struct __unnamed3 u
+30 uint32 LowPart
+34 int32 HighPart
+30 int64 QuadPart
+38 function *CancelRoutine
+3c void *UserBuffer
+40 union __unnamed17 Tail
+40 struct __unnamed18 Overlay
+40 struct _KDEVICE_QUEUE_ENTRY DeviceQueueEntry
+40 struct _LIST_ENTRY DeviceListEntry
+40 struct _LIST_ENTRY *Flink
+44 struct _LIST_ENTRY *Blink
+48 uint32 SortKey
+4c byte Inserted
+40 void *DriverContext[4]
+50 struct _ETHREAD *Thread
+54 char *AuxiliaryBuffer
+58 struct _LIST_ENTRY ListEntry
+58 struct _LIST_ENTRY *Flink
+5c struct _LIST_ENTRY *Blink
+60 struct _IO_STACK_LOCATION *CurrentStackLocation
+60 uint32 PacketType
+64 struct _FILE_OBJECT *OriginalFileObject
+40 struct _KAPC Apc
+40 int16 Type
+42 int16 Size
+44 uint32 Spare0
+48 struct _KTHREAD *Thread
+4c struct _LIST_ENTRY ApcListEntry
+4c struct _LIST_ENTRY *Flink
+50 struct _LIST_ENTRY *Blink
+54 function *KernelRoutine
+58 function *RundownRoutine
+5c function *NormalRoutine
+60 void *NormalContext
+64 void *SystemArgument1
+68 void *SystemArgument2
+6c char ApcStateIndex
+6d char ApcMode
+6e byte Inserted
+40 void *CompletionKey

IO_STACK_LOCATION 结构定义如下

struct _IO_STACK_LOCATION (sizeof=36)
+00 byte MajorFunction
+01 byte MinorFunction
+02 byte Flags
+03 byte Control
+04 union __unnamed19 Parameters
+04 struct __unnamed20 Create
+04 struct _IO_SECURITY_CONTEXT *SecurityContext
+08 uint32 Options
+0c uint16 FileAttributes
+0e uint16 ShareAccess
+10 uint32 EaLength
+04 struct __unnamed21 CreatePipe
+04 struct _IO_SECURITY_CONTEXT *SecurityContext
+08 uint32 Options
+0c uint16 Reserved
+0e uint16 ShareAccess
+10 struct _NAMED_PIPE_CREATE_PARAMETERS *Parameters
+04 struct __unnamed22 CreateMailslot
+04 struct _IO_SECURITY_CONTEXT *SecurityContext
+08 uint32 Options
+0c uint16 Reserved
+0e uint16 ShareAccess
+10 struct _MAILSLOT_CREATE_PARAMETERS *Parameters
+04 struct __unnamed23 Read
+04 uint32 Length
+08 uint32 Key
+0c union _LARGE_INTEGER ByteOffset
+0c uint32 LowPart
+10 int32 HighPart
+0c struct __unnamed3 u
+0c uint32 LowPart
+10 int32 HighPart
+0c int64 QuadPart
+04 struct __unnamed23 Write
+04 uint32 Length
+08 uint32 Key
+0c union _LARGE_INTEGER ByteOffset
+0c uint32 LowPart
+10 int32 HighPart
+0c struct __unnamed3 u
+0c uint32 LowPart
+10 int32 HighPart
+0c int64 QuadPart
+04 struct __unnamed24 QueryDirectory
+04 uint32 Length
+08 struct _STRING *FileName
+0c int32 FileInformationClass
+10 uint32 FileIndex
+04 struct __unnamed25 NotifyDirectory
+04 uint32 Length
+08 uint32 CompletionFilter
+04 struct __unnamed26 QueryFile
+04 uint32 Length
+08 int32 FileInformationClass
+04 struct __unnamed27 SetFile
+04 uint32 Length
+08 int32 FileInformationClass
+0c struct _FILE_OBJECT *FileObject
+10 byte ReplaceIfExists
+11 byte AdvanceOnly
+10 uint32 ClusterCount
+10 void *DeleteHandle
+04 struct __unnamed28 QueryEa
+04 uint32 Length
+08 void *EaList
+0c uint32 EaListLength
+10 uint32 EaIndex
+04 struct __unnamed29 SetEa
+04 uint32 Length
+04 struct __unnamed30 QueryVolume
+04 uint32 Length
+08 int32 FsInformationClass
+04 struct __unnamed30 SetVolume
+04 uint32 Length
+08 int32 FsInformationClass
+04 struct __unnamed31 FileSystemControl
+04 uint32 OutputBufferLength
+08 uint32 InputBufferLength
+0c uint32 FsControlCode
+10 void *Type3InputBuffer
+04 struct __unnamed32 LockControl
+04 union _LARGE_INTEGER *Length
+08 uint32 Key
+0c union _LARGE_INTEGER ByteOffset
+0c uint32 LowPart
+10 int32 HighPart
+0c struct __unnamed3 u
+0c uint32 LowPart
+10 int32 HighPart
+0c int64 QuadPart
+04 struct __unnamed33 DeviceIoControl
+04 uint32 OutputBufferLength
+08 uint32 InputBufferLength
+0c uint32 IoControlCode
+10 void *Type3InputBuffer
+04 struct __unnamed34 QuerySecurity
+04 uint32 SecurityInformation
+08 uint32 Length
+04 struct __unnamed35 SetSecurity
+04 uint32 SecurityInformation
+08 void *SecurityDescriptor
+04 struct __unnamed36 MountVolume
+04 struct _VPB *Vpb
+08 struct _DEVICE_OBJECT *DeviceObject
+04 struct __unnamed36 VerifyVolume
+04 struct _VPB *Vpb
+08 struct _DEVICE_OBJECT *DeviceObject
+04 struct __unnamed37 Scsi
+04 *Srb
+04 struct __unnamed38 QueryQuota
+04 uint32 Length
+08 void *StartSid
+0c struct _FILE_GET_QUOTA_INFORMATION *SidList
+10 uint32 SidListLength
+04 struct __unnamed29 SetQuota
+04 uint32 Length
+04 struct __unnamed39 QueryDeviceRelations
+04 int32 Type
+04 struct __unnamed40 QueryInterface
+04 struct _GUID *InterfaceType
+08 uint16 Size
+0a uint16 Version
+0c struct _INTERFACE *Interface
+10 void *InterfaceSpecificData
+04 struct __unnamed41 DeviceCapabilities
+04 struct _DEVICE_CAPABILITIES *Capabilities
+04 struct __unnamed42 FilterResourceRequirements
+04 struct _IO_RESOURCE_REQUIREMENTS_LIST *IoResourceRequirementList
+04 struct __unnamed51 ReadWriteConfig
+04 uint32 WhichSpace
+08 void *Buffer
+0c uint32 Offset
+10 uint32 Length
+04 struct __unnamed52 SetLock
+04 byte Lock
+04 struct __unnamed53 QueryId
+04 int32 IdType
+04 struct __unnamed54 QueryDeviceText
+04 int32 DeviceTextType
+08 uint32 LocaleId
+04 struct __unnamed55 UsageNotification
+04 byte InPath
+05 byte Reserved[3]
+08 int32 Type
+04 struct __unnamed56 WaitWake
+04 int32 PowerState
+04 struct __unnamed57 PowerSequence
+04 struct _POWER_SEQUENCE *PowerSequence
+04 struct __unnamed58 Power
+04 uint32 SystemContext
+08 int32 Type
+0c union _POWER_STATE State
+0c int32 SystemState
+0c int32 DeviceState
+10 int32 ShutdownType
+04 struct __unnamed59 StartDevice
+04 struct _CM_RESOURCE_LIST *AllocatedResources
+08 struct _CM_RESOURCE_LIST *AllocatedResourcesTranslated
+04 struct __unnamed60 WMI
+04 uint32 ProviderId
+08 void *DataPath
+0c uint32 BufferSize
+10 void *Buffer
+04 struct __unnamed61 Others
+04 void *Argument1
+08 void *Argument2
+0c void *Argument3
+10 void *Argument4
+14 struct _DEVICE_OBJECT *DeviceObject
+18 struct _FILE_OBJECT *FileObject
+1c function *CompletionRoutine
+20 void *Context

IO_STACK_LOCATION 结构的大小是固定的,+04 到 +14 之间的16个字节是个公用体。

我们大略的看一个例子,或许能让你对 IO_STACK_LOCATION 有点概念

一个驱动程序的应用层程序,调用 DeviceIoControl ,让驱动程序完成一个任务。DeviceIoControl 中会申请一个Irp,初始化它,然后用这个 Irp,调用 IoCallDriver 发往设备栈的最高层。

IoCallDriver 会根据Irp中的当前 IO_STACK_LOCATION 中的 +00 byte MajorFunction,调用发往设备对象所属驱动中的相应函数。

我们看看被传入到设备栈最高层的 irp,

kd> !irp fe403968
Irp is active with 6 stacks 6 is current (= 0xfe403a8c)
No Mdl System buffer = fe3d6068 Thread fe427960: Irp stack trace. 
cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
>[ e, 0] 0 0 fe4f5df0 fe426688 00000000-00000000 
/Driver/Kbdclass
Args: 00000000 00000004 000b0008 00000000

WinDbg 的 !irp 命令,会显示一个 Irp 的 IO_STACK_LOCATION 数组的一些格式化信息

可以看到传入的这个 Irp,它的最后一个 IO_STACK_LOCATION 是当前的 IO_STACK_LOCATION,里面有传入的一些参数。

>[ e, 0] 0 0 fe4f5df0 fe426688 00000000-00000000 
/Driver/Kbdclass
Args: 00000000 00000004 000b0008 00000000

kd> !strct io_stack_location fe403a8c
struct _IO_STACK_LOCATION (sizeof=36)
+00 byte MajorFunction = 0e .
+01 byte MinorFunction = 00 .
+02 byte Flags = 00 .
+03 byte Control = 00 .
+04 union __unnamed19 Parameters
+04 struct __unnamed33 DeviceIoControl
+04 uint32 OutputBufferLength = 00000000
+08 uint32 InputBufferLength = 00000004
+0c uint32 IoControlCode = 000b0008
+10 void *Type3InputBuffer = 00000000
+14 struct _DEVICE_OBJECT *DeviceObject = FE4F5DF0
+18 struct _FILE_OBJECT *FileObject = FE426688
+1c function *CompletionRoutine = 00000000
+20 void *Context = 00000000

这些就是当前 IO_STACK_LOCATION,里面有参数什么的,这样本层驱动就可以根据 IRP 和当前的 IO_STACK_LOCATION 中的内容,知道该干些什么。本例中,本层驱动根据这个 Irp 做了些处理,发现还需要下层驱动做更多处理,就设置了下一层驱动要使用的 IO_STACK_LOCATION ,然后调用 IoCallDriver ,把这个 Irp 发到了下一层。

在下一层的处理程序中,我们看看收到的 Irp

kd> !irp fe403968
Irp is active with 6 stacks 5 is current (= 0xfe403a68)
No Mdl System buffer = fe3d6068 Thread fe427960: Irp stack trace. 
cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000 

Args: 00000000 00000000 00000000 00000000
>[ f, 0] 0 0 fe4f5020 fe426688 00000000-00000000 
/Driver/i8042prt
Args: 00000000 00000004 000b0008 00000000
[ e, 0] 0 0 fe4f5df0 fe426688 00000000-00000000 
/Driver/Kbdclass
Args: 00000000 00000004 000b0008 00000000

我们看到了 Irp 的当前 IO_STACK_LOCATION 变成了倒数第二个 IO_STACK_LOCATION ,里面是上一层驱动中设置的参数,告诉这一层驱动要干什么。本例中,本层驱动读写端口,操作硬件,完成了相应的功能。

IoCallDriver

首先我们看看对了解 IRP 最重要的一个函数,也是使用 IRP 进行驱动间通信所使用的函数,IoCallDriver。这个函数并不大,也不复杂,我们将详细的看看它的汇编代码。

NTSTATUS 
IoCallDriver(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
);
Irp 是发往设备对象的。参数 DeviceObject 指明设备目标设备对象。

nt!IoCallDriver:
80421417 8b542408 mov edx,[esp+0x8]
/* [esp+0x8] 为 IN OUT PIRP Irp */
8042141b 8b4c2404 mov ecx,[esp+0x4]
/* [esp+0x4] 为 IN PDEVICE_OBJECT DeviceObject */
8042141f e82ae1ffff call nt!IofCallDriver (8041f54e)
80421424 c20800 ret 0x8

nt!IofCallDriver:
8041f54e ff25d01a4780 jmp dword ptr [nt!pIofCallDriver (80471ad0)]

nt!IopfCallDriver:
8041f516 56 push esi
8041f517 8bf2 mov esi,edx
/* edx 为 IN OUT PIRP Irp */
8041f519 57 push edi
8041f51a 8bf9 mov edi,ecx
/* ecx 为 IN PDEVICE_OBJECT DeviceObject */
8041f51c fe4e23 dec byte ptr [esi+0x23]
/* esi 为 IN OUT PIRP Irp */
/* struct _IRP (sizeof=112) */
/* +23 char CurrentLocation */
8041f51f 8a4623 mov al,[esi+0x23]
8041f522 33c9 xor ecx,ecx
8041f524 3ac1 cmp al,cl
8041f526 7f0b jg nt!IopfCallDriver+0x1d (8041f533)
/* 如果 Irp->CurrentLocation 大于0,就跳 */
8041f528 51 push ecx
8041f529 51 push ecx
8041f52a 51 push ecx
8041f52b 56 push esi
8041f52c 6a35 push 0x35
8041f52e e8e1c90000 call nt!KeBugCheckEx (8042bf14)
8041f533 8b4660 mov eax,[esi+0x60]
/* esi 为 IN OUT PIRP Irp */
/* struct _IRP (sizeof=112) */
/* +60 struct _IO_STACK_LOCATION *CurrentStackLocation */
8041f536 56 push esi
/* esi 为 IN OUT PIRP Irp */
8041f537 83e824 sub eax,0x24
/* eax 为 Irp->CurrentStackLocation */
/* 0x24 为 sizeof(IO_STACK_LOCATION) */
8041f53a 57 push edi
/* edi 为 IN PDEVICE_OBJECT DeviceObject */
8041f53b 894660 mov [esi+0x60],eax
/* [esi+0x60] 为 Irp->CurrentStackLocation */
8041f53e 897814 mov [eax+0x14],edi
/* eax 为新的当前 IO_STACK_LOCATION */
/* struct _IO_STACK_LOCATION (sizeof=36) */
/* +14 struct _DEVICE_OBJECT *DeviceObject */
/* edi 为 IN PDEVICE_OBJECT DeviceObject */
8041f541 8b4f08 mov ecx,[edi+0x8]
/* edi 为 IN PDEVICE_OBJECT DeviceObject */
/* struct _DEVICE_OBJECT (sizeof=184) */
/* +08 struct _DRIVER_OBJECT *DriverObject */
8041f544 0fb600 movzx eax,byte ptr [eax]
/* eax 为新的当前 IO_STACK_LOCATION */
/* struct _IO_STACK_LOCATION (sizeof=36) */
/* +00 byte MajorFunction */
8041f547 ff548138 call dword ptr [ecx+eax*4+0x38]
/* ecx 为 DeviceObject->DriverObject */
/* struct _DRIVER_OBJECT (sizeof=168) */
/* +38 function *MajorFunction[28] */
/* eax 为 Irp->CurrentStackLocation->MajorFunction */
/* [ecx+eax*4+0x38] 为 */
/* DeviceObject->DriverObject.MajorFunction[Irp->CurrentStackLocation->MajorFunction] */
8041f54b 5f pop edi
8041f54c 5e pop esi
8041f54d c3 ret

IoCallDriver 将参数 Irp 的 +23 char CurrentLocation 减1,然后检查这时的 CurrentLocation 是否大于0。如果不大于0,将蓝屏。接着将参数 Irp 的 +60 struct _IO_STACK_LOCATION *CurrentStackLocation 减 0x24 。这里原来是一个 IO_STACK_LOCATION 的地址,0x24是一个 IO_STACK_LOCATION 结构的大小。这样减 0x24 就等于把 +60 struct _IO_STACK_LOCATION *CurrentStackLocation 指向了前一个 IO_STACK_LOCATION。然后将新的 CurrentStackLocation 的 +14 struct _DEVICE_OBJECT *DeviceObject 赋值为传入的参数 DeviceObject 。从传入的参数 DeviceObject 中获得该 DeviceObject 的 DriverObject,调用该 DriverObject 的新的 CurrentStackLocation 的 +00 byte MajorFunction 相应的 MajorFunction ,用传入的两个参数 IN PDEVICE_OBJECT DeviceObject,IN OUT PIRP Irp 做参数。

简单的说,把 Irp 的 CurrentLocation 减1,CurrentStackLocation 指向前一个(地址更小处) 的IO_STACK_LOCATION。然后根据现在的 CurrentStackLocation 所指的 IO_STACK_LOCATION 结构中 MajorFunction 的值,调用 DeviceObject 所属的驱动的 DriverObject 中 MajorFunction[28] 相应的函数。

DriverObject 中的 MajorFunction[28],是在 DriverEntry 中初始化的。

Irp 的产生

Irp 说到底是由 IoAllocateIrp 产生的。IoBuildDeviceIoControlRequest 这样产生 Irp 的函数,也是调用 
IoAllocateIrp 实现的。一个驱动可能需要另一层的驱动完成什么功能,而直接使用 IoBuildDeviceIoControlRequest 这样函数产生 Irp,并用这个 Irp 和其他驱动通信。更多的 Irp 是应用层,使用 ReadFile,WriteFile,DeviceIoControl 等这样的 api,来产生的。这些 api 最终也会调用 IoAllocateIrp 产生一个 Irp,然后初始化这个 Irp,发给驱动,驱动会根据 Irp ,完成相应的任务。

Irp 操作的一些函数

操作Irp的一些函数,很简单,只是一些宏。了解这些函数的具体的操作,有助于对 Irp 的了解。
下面的内容来自 ntddk.h

IoGetCurrentIrpStackLocation

#define IoGetCurrentIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation )

IoSkipCurrentIrpStackLocation

#define IoSkipCurrentIrpStackLocation( Irp ) /
(Irp)->CurrentLocation++; /
(Irp)->Tail.Overlay.CurrentStackLocation++;

IoGetNextIrpStackLocation

#define IoGetNextIrpStackLocation( Irp ) (/
(Irp)->Tail.Overlay.CurrentStackLocation - 1 )

IoCopyCurrentIrpStackLocationToNext

#define IoCopyCurrentIrpStackLocationToNext( Irp ) { /
PIO_STACK_LOCATION irpSp; /
PIO_STACK_LOCATION nextIrpSp; /
irpSp = IoGetCurrentIrpStackLocation( (Irp) ); /
nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); /
RtlCopyMemory( nextIrpSp, irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); /
nextIrpSp->Control = 0; }

IoMarkIrpPending

#define IoMarkIrpPending( Irp ) ( /
IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED )

Irp 的释放

使用 IoFreeIrp 释放一个 Irp

Irp 的结束

使用 IoCompleteRequest 结束一个 Irp,这个是了解如何使用 Irp 通信中,除了 IoCallDriver 外,第二重要的函数,这个函数又大又复杂,牵涉到其他的一些机制,对自己,还是下不了这个毒手,所以就不说了,用一用也就有个大概的概念。

晕了吧



欢迎交流,欢迎交朋友,
欢迎访问
主页 http://jiurl.yeah.net http://jiurl.nease.net 论坛 http://jiurl.cosoft.org.cn/forum

f啊k,不带你们这样的啊,有好事不叫我。

 

 

飞牛NAS打造成童年经典游戏机 这篇文章介绍如何使用飞牛NAS搭建经典游戏模拟器。首先需开启Docker并下载RetroArch-web镜像,随后创建容器并设置端口映射。启动后上传游戏ROM文件(如NES格式),在模拟器中加载即可游玩。文章以修改版坦克大战为例,详细说明按键配置方法。同时还提到公网访问需配置DDNS或使用ZeroTier内网穿透。通过这套方案,用户可以在NAS上重温红白机等经典游戏体验。 阅读详情

相关推荐

MATLAB Appdesigner开发独立桌面App全流程(一):以打开串口功能为例介绍Appdesigner的基本使用

本文详细介绍了Appdesigner的基本使用,以串口功能为例介绍按钮回调函数的实现以及控件之间通信的问题

Zhuwany的博客 3万+

IRP 处理流程

本文通过打开一个文件对象为例子,描述了一个带有两个I/O stack location的IRP的详细处理过程。当然一个IRP可以有多个I/O stack location,具体个数取决于将要处理该请求的驱动的层数。下图详细描述了驱动程序是如何通过使用I/O支持例程(IoXxx routines)来处理IRP以此来实现对相应文件的读写操作。 1:I/O管理器调用文件系统驱动

门没锁的专栏 7344

Cadence IC618/Spectre231安装避坑指南:详解环境变量配置与License管理那些事儿

本文深入解析Cadence IC618/Spectre231安装过程中的环境变量配置与License管理难题,提供从变量冲突解决到高效License管理的实用方案。针对常见的64位标识冲突、路径污染及License服务器连接问题,给出具体诊断步骤和优化建议,帮助用户构建稳定可靠的EDA环境。

weixin_33737134的博客 615

驱动开发程序的IRP处理过程

标准IRP的处理过程如同上图所示,整个处理由IO管理器创建的IRP开始。当然这个IO管理器在大多数情况下是系统,然而在驱动程序当中也可以创建IRP。下面四个函数可以用于创建IRP: IoBuildAsynchronousFsdRequest用于创建异步IRP,发送IRP的IO管理器不需要因为等待IRP的处理。 IoBuildSynchronousFsdRequest用于创建同步IRP,如果IR

dayenglish的专栏 1556

用python画带有正负值的条形图

常见的条形图只能表现数据的大小,却不能表现值的正负关系。但是其实仅仅使用`pandas`和`matplotlib`两个包就可以实现y轴负轴的添加以及负值的显示,并且可以为正负值分别设置不同的颜色,让条形图看上去更加清晰,易于我们分析

weixin_44853840的博客 5382

7.1华为OD机试真题 新系统 - 仓库盘点 (Java/Py/C/C++/Js/Go)

7.1华为OD机试真题 新系统 - 仓库盘点 (Java/Py/C/C++/Js/Go)

算法大师! 507

伪指令IRP和IRPC

伪指令IRP和IRPC伪指令IRP 伪指令IRP的作用是用每个参数创建一组语句,其重复次数由伪指令后面参数表中参数的个数来确定。其一般使用格式如下: IRP形式参数, <实参1, 实参2, ……, 实参n> 重复的语句组 ENDM 例9.11 把16位通用寄存器之值相加,并把结果存入寄存器AX。 解:由于16位通用寄存器名是一些不同的符号,不能用计数的方法来依次访问它们,所以,我们需要用

LiYuan199118的博客 1546

使用LSTM实现自动调制识别(RML2018.01a)

目录一、LSTM的代码实现1.1 导入包1.2 数据读取及数据集划分1.3 数据预处理1.4 构建LSTM模型 本文基于RML2018.01a大型数据集,给出LSTM的信号识别的实现方式(附代码) RML2018.01a数据集信息如下: 模型 传送门 CNN/ResNet 使用CNN/ResNet实现自动调制识别(RML2018.01a) LSTM 使用LSTM实现自动调制识别(RML2018.01a)) 一、LSTM的代码实现 1.1 导入包 import numpy as np

QAQIknow的博客 6121

I/O Request Packet

第5章 I/O Request Packet 5.1 数据结构 在处理 I/O 请求上,有两个重要的数据结构:IRP(I/O request packet)和 IO_STACK_LOCATION 5.1.1 IRP 的结构 下面是在 windbg 里得到的 IRP 结构: nt!_IRP +0x000 Type : Int2B +0x002 Size

zhuo_zhibin的专栏 6094

DeepSeek赋能公文写作:从高效成文到精准传情的全维度指南

摘要:AI赋能公文写作的精准化实践 公文写作长期面临框架混乱、素材匮乏、表达不规范、修改低效等痛点。DeepSeek等AI工具通过"精准指令+分步赋能"模式实现突破:首先明确公文的目的性、逻辑性和规范性特征;其次采用包含场景、类型、目的等要素的指令模板;再分四步实施:框架搭建确保层次分明,内容填充解决素材问题,表达优化适配不同语体,合规校验把关格式规范。典型案例显示,AI能将数据罗列转化为"数据+成果+价值"的生动表述,使公文既规范又具感染力。这种AI赋能的写作方法显

通俗易懂学IT 231

10分钟极速SpringBoot项目搭建:OpenClaw AI实战攻略

OpenClaw,作为一款革命性的 AI 工具,凭借其强大的智能体能力,能够在短短 10 分钟内,帮助开发者从零构建一个完整的 SpringBoot 项目,实现真正的极速开发。它不仅极大地提高了开发效率,还降低了开发门槛,让更多的开发者能够专注于业务逻辑的实现,而无需被繁琐的配置工作所困扰

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 297

终于彻底弄明白 IRP

 终于彻底弄明白 IRP ,来源:(http://bbs.znpc.net/space.php?uid=2)子系统调用NT的IO系统服务打开命名文件。NT的IO管理器调用对象管理器,查询命名文件,并且帮助解决文件对象的符号连接。同时调用安全参照监视器,检查子系统是否具备打开文件句柄的正确权限。如果NT文件系统不认识文件对象,IO管理器挂起请求。调用多个文件系统直到识别出文件对象才继

SDNHELIXIN的专栏 1081

5.13华为OD机试真题 新系统 - 社交网络相同爱好好友查询 (Java/Py/C/C++/Js/Go)

5.13华为OD机试真题 新系统 - 社交网络相同爱好好友查询 (Java/Py/C/C++/Js/Go)

算法大师! 154

IRP 乱杂谈[转]

作者: JIURL 主页: http://jiurl.yeah.net IRP 是 I/O request packet 的缩写,即 I/O 请求包。驱动与驱动之间通过 IRP 进行通信。而使用驱动的应用层调用的 CreatFile,ReadFile,WriteFile,DeviceIoControl 等函数,说到底也是使用 IRP 和驱动进行通信。一个 IRP 由两部分组成。首先

blues_li的专栏 514

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

[转]IRP 乱杂谈

IRP 是 I/O request packet 的缩写,即 I/O 请求包。驱动与驱动之间通过 IRP 进行通信。而使用驱动的应用层调用的 CreatFile,ReadFile,WriteFile,DeviceIoControl 等函数,说到底也是使用 IRP 和驱动进行通信。一个 IRP 由两部分组成。首先是头部或者叫包的固定部分,是一个 IRP 结构。紧跟在这个头部之后的是 I/O stac...

weixin_30713953的博客 113

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

驱动对象 设备对象 设备栈 乱杂谈

驱动对象 设备对象 设备栈 乱杂谈作者: JIURL                 主页: http://jiurl.yeah.net         用有限的几句话就舒舒服服的建立起对驱动对象和设备对象的概念是不可能的。刚开始是一片模糊,了解的多了,慢慢就清楚。下面的内容会使你对

jiurl的专栏 5888

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

[zz]驱动对象设备对象设备栈乱杂谈

作者: JIURL 主页: http://jiurl.yeah.net   用有限的几句话就舒舒服服的建立起对驱动对象和设备对象的概念是不可能的。刚开始是一片模糊,了解的多了,慢慢就清楚。下面的内容会使你对他们了解的清楚些。   为了后面的叙述方便,首先列出驱动对象和设备对象的结构。   驱动对象结构 DRIVER_OBJECT ,定义如下   struct _DRIVER_OB

anna的专栏 716

[转载]驱动对象 设备对象 设备栈 乱杂谈

作者: JIURL 主页: http://jiurl.yeah.net 用有限的几句话就舒舒服服的建立起对驱动对象和设备对象的概念是不可能的。刚开始是一片模糊,了解的多了,慢慢就清楚。下面的内容会使你对他们了解的清楚些。 为了后面的叙述方便,首先列出驱动对象和设备对象的结构。 驱动对象结构 DRIVER_OBJECT ,定义如下 struct _DRIVER_OBJECT

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 539

windows驱动编程学习笔记——(三)IRP

一,IRP的概念(I/O Request Package) 当一个应用程序调用函数去操作某个设备时,比如调用createFile,deviceIOControl,等等时,I/O管理器为此函数创建一个IRP数据结构对象和一个IRP_STACK_LOCATION数据结构对象数组,(数组个数等于驱动程序堆栈上驱动的个数),IRP中的CurrentStackLocation指向IRP_STACK_LOC

知了112的专栏 1990

【IRP】Windows 驱动之IRP

什么是IRP: I/O request packets,简称IRP。即输入输出请求包。它是WINDOWS内核中的一种非常重要的数据结构。上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求。操作系统将相应的I/O请求转换为相应的IRP。不同的IRP会根据类型被分派的不同的派遣历程中进行处理。 作用: 上层应用程序于底层驱动之间的通讯,即EXE程序和SYS之间的通讯。 应用程序 想要访问内核数据,必须通过IRP数据。又叫IRP请求,当应用程序和驱动交互时,发送一个IRP请求,IRP会在各层设备驱动个之间

dr0op's blog 4914

GNU汇编器——.irp和.macro

目录1 从一个汇编错误开始说起2 GNU汇编器的.irp3 GNU汇编器的.macro4 当.irp遇到.macro参考文献 1 从一个汇编错误开始说起 最近从u-boot中摘了一段代码出来(源于kernel),这段代码作用是用软件(汇编)实现除法和取模运算,因为有些老的CPU是没有相关的硬件指令的。在编译的时候,汇编器报了一些错误,这些错误都是同一类型,这里仅列出其中的一个:Error: bad instruction 'reteq lr'。 错误本身还是比较好理解的,arm32是没有ret指令的。但让人

gzxb1995的博客 3696

IRP IO_STACK_LOCATION 《寒江独钓》内核学习笔记(1)

在学习内核过滤驱动的过程中,遇到了大量的涉及IRP操作的代码,这里有必要对IRP的数据结构和与之相关的API函数做一下笔记。   1. 相关阅读资料 《深入解析 windows 操作系统(第4版,中文版)》 --- 9章 《windows driver kit 帮助文档》 http://support.microsoft.com/kb/115758/zh-cn  IRP 结构中各地址字段...

weixin_33739523的博客 2504
上一篇: JIURL键盘驱动 2
下一篇: JIURL键盘驱动 3
imquestion
博客等级 码龄25年 50粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值