static NTSTATUS PdoSystemPower( IN PXENFILT_THREAD Self, IN PVOID Context ) { PXENFILT_PDO Pdo = Context; PKEVENT Event; Event = ThreadGetEvent(Self); for (;;) { PIRP Irp; PIO_STACK_LOCATION StackLocation; UCHAR MinorFunction; if (Pdo->SystemPowerIrp == NULL) { (VOID) KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, NULL); KeClearEvent(Event); } if (ThreadIsAlerted(Self)) break; Irp = Pdo->SystemPowerIrp; if (Irp == NULL) continue; Pdo->SystemPowerIrp = NULL; KeMemoryBarrier(); StackLocation = IoGetCurrentIrpStackLocation(Irp); MinorFunction = StackLocation->MinorFunction; switch (StackLocation->MinorFunction) { case IRP_MN_SET_POWER: (VOID) __PdoSetSystemPower(Pdo, Irp); break; case IRP_MN_QUERY_POWER: (VOID) __PdoQuerySystemPower(Pdo, Irp); break; default: ASSERT(FALSE); break; } IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); } return STATUS_SUCCESS; }
static NTSTATUS VifMonitor( IN PXENVIF_THREAD Self, IN PVOID _Context ) { PXENVIF_VIF_CONTEXT Context = _Context; PXENVIF_FRONTEND Frontend = PdoGetFrontend(Context->Pdo); PKEVENT Event[EVENT_COUNT]; Trace("====>\n"); Event[THREAD_EVENT] = ThreadGetEvent(Self); Event[MAC_EVENT] = MacGetEvent(FrontendGetMac(Frontend)); for (;;) { NTSTATUS status; Trace("waiting...\n"); status = KeWaitForMultipleObjects(EVENT_COUNT, Event, WaitAny, Executive, KernelMode, FALSE, NULL, NULL); Trace("awake\n"); if (status >= STATUS_WAIT_0 && status < STATUS_WAIT_0 + EVENT_COUNT) { switch (status & STATUS_MASK) { case MAC_EVENT: { KeClearEvent(Event[MAC_EVENT]); Trace("MAC_EVENT\n"); if (Context->Enabled) { PVIF_CALLBACK Callback = &Context->Callback; Callback->Function(Callback->Argument, XENVIF_CALLBACK_MEDIA_STATE_CHANGE); } break; } case THREAD_EVENT: KeClearEvent(Event[THREAD_EVENT]); Trace("THREAD_EVENT\n"); if (ThreadIsAlerted(Self)) goto done; KeSetEvent(&Context->MonitorEvent, IO_NO_INCREMENT, FALSE); break; default: ASSERT(FALSE); break; } } } done: KeSetEvent(&Context->MonitorEvent, IO_NO_INCREMENT, FALSE); Trace("<====\n"); return STATUS_SUCCESS; }