[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/5] Remove StartOverride from all PCI storage adapters



Its possible to install non-Microsoft NVMe drivers on the emulated
NVMe device. During upgrades, the VM requires a reboot using the emulated
devices, but if the driver assigned for the emulated device has a StartOverride
setting, then its likely not started which results in a 0x7B bugcheck.

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/monitor/monitor.c | 191 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 191 insertions(+)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 52311aa..61945f0 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -90,6 +90,12 @@ MONITOR_CONTEXT MonitorContext;
 #define PARAMETERS_KEY(_Service) \
         SERVICE_KEY(_Service) ## "\\Parameters"
 
+#define ENUM_KEY(_Class) \
+        "SYSTEM\\CurrentControlSet\\Enum\\" ## _Class
+
+#define STORAGE_CLASS_GUID \
+        "{4d36e97b-e325-11ce-bfc1-08002be10318}"
+
 static VOID
 #pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds 
/analyze:stacksize'1024'
 __Log(
@@ -1393,6 +1399,189 @@ fail1:
     return FALSE;
 }
 
+static BOOLEAN
+RemoveStartOverrideInstance(
+    _In_ HKEY           BaseKey,
+    _In_ PTSTR          SubKeyName,
+    _In_opt_ PVOID      Context
+    )
+{
+    DWORD               Type;
+    PTSTR               Value;
+    DWORD               ValueLength;
+    DWORD               MaxValueLength;
+    HKEY                SubKey;
+    HRESULT             Error;
+
+    UNREFERENCED_PARAMETER(Context);
+
+    Error = RegOpenKeyEx(BaseKey,
+                         SubKeyName,
+                         0,
+                         KEY_READ,
+                         &SubKey);
+    if (Error != ERROR_SUCCESS)
+        return TRUE;
+
+    Error = RegQueryInfoKey(SubKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    ValueLength = MaxValueLength + sizeof (TCHAR);
+
+    Value = calloc(1, ValueLength);
+    if (Value == NULL)
+        goto fail2;
+
+    Error = RegQueryValueEx(SubKey,
+                            "ClassGUID",
+                            NULL,
+                            &Type,
+                            (LPBYTE)Value,
+                            &ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
+
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail4;
+    }
+
+    if (_tcsnicmp(Value, STORAGE_CLASS_GUID, ValueLength) != 0)
+        goto done;
+
+    ValueLength = MaxValueLength + sizeof (TCHAR);
+    memset(Value, 0, ValueLength);
+
+    Error = RegQueryValueEx(SubKey,
+                            "Service",
+                            NULL,
+                            &Type,
+                            (LPBYTE)Value,
+                            &ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail5;
+    }
+
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail6;
+    }
+
+    RemoveStartOverride(Value);
+
+done:
+    free(Value);
+
+    RegCloseKey(SubKey);
+
+    return TRUE;
+
+fail6:
+    Log("fail6");
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+    free(Value);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Log("fail1");
+
+    return TRUE;
+}
+
+static BOOLEAN
+RemoveStartOverrideDevice(
+    _In_ HKEY           BaseKey,
+    _In_ PTSTR          SubKeyName,
+    _In_opt_ PVOID      Context
+    )
+{
+    HKEY                SubKey;
+    HRESULT             Error;
+
+    UNREFERENCED_PARAMETER(Context);
+
+    Error = RegOpenKeyEx(BaseKey,
+                         SubKeyName,
+                         0,
+                         KEY_READ,
+                         &SubKey);
+    if (Error != ERROR_SUCCESS)
+        return TRUE;
+
+    (VOID) RegEnumSubKeys(SubKey,
+                          RemoveStartOverrideInstance,
+                          NULL);
+
+    RegCloseKey(SubKey);
+
+    return TRUE;
+}
+
+static BOOL
+RemoveAllStartOverrides(
+    VOID
+    )
+{
+    HKEY            EnumKey;
+    HRESULT         Error;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         ENUM_KEY("PCI"),
+                         0,
+                         KEY_READ,
+                         &EnumKey);
+    if (Error != ERROR_SUCCESS) {
+        goto fail1;
+    }
+
+    Error = RegEnumSubKeys(EnumKey,
+                           RemoveStartOverrideDevice,
+                           NULL);
+    if (Error != ERROR_SUCCESS) {
+        goto fail2;
+    }
+
+    RegCloseKey(EnumKey);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Log("fail1");
+
+    return FALSE;
+}
+
 VOID WINAPI
 MonitorMain(
     _In_    DWORD       argc,
@@ -1411,6 +1600,7 @@ MonitorMain(
     Log("====>");
 
     (VOID) RemoveStartOverride("stornvme");
+    (VOID) RemoveAllStartOverrides();
 
     Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                          PARAMETERS_KEY(__MODULE__),
@@ -1565,6 +1755,7 @@ done:
 
     CloseHandle(Context->ParametersKey);
     (VOID) RemoveStartOverride("stornvme");
+    (VOID) RemoveAllStartOverrides();
 
     Log("<====");
 
-- 
2.51.2.windows.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.