]> xenbits.xensource.com Git - people/pauldu/xennet.git/commitdiff
Clear stolen linkage on device removal
authorPaul Durrant <paul.durrant@citrix.com>
Fri, 4 Mar 2016 11:10:33 +0000 (11:10 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 1 Apr 2016 09:05:46 +0000 (10:05 +0100)
Commit 04c391d9 "Replace copying network settings with identity stealing" to
XENVIF changed the way that network settings are preserved when replacing
an emulated NIC with a PV network device. This change means that both the
emulated NIC and PV device have the same binding to the Windows network
stack. Thus, if we do not destroy that binding prior to uninstallation of
the PV network driver, the stack will be torn down by the network class
uninstall code rather than left in place for the emulated NIC to use after
reboot.

This patch hence adds code to the XENNET co-installer to remove stolen
linkage information from the registry in the pre-remove phase.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/coinst/coinst.c

index 345b0c636f01ee4a3238bb35903096fd3cb1ea94..d38d90d7158167f9864f811134be646df42d0892 100644 (file)
@@ -433,6 +433,189 @@ fail1:
     return FALSE;
 }
 
+static BOOLEAN
+OpenSoftwareKey(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    OUT PHKEY               Key
+    )
+{
+    HRESULT                 Error;
+
+    *Key = SetupDiOpenDevRegKey(DeviceInfoSet,
+                                DeviceInfoData,
+                                DICS_FLAG_GLOBAL,
+                                0,
+                                DIREG_DRV,
+                                KEY_ALL_ACCESS);
+    if (*Key == INVALID_HANDLE_VALUE) {
+        SetLastError(ERROR_PATH_NOT_FOUND);
+        goto fail1;
+    }
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+GetAliasNetInstance(
+    IN  HKEY    Key,
+    OUT PTCHAR  *AliasNetInstance
+    )
+{
+    HRESULT     Error;
+    DWORD       MaxValueLength;
+    DWORD       AliasNetInstanceLength;
+    DWORD       Type;
+
+    Log("====>");
+
+    Error = RegQueryInfoKey(Key,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    AliasNetInstanceLength = MaxValueLength + sizeof (TCHAR);
+
+    *AliasNetInstance = calloc(1, AliasNetInstanceLength);
+    if (*AliasNetInstance == NULL)
+        goto fail2;
+
+    Error = RegQueryValueEx(Key,
+                            "AliasNetInstance",
+                            NULL,
+                            &Type,
+                            (LPBYTE)*AliasNetInstance,
+                            &AliasNetInstanceLength);
+    if (Error != ERROR_SUCCESS) {
+        if (Error != ERROR_FILE_NOT_FOUND) {
+            SetLastError(Error);
+            goto fail3;
+        }
+
+        Type = REG_SZ;
+        AliasNetInstanceLength = 0;
+    }
+
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail4;
+    }
+
+    if (AliasNetInstanceLength == 0) {
+        free(*AliasNetInstance);
+        *AliasNetInstance = NULL;
+    }
+
+    Log("%s", (*AliasNetInstance == NULL) ? "[NONE]" : *AliasNetInstance);
+
+    Log("<====");
+
+    return TRUE;
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+    free(*AliasNetInstance);
+    *AliasNetInstance = NULL;
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static VOID
+ClearStolenLinkage(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData
+    )
+{
+    BOOLEAN                 Success;
+    PTCHAR                  AliasNetInstance;
+    HKEY                    Key;
+    HRESULT                 Error;
+
+    Log("====>");
+
+    Success = OpenSoftwareKey(DeviceInfoSet,
+                              DeviceInfoData,
+                              &Key);
+    if (!Success)
+        goto fail1;
+
+    Success = GetAliasNetInstance(Key, &AliasNetInstance);
+    if (!Success)
+        goto fail2;
+
+    if (AliasNetInstance == NULL)
+        goto done;
+
+    (VOID) RegDeleteKey(Key, "Linkage");
+    (VOID) RegDeleteValue(Key, "NetLuidIndex");
+    (VOID) RegDeleteValue(Key, "NetCfgInstanceID");
+
+done:
+    RegCloseKey(Key);
+
+    Log("<====");
+
+    return;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(Key);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+}
+
 static FORCEINLINE HRESULT
 __DifInstallPreProcess(
     IN  HDEVINFO                    DeviceInfoSet,
@@ -542,12 +725,12 @@ __DifRemovePreProcess(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
     UNREFERENCED_PARAMETER(Context);
 
     Log("<===>");
 
+    ClearStolenLinkage(DeviceInfoSet, DeviceInfoData);
+
     return NO_ERROR;
 }