static FORCEINLINE NTSTATUS __UnplugPreamble( IN PXENFILT_UNPLUG_CONTEXT Context, IN BOOLEAN Locked ) { KIRQL Irql = PASSIVE_LEVEL; USHORT Magic; UCHAR Version; NTSTATUS status; if (!Locked) AcquireHighLock(&Context->Lock, &Irql); // See docs/misc/hvm-emulated-unplug.markdown for details of the // protocol in use here Magic = READ_PORT_USHORT((PUSHORT)0x10); if (Magic == 0xd249) { Context->BlackListed = TRUE; goto done; } status = STATUS_NOT_SUPPORTED; if (Magic != 0x49d2) goto fail1; Version = READ_PORT_UCHAR((PUCHAR)0x12); if (Version != 0) { WRITE_PORT_USHORT((PUSHORT)0x12, 0xFFFF); // FIXME WRITE_PORT_ULONG((PULONG)0x10, (MAJOR_VERSION << 16) | (MINOR_VERSION << 8) | MICRO_VERSION); Magic = READ_PORT_USHORT((PUSHORT)0x10); if (Magic == 0xd249) Context->BlackListed = TRUE; } done: LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: PRE-AMBLE (DRIVERS %s)\n", (Context->BlackListed) ? "BLACKLISTED" : "NOT BLACKLISTED"); if (!Locked) ReleaseHighLock(&Context->Lock, Irql); return STATUS_SUCCESS; fail1: Error("fail1 (%08x)\n", status); if (!Locked) ReleaseHighLock(&Context->Lock, Irql); return status; }
static VOID DebugDeregister( IN PXENBUS_DEBUG_CONTEXT Context, IN PXENBUS_DEBUG_CALLBACK Callback ) { KIRQL Irql; AcquireHighLock(&Context->Lock, &Irql); RemoveEntryList(&Callback->ListEntry); ReleaseHighLock(&Context->Lock, Irql); __DebugFree(Callback); }
static NTSTATUS DebugRegister( IN PXENBUS_DEBUG_CONTEXT Context, IN const CHAR *Prefix, IN VOID (*Function)(PVOID, BOOLEAN), IN PVOID Argument OPTIONAL, OUT PXENBUS_DEBUG_CALLBACK *Callback ) { ULONG Length; KIRQL Irql; NTSTATUS status; *Callback = __DebugAllocate(sizeof (XENBUS_DEBUG_CALLBACK)); status = STATUS_NO_MEMORY; if (*Callback == NULL) goto fail1; (VOID) RtlCaptureStackBackTrace(1, 1, &(*Callback)->Caller, NULL); Length = (ULONG)__min(strlen(Prefix), MAXIMUM_PREFIX_LENGTH - 1); RtlCopyMemory((*Callback)->Prefix, Prefix, Length); (*Callback)->Function = Function; (*Callback)->Argument = Argument; AcquireHighLock(&Context->Lock, &Irql); InsertTailList(&Context->List, &(*Callback)->ListEntry); ReleaseHighLock(&Context->Lock, Irql); return STATUS_SUCCESS; fail1: Error("fail1 (%08x)\n", status); return status; }
static VOID UnplugReplay( IN PXENFILT_UNPLUG_CONTEXT Context ) { KIRQL Irql; NTSTATUS status; AcquireHighLock(&Context->Lock, &Irql); status = __UnplugPreamble(Context, TRUE); ASSERT(NT_SUCCESS(status)); if (Context->UnpluggedDisks) { __UnplugDisksLocked(Context); } if (Context->UnpluggedNics) { __UnplugNicsLocked(); } ReleaseHighLock(&Context->Lock, Irql); }
static FORCEINLINE VOID __UnplugNics( IN PXENFILT_UNPLUG_CONTEXT Context ) { HANDLE UnplugKey; PANSI_STRING ServiceNames; ULONG Index; HANDLE ServiceKey; KIRQL Irql; NTSTATUS status; UnplugKey = DriverGetUnplugKey(); ServiceKey = NULL; ServiceNames = NULL; status = RegistryQuerySzValue(UnplugKey, "NICS", &ServiceNames); if (!NT_SUCCESS(status)) goto done; for (Index = 0; ServiceNames[Index].Buffer != NULL; Index++) { PANSI_STRING ServiceName = &ServiceNames[Index]; CHAR ServiceKeyName[sizeof (SERVICES_KEY "\\XXXXXXXX")]; ULONG Count; status = RtlStringCbPrintfA(ServiceKeyName, sizeof (ServiceKeyName), SERVICES_KEY "\\%Z", ServiceName); ASSERT(NT_SUCCESS(status)); status = RegistryOpenSubKey(NULL, ServiceKeyName, KEY_READ, &ServiceKey); if (!NT_SUCCESS(status)) goto done; status = RegistryQueryDwordValue(ServiceKey, "Count", &Count); if (NT_SUCCESS(status)) { if (Count == 0) goto done; } RegistryCloseKey(ServiceKey); ServiceKey = NULL; } AcquireHighLock(&Context->Lock, &Irql); ASSERT(!Context->UnpluggedNics); __UnplugNicsLocked(); Context->UnpluggedNics = TRUE; ReleaseHighLock(&Context->Lock, Irql); done: if (ServiceKey != NULL) RegistryCloseKey(ServiceKey); if (ServiceNames != NULL) RegistryFreeSzValue(ServiceNames); }