還原PoStartNextPowerIrp實現

void __stdcall PoStartNextPowerIrp(PIRP Irp)
{
  _IO_STACK_LOCATION *nextSp; // esi MAPDST
  bool v3; // zf
  PIRP findIrp; // edi MAPDST
  _IO_STACK_LOCATION *v8; // esi
  ULONG v9; // eax
  _LIST_ENTRY *v11; // ecx
  _IO_STACK_LOCATION *v12; // esi
  _LIST_ENTRY *v13; // ST10_4
  IRP *v15; // eax
  _LIST_ENTRY *v16; // ecx
  _LIST_ENTRY *v17; // edx
  UCHAR minorFunction; // cl
  POWER_STATE_TYPE powerType; // ecx
  _IO_STACK_LOCATION *pCurStackLocation; // esi
  _LIST_ENTRY *v24; // ecx
  LIST_ENTRY *v25; // eax MAPDST
  PVOID CallersAddress; // [esp+Ch] [ebp-1Ch]
  PVOID CallersCaller; // [esp+10h] [ebp-18h]
  DEVOBJ_EXTENSION *devOjExt; // [esp+18h] [ebp-10h] MAPDST
  _IO_STACK_LOCATION *ioStack; // [esp+1Ch] [ebp-Ch]
  _DEVICE_OBJECT *devObj; // [esp+20h] [ebp-8h]
  KIRQL NewIrql; // [esp+27h] [ebp-1h]

  nextSp = 0;
  ioStack = 0;
  if ( !Irp )
    RtlAssert("Irp", "d:\\srvrtm\\base\\ntos\\po\\pocall.c", 0x213u, 0);
  nextSp = Irp->Tail.Overlay.CurrentStackLocation;
  v3 = nextSp->MajorFunction == IRP_MJ_POWER;
  nextSp = Irp->Tail.Overlay.CurrentStackLocation;
  if ( !v3 )
    RtlAssert("irpsp->MajorFunction == IRP_MJ_POWER", "d:\\srvrtm\\base\\ntos\\po\\pocall.c", 0x216u, 0);
  if ( KeGetCurrentIrql() > DISPATCH_LEVEL )
    RtlAssert("KeGetCurrentIrql() <= DISPATCH_LEVEL", "d:\\srvrtm\\base\\ntos\\po\\pocall.c", 0x217u, 0);
  devObj = nextSp->DeviceObject;
  devOjExt = devObj->DeviceObjectExtension;
  findIrp = 0;
  findIrp = 0;
  RtlGetCallersAddress(&CallersAddress, &CallersCaller);
  PoPowerTracePrint(4, CallersAddress, CallersCaller, devObj, Irp, nextSp);
  NewIrql = KfAcquireSpinLock(&PopIrpSerialLock);
  if ( PopInrushIrpPointer != Irp )
  {
    minorFunction = nextSp->MinorFunction;
    if ( minorFunction != IRP_MN_SET_POWER && minorFunction != IRP_MN_QUERY_POWER )
    {
      if ( PoDebug & 0x200 )
        DbgPrint("PoStartNextPowerIrp: Irp @ %08x, minor function %d\n", Irp, minorFunction);
      goto LABEL_63;
    }
    powerType = nextSp->Parameters.Power.Type;
    if ( powerType != DevicePowerState )
    {
      if ( powerType )
        goto LABEL_63;
      nextSp = 0;
      findIrp = 0;
      findIrp = PopFindIrpByDeviceObject(devObj, 0);
      if ( !findIrp )
      {
        BYTE1(devOjExt->PowerFlags) &= 0xFCu;
        goto LABEL_63;
      }
      goto LABEL_61;
    }
    if ( !PopInrushIrpPointer && PopInrushPending )
    {
      findIrp = PopFindIrpByInrush();
      if ( !findIrp )
      {
        PopInrushPending = 0;
LABEL_52:
        nextSp = 0;
        goto LABEL_53;
      }
      pCurStackLocation = findIrp->Tail.Overlay.CurrentStackLocation;
      // pCurrStackLocation--;
      devOjExt = pCurStackLocation[-1].DeviceObject->DeviceObjectExtension;
      nextSp = pCurStackLocation - 1;
      if ( !(devOjExt->PowerFlags & 0x400) )
      {
        RemoveEntryList(&findIrp->Tail.CompletionKey + 3);
        --PopIrpSerialListLength;
        nextSp->DeviceObject->DeviceObjectExtension->PowerFlags |= 0x400u;
        PopInrushIrpPointer = findIrp;
        PopInrushIrpReferenceCount = 1;
        PopPerfHandleInrush(1);
LABEL_53:
        if ( findIrp && nextSp->DeviceObject == devObj )
        {
          findIrp = 0;
          goto LABEL_63;
        }
        findIrp = PopFindIrpByDeviceObject(devObj, 1);
        if ( !findIrp )
          goto LABEL_57;
LABEL_61:
        v24 = findIrp->Tail.Overlay.ListEntry.Blink;
        ioStack = findIrp->Tail.Overlay.CurrentStackLocation - 1;
        v25 = findIrp->Tail.Overlay.ListEntry.Flink;
        v24->Flink = v25;
        v25->Blink = v24;
        goto LABEL_62;
      }
    }
    findIrp = 0;
    goto LABEL_52;
  }
  if ( (nextSp->Parameters.Power.SystemContext & PowerSystemHibernate) != PowerSystemHibernate )
    RtlAssert(
      "(irpsp->Parameters.Power.SystemContext & POP_INRUSH_CONTEXT) == POP_INRUSH_CONTEXT",
      "d:\\srvrtm\\base\\ntos\\po\\pocall.c",
      0x23Du,
      0);
  if ( PopInrushIrpReferenceCount > 1 )
  {
    if ( --PopInrushIrpReferenceCount < 0 )
      RtlAssert("PopInrushIrpReferenceCount >= 0", "d:\\srvrtm\\base\\ntos\\po\\pocall.c", 0x24Au, 0);
    findIrp = PopFindIrpByDeviceObject(devObj, 1);
    if ( !findIrp )
      goto LABEL_75;
    v8 = findIrp->Tail.Overlay.CurrentStackLocation;
    v9 = v8[-1].Parameters.Power.SystemContext;
    nextSp = v8 - 1;
    if ( (v9 & PowerSystemHibernate) == PowerSystemHibernate )
    {
      findIrp = 0;
    }
    else
    {
      v25 = findIrp->Tail.Overlay.ListEntry.Flink;
      v11 = findIrp->Tail.Overlay.ListEntry.Blink;
      v11->Flink = v25;
      v25->Blink = v11;
      --PopIrpSerialListLength;
    }
    if ( !findIrp )
LABEL_75:
      BYTE1(devOjExt->PowerFlags) &= 0xF3u;
    KfReleaseSpinLock(&PopIrpSerialLock, NewIrql);
    if ( findIrp )
    {
      if ( !(nextSp->DeviceObject->DeviceObjectExtension->PowerFlags & 0x400) )
        RtlAssert(
          "nextsp->DeviceObject->DeviceObjectExtension->PowerFlags & POPF_DEVICE_ACTIVE",
          "d:\\srvrtm\\base\\ntos\\po\\pocall.c",
          0x26Bu,
          0);
      PopPresentIrp(nextSp, findIrp, 0);
    }
    return;
  }
  if ( --PopInrushIrpReferenceCount )
    RtlAssert("PopInrushIrpReferenceCount == 0", "d:\\srvrtm\\base\\ntos\\po\\pocall.c", 0x278u, 0);
  findIrp = PopFindIrpByInrush();
  nextSp = 0;
  if ( findIrp )
  {
    if ( !PopInrushPending )
      RtlAssert("PopInrushPending", "d:\\srvrtm\\base\\ntos\\po\\pocall.c", 0x27Du, 0);
    v12 = findIrp->Tail.Overlay.CurrentStackLocation;
    v13 = v12[-1].DeviceObject;
    nextSp = v12 - 1;
    findIrp = PopFindIrpByDeviceObject(v13, 1);
    if ( findIrp )
    {
      PopInrushIrpPointer = 0;
      PopInrushIrpReferenceCount = 0;
      nextSp = findIrp->Tail.Overlay.CurrentStackLocation - 1;
      PopPerfHandleInrush(0);
      if ( nextSp->DeviceObject->DeviceObjectExtension->PowerFlags & 0x400 )
      {
        findIrp = 0;
        nextSp = 0;
      }
      else
      {
        RemoveEntryList(&findIrp->Tail.Overlay.ListEntry);
        nextSp->DeviceObject->DeviceObjectExtension->PowerFlags |= 0x400u;
        --PopIrpSerialListLength;
      }
    }
    else
    {
      RemoveEntryList(&findIrp->Tail.Overlay.ListEntry);
      BYTE1(nextSp->DeviceObject->DeviceObjectExtension->PowerFlags) |= 4u;
      --PopIrpSerialListLength;
      PopInrushIrpPointer = findIrp;
      PopInrushIrpReferenceCount = 1;
    }
  }
  else
  {
    PopInrushIrpPointer = 0;
    PopInrushIrpReferenceCount = 0;
    PopPerfHandleInrush(0);
  }
  if ( !nextSp || nextSp->DeviceObject != devObj )
  {
    v15 = PopFindIrpByDeviceObject(devObj, 1);
    findIrp = v15;
    if ( v15 )
    {
      v16 = v15->Tail.Overlay.ListEntry.Flink;
      v17 = v15->Tail.Overlay.ListEntry.Blink;
      nextSp = v15->Tail.Overlay.CurrentStackLocation - 1;
      v17->Flink = v16;
      v16->Blink = v17;
      ioStack = nextSp;
      BYTE1(nextSp->DeviceObject->DeviceObjectExtension->PowerFlags) |= 4u;
LABEL_62:
      --PopIrpSerialListLength;
      goto LABEL_63;
    }
    ioStack = 0;
LABEL_57:
    BYTE1(devOjExt->PowerFlags) &= 0xF3u;
    goto LABEL_63;
  }
  findIrp = 0;
  ioStack = 0;
LABEL_63:
  KfReleaseSpinLock(&PopIrpSerialLock, NewIrql);
  if ( findIrp )
  {
    if ( !(nextSp->DeviceObject->DeviceObjectExtension->PowerFlags & 0x500) )
      RtlAssert(
        "nextsp->DeviceObject->DeviceObjectExtension->PowerFlags & (POPF_DEVICE_ACTIVE | POPF_SYSTEM_ACTIVE)",
        "d:\\srvrtm\\base\\ntos\\po\\pocall.c",
        0x356u,
        0);
    PopPresentIrp(nextSp, findIrp, 0);
  }
  else if ( !findIrp )
  {
    return;
  }
  if ( findIrp )
  {
    nextSp = ioStack;
    if ( !(ioStack->DeviceObject->DeviceObjectExtension->PowerFlags & 0x500) )
      RtlAssert(
        "secondsp->DeviceObject->DeviceObjectExtension->PowerFlags & (POPF_DEVICE_ACTIVE | POPF_SYSTEM_ACTIVE)",
        "d:\\srvrtm\\base\\ntos\\po\\pocall.c",
        0x35Cu,
        0);
    PopPresentIrp(nextSp, findIrp, 0);
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章