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);
}
}