首页 > 代码库 > CPU与IRP的一些相关函数

CPU与IRP的一些相关函数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
VOID
KiAdjustIrpCredits (
    VOID
    )其中        Number = KeNumberProcessors;Prcb = KiProcessorBlock[Index];
多核情况下调整每个CPU的IRP对象配额。在while (Index < Number);轮询调整1-n的CPU的配额InterlockedExchangeAdd(&Prcb->LookasideIrpFloat, Adjust),不过最后一个CPU为什么是 InterlockedExchangeAdd(&Prcb->LookasideIrpFloat, -TotalAdjust)??  PIRP
IopAllocateIrpPrivate(
    IN CCHAR StackSize,
    IN BOOLEAN ChargeQuota
    )分配IRP首先根据IRP需要的栈单元决定是否从两个快查表中的一个分配。一个栈单元为1则为LookasideSmallIrpList ,一个栈单元小于8大于1则为LookasideLargeIrpList.然后从指定的快查表中摘除一个作为IRP的空间。如果超过8 则自行分配。没什么说的了。 里面的IopInitializeIrp倒是个需要注意的 StackSize  是IRP要分配的堆栈数目PacketSize是IRP的长度加上 StackSize *stack的长度#define IopInitializeIrp( Irp, PacketSize, StackSize ) {          \
    RtlZeroMemory( (Irp), (PacketSize) );                         \
    (Irp)->Type = (CSHORT) IO_TYPE_IRP;                           \
    (Irp)->Size = (USHORT) ((PacketSize));                        \
    (Irp)->StackCount = (CCHAR) ((StackSize));                    \
    (Irp)->CurrentLocation = (CCHAR) ((StackSize) + 1);           \
    (Irp)->ApcEnvironment = KeGetCurrentApcEnvironment();         \
    InitializeListHead (&(Irp)->ThreadListEntry);                 \
    (Irp)->Tail.Overlay.CurrentStackLocation =                    \
        ((PIO_STACK_LOCATION) ((UCHAR *) (Irp) +                  \
            sizeof( IRP ) +                                       \
            ( (StackSize) * sizeof( IO_STACK_LOCATION )))); } IopFreeIrp情况类似:首先检验IRP是否是IO_TYPE_IRP,&(Irp)->ThreadListEntry为空。当前IRP的CurrentLocation大于IRP的STACKCOUNT。获取当前CPU的PKPRCB , prcb = KeGetCurrentPrcb();然后根据IRP之前是从快查表分配还是使用自行分配进行处理。 另:这里是 gussing是个错别字 的博客
http://www.cnblogs.com/gussing/archive/2011/01/18/1938140.html因为他不允许转载 所以在这里谈谈内容 也推荐大家对驱动内核有兴趣的去看下他的wdk tips IRP的创建可以为自写驱动创建和IO管理器创建,在释放上有自己释放或者由IO管理器释放两种IoAllocateIrp IoBuildAsynchronousFsdRequest属于需要自行释放,WDK帮助也有提到。( IoBuildSynchronousFsdRequest   IoBuildDeviceIoControlRequest TdiBuildInternalDeviceControlIrp 属于交与IO管理器释放。 PIRP
IoBuildAsynchronousFsdRequest(
    IN ULONG MajorFunction,
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PVOID Buffer OPTIONAL,
    IN ULONG Length OPTIONAL,
    IN PLARGE_INTEGER StartingOffset OPTIONAL,
    IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL
    )
{
    PIRP irp;
    PIO_STACK_LOCATION irpSp;    //    分配IRP 第一个是IRP的stack数目 ,第二个参数是不改变IRP配额    irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );
    if (!irp) {
        return irp;
    }    // 按推荐的博客的那个作者的意思 这里应该不设置THREAD 因为他将创建的IRP分类至NON THREAD IRP。    irp->Tail.Overlay.Thread = PsGetCurrentThread();    irpSp = IoGetNextIrpStackLocation( irp );    irpSp->MajorFunction = (UCHAR) MajorFunction;    if (MajorFunction != IRP_MJ_FLUSH_BUFFERS &&
        MajorFunction != IRP_MJ_SHUTDOWN &&
        MajorFunction != IRP_MJ_PNP &&
        MajorFunction != IRP_MJ_POWER) {    // ......根据设备对象的类型来决定 BUFFER的种类是SYSBUF 还是MDL 或者原函数输入BUF......   // 代码比较简单  分配IRP并设置读写参数        if (MajorFunction == IRP_MJ_WRITE) {
            irpSp->Parameters.Write.Length = Length;
            irpSp->Parameters.Write.ByteOffset = *StartingOffset;
        } else {
            irpSp->Parameters.Read.Length = Length;
            irpSp->Parameters.Read.ByteOffset = *StartingOffset;
        }
    }    irp->UserIosb = IoStatusBlock;
    return irp;
}    IoBuildsynchronousFsdRequest还是调用IoBuildAsynchronousFsdRequest只不过多了一行 irp->UserEvent = Event,用于同步时候的等待。