[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/2] Add safety check to Unplug
If a driver does not have the matching Enum keys to trigger an AddDevice, then block the Unplug of any emulated device. When a boot start driver is removed, the Enum keys are removed, but the driver is not unloaded. Since there is no CoInstaller to remove the Unplug value, there needs to be a check to prevent emulated devices from being unplugged while there is no driver bindings for the child device, so the child device will not create the PV device. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx> --- src/xen/unplug.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/xen/unplug.c b/src/xen/unplug.c index 7ace2ab..3121005 100644 --- a/src/xen/unplug.c +++ b/src/xen/unplug.c @@ -49,6 +49,11 @@ #define UNPLUG_TAG 'LPNU' +typedef struct _UNPLUG_DATA { + PCHAR Name; + BOOLEAN Found; +} UNPLUG_DATA, *PUNPLUG_DATA; + typedef struct _UNPLUG_CONTEXT { LONG References; HIGH_LOCK Lock; @@ -186,6 +191,74 @@ fail1: return status; } +static NTSTATUS +UnplugCheckEnumKeyCallback( + IN PVOID Context, + IN HANDLE Key, + IN PANSI_STRING Name + ) +{ + PUNPLUG_DATA Data = Context; + + UNREFERENCED_PARAMETER(Key); + + if (strstr(Name->Buffer, Data->Name) != NULL) + Data->Found = TRUE; + + return STATUS_SUCCESS; +} + +static NTSTATUS +UnplugCheckEnumKey( + IN PCHAR EnumName, + OUT PULONG Value + ) +{ + UNICODE_STRING Unicode; + UNPLUG_DATA Data; + HANDLE Key; + NTSTATUS status; + + RtlInitUnicodeString(&Unicode, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum\\XENBUS"); + + status = RegistryOpenKey(NULL, + &Unicode, + KEY_READ, + &Key); + if (!NT_SUCCESS(status)) + goto fail1; + + Data.Found = FALSE; + Data.Name = EnumName; + + status = RegistryEnumerateSubKeys(Key, + UnplugCheckEnumKeyCallback, + &Data); + if (!NT_SUCCESS(status)) + goto fail2; + + if (!Data.Found) { + Info("VETO Unplug %s\n", EnumName); + *Value = 0; + } + + RegistryCloseKey(Key); + + return STATUS_SUCCESS; + +fail2: + Error("fail2\n"); + + RegistryCloseKey(Key); + +fail1: + Error("fail1 %08x\n", status); + + *Value = 0; + + return status; +} + static VOID UnplugSetRequest( IN UNPLUG_TYPE Type @@ -194,6 +267,7 @@ UnplugSetRequest( PUNPLUG_CONTEXT Context = &UnplugContext; HANDLE UnplugKey; PCHAR ValueName; + PCHAR EnumName; ULONG Value; KIRQL Irql; NTSTATUS status; @@ -207,12 +281,15 @@ UnplugSetRequest( switch (Type) { case UNPLUG_DISKS: ValueName = "DISKS"; + EnumName = "VBD"; break; case UNPLUG_NICS: ValueName = "NICS"; + EnumName = "VIF"; break; default: ValueName = NULL; + EnumName = NULL; ASSERT(FALSE); } @@ -224,6 +301,9 @@ UnplugSetRequest( (VOID) RegistryDeleteValue(UnplugKey, ValueName); + if (Value != 0) + (VOID) UnplugCheckEnumKey(EnumName, &Value); + Info("%s (%u)\n", ValueName, Value); AcquireHighLock(&Context->Lock, &Irql); -- 2.44.0.windows.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |