]> xenbits.xensource.com Git - pvdrivers/win/xennet.git/commitdiff
Update the co-installer to match how we do alias detection in xenvif
authorPaul Durrant <paul.durrant@citrix.com>
Mon, 9 Sep 2013 14:02:11 +0000 (15:02 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Mon, 9 Sep 2013 14:02:11 +0000 (15:02 +0100)
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
build.py
src/coinst/coinst.c

index b36379052326623b2fc5c9c3bf9d778b1af43fe2..a7b4558e7a7ab7b8def48f7b8a1f003f16cee020 100644 (file)
--- a/build.py
+++ b/build.py
@@ -257,7 +257,6 @@ def archive(filename, files, tgz=False):
     tar = tarfile.open(filename, access)
     for name in files :
         try:
-            print('adding '+name)
             tar.add(name)
         except:
             pass
index 6d590c1741671de3e67d593b3aba84f7dd118e89..90bc0b97f1bcfdcf579c0b8d5d69720ee456cdcf 100644 (file)
@@ -51,14 +51,20 @@ __user_code;
 
 #define SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
 
-#define PARAMETERS_KEY(_Driver)    \
-        SERVICES_KEY ## "\\" ## #_Driver ## "\\Parameters"
+#define SERVICE_KEY(_Driver)    \
+        SERVICES_KEY ## "\\" ## #_Driver
 
-#define ADDRESSES_KEY(_Driver)    \
-        SERVICES_KEY ## "\\" ## #_Driver ## "\\Addresses"
+#define PARAMETERS_KEY(_Driver) \
+        SERVICE_KEY(_Driver) ## "\\Parameters"
 
-#define ALIASES_KEY(_Driver)    \
-        SERVICES_KEY ## "\\" ## #_Driver ## "\\Aliases"
+#define ADDRESSES_KEY(_Driver)  \
+        SERVICE_KEY(_Driver) ## "\\Addresses"
+
+#define ALIASES_KEY(_Driver)  \
+        SERVICE_KEY(_Driver) ## "\\Aliases"
+
+#define UNPLUG_KEY(_Driver)     \
+        SERVICE_KEY(_Driver) ## "\\Unplug"
 
 #define CLASS_KEY "SYSTEM\\CurrentControlSet\\Control\\Class"
 
@@ -192,6 +198,42 @@ FunctionName(
 #undef  _NAME
 }
 
+static HKEY
+OpenSoftwareKey(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData
+    )
+{
+    HKEY                    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 Key;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return NULL;
+}
+
 static PTCHAR
 GetProperty(
     IN  HDEVINFO            DeviceInfoSet,
@@ -265,23 +307,35 @@ fail1:
 static BOOLEAN
 SetFriendlyName(
     IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData,
-    IN  PTCHAR              Description,
-    IN  PTCHAR              Location
+    IN  PSP_DEVINFO_DATA    DeviceInfoData
     )
 {
+    PTCHAR                  Description;
+    PTCHAR                  Location;
     TCHAR                   FriendlyName[MAX_PATH];
     DWORD                   FriendlyNameLength;
     HRESULT                 Result;
     HRESULT                 Error;
 
+    Description = GetProperty(DeviceInfoSet,
+                              DeviceInfoData,
+                              SPDRP_DEVICEDESC);
+    if (Description == NULL)
+        goto fail1;
+
+    Location = GetProperty(DeviceInfoSet,
+                           DeviceInfoData,
+                           SPDRP_LOCATION_INFORMATION);
+    if (Location == NULL)
+        goto fail2;
+
     Result = StringCbPrintf(FriendlyName,
                             MAX_PATH,
-                            TEXT("%s #%s"),
+                            "%s #%s",
                             Description,
                             Location);
     if (!SUCCEEDED(Result))
-        goto fail1;
+        goto fail3;
 
     FriendlyNameLength = (DWORD)(strlen(FriendlyName) + sizeof (TCHAR));
 
@@ -290,15 +344,29 @@ SetFriendlyName(
                                           SPDRP_FRIENDLYNAME,
                                           (PBYTE)FriendlyName,
                                           FriendlyNameLength))
-        goto fail2;
+        goto fail4;
 
     Log("%s", FriendlyName);
 
+    free(Location);
+
+    free(Description);
+
     return TRUE;
 
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+    free(Location);
+
 fail2:
     Log("fail2");
 
+    free(Description);
+
 fail1:
     Error = GetLastError();
 
@@ -386,17 +454,25 @@ fail1:
 
 static PETHERNET_ADDRESS
 GetPermanentAddress(
-    IN  PTCHAR          Location
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData
     )
 {
-    HRESULT             Error;
-    HKEY                AddressesKey;
-    DWORD               MaxValueLength;
-    DWORD               BufferLength;
-    PTCHAR              Buffer;
-    DWORD               Type;
-    BOOLEAN             Success;
-    PETHERNET_ADDRESS   Address;
+    PTCHAR                  Location;
+    HRESULT                 Error;
+    HKEY                    AddressesKey;
+    DWORD                   MaxValueLength;
+    DWORD                   BufferLength;
+    PTCHAR                  Buffer;
+    DWORD                   Type;
+    BOOLEAN                 Success;
+    PETHERNET_ADDRESS       Address;
+
+    Location = GetProperty(DeviceInfoSet,
+                           DeviceInfoData,
+                           SPDRP_LOCATION_INFORMATION);
+    if (Location == NULL)
+        goto fail1;
 
     Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                          ADDRESSES_KEY(XENVIF),
@@ -405,7 +481,7 @@ GetPermanentAddress(
                          &AddressesKey);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
-        goto fail1;
+        goto fail2;
     }
 
     Error = RegQueryInfoKey(AddressesKey,
@@ -422,14 +498,14 @@ GetPermanentAddress(
                             NULL);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
-        goto fail2;
+        goto fail3;
     }
 
     BufferLength = MaxValueLength + sizeof (TCHAR);
 
     Buffer = malloc(BufferLength);
     if (Buffer == NULL)
-        goto fail3;
+        goto fail4;
 
     memset(Buffer, 0, BufferLength);
 
@@ -441,26 +517,28 @@ GetPermanentAddress(
                             &BufferLength);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
-        goto fail4;
+        goto fail5;
     }
 
     if (Type != REG_SZ) {
         SetLastError(ERROR_BAD_FORMAT);
-        goto fail5;
+        goto fail6;
     }
 
     Address = malloc(sizeof (ETHERNET_ADDRESS));
     if (Address == NULL)
-        goto fail6;
+        goto fail7;
 
     Success = ParseMacAddress(Buffer, Address);
     if (!Success)
-        goto fail7;
+        goto fail8;
 
     free(Buffer);
 
     RegCloseKey(AddressesKey);
 
+    free(Location);
+
     Log("%02X:%02X:%02X:%02X:%02X:%02X",
         Address->Byte[0],
         Address->Byte[1],
@@ -471,29 +549,34 @@ GetPermanentAddress(
 
     return Address;
 
-fail7:
-    Log("fail7");
+fail8:
+    Log("fail8");
 
     free(Address);
 
+fail7:
+    Log("fail7");
+
 fail6:
     Log("fail6");
 
 fail5:
     Log("fail5");
 
+    free(Buffer);
+
 fail4:
     Log("fail4");
 
-    free(Buffer);
-
 fail3:
     Log("fail3");
 
+    RegCloseKey(AddressesKey);
+
 fail2:
     Log("fail2");
 
-    RegCloseKey(AddressesKey);
+    free(Location);
 
 fail1:
     Error = GetLastError();
@@ -581,21 +664,12 @@ OpenClassKey(
     OUT PHKEY       Key
     )
 {   
-    DWORD           KeyLength;
-    PTCHAR          KeyName;
+    TCHAR           KeyName[MAX_PATH];
     HRESULT         Result;
     HRESULT         Error;
 
-    KeyLength = sizeof (CLASS_KEY) +
-                sizeof ("\\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}") +
-                sizeof (TCHAR);
-
-    KeyName = malloc(KeyLength);
-    if (KeyName == NULL)
-        goto fail1;
-
     Result = StringCbPrintf(KeyName,
-                            KeyLength,
+                            MAX_PATH,
                             "%s\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
                             CLASS_KEY,
                             Guid->Data1,
@@ -611,7 +685,7 @@ OpenClassKey(
                             Guid->Data4[7]);
     if (!SUCCEEDED(Result)) {
         SetLastError(ERROR_BUFFER_OVERFLOW);
-        goto fail2;
+        goto fail1;
     }
 
     Log("%s", KeyName);
@@ -623,21 +697,14 @@ OpenClassKey(
                          Key);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
-        goto fail3;
+        goto fail2;
     }
 
-    free(KeyName);
-
     return TRUE;
 
-fail3:
-    Log("fail3");
-
 fail2:
     Log("fail2");
 
-    free(KeyName);
-
 fail1:
     Error = GetLastError();
 
@@ -657,6 +724,7 @@ FindAliasSoftwareKeyName(
     OUT PTCHAR              *Name
     )
 {
+    const GUID              *Guid = &GUID_DEVCLASS_NET;
     BOOLEAN                 Success;
     PNET_LUID               NetLuid;
     HKEY                    NetKey;
@@ -667,12 +735,14 @@ FindAliasSoftwareKeyName(
     PTCHAR                  SubKeyName;
     DWORD                   Index;
     HKEY                    SubKey;
+    DWORD                   NameLength;
+    HRESULT                 Result;
 
     Success = GetNetLuid(Address, &NetLuid);
     if (!Success)
         goto fail1;
 
-    SubKeyName = NULL;
+    *Name = NULL;
 
     if (NetLuid == NULL)
         goto done;
@@ -681,7 +751,7 @@ FindAliasSoftwareKeyName(
         NetLuid->Info.IfType,
         NetLuid->Info.NetLuidIndex);
 
-    Success = OpenClassKey(&GUID_DEVCLASS_NET, &NetKey);
+    Success = OpenClassKey(Guid, &NetKey);
     if (!Success)
         goto fail2;
 
@@ -772,18 +842,52 @@ loop:
     goto fail6;
 
 found:
-    Log("%s", SubKeyName);
-
     RegCloseKey(SubKey);
 
     RegCloseKey(NetKey);
 
     free(NetLuid);
 
+    NameLength = (DWORD)(sizeof ("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\\") +
+                         ((strlen(SubKeyName) + 1) * sizeof (TCHAR)));
+
+    *Name = malloc(NameLength);
+    if (*Name == NULL)
+        goto fail7;
+
+    Result = StringCbPrintf(*Name,
+                            NameLength,
+                            "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%s",
+                            Guid->Data1,
+                            Guid->Data2,
+                            Guid->Data3,
+                            Guid->Data4[0],
+                            Guid->Data4[1],
+                            Guid->Data4[2],
+                            Guid->Data4[3],
+                            Guid->Data4[4],
+                            Guid->Data4[5],
+                            Guid->Data4[6],
+                            Guid->Data4[7],
+                            SubKeyName);
+    if (!SUCCEEDED(Result)) {
+        SetLastError(ERROR_BUFFER_OVERFLOW);
+        goto fail8;
+    }
+
+    Log("%s", *Name);
+
 done:
-    *Name = SubKeyName;
     return TRUE;
 
+fail8:
+    Log("fail8");
+
+    free(*Name);
+
+fail7:
+    Log("fail7");
+
 fail6:
     Log("fail6");
 
@@ -820,25 +924,63 @@ fail1:
 
 static BOOLEAN
 SetAliasSoftwareKeyName(
-    IN  HKEY    SoftwareKey,
-    IN  PTCHAR  Name
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    IN  PTCHAR              Name
     )
 {
-    HRESULT     Error;
+    PTCHAR                  Location;
+    HKEY                    AliasesKey;
+    HRESULT                 Error;
+
+    Location = GetProperty(DeviceInfoSet,
+                           DeviceInfoData,
+                           SPDRP_LOCATION_INFORMATION);
+    if (Location == NULL)
+        goto fail1;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         ALIASES_KEY(XENVIF),
+                         0,
+                         KEY_ALL_ACCESS,
+                         &AliasesKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
 
-    Error = RegSetValueEx(SoftwareKey,
-                          "Alias",
+    if (Name == NULL)
+        Name = "";
+
+    Error = RegSetValueEx(AliasesKey,
+                          Location,
                           0,
                           REG_SZ,
                           (LPBYTE)Name,
                           (DWORD)((strlen(Name) + 1) * sizeof (TCHAR)));
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
-        goto fail1;
+        goto fail3;
     }
 
+    Log("%s", (strlen(Name) == 0) ? "[NONE]" : Name);
+
+    RegCloseKey(AliasesKey);
+
+    free(Location);
+
     return TRUE;
 
+fail3:
+    Log("fail3");
+
+    RegCloseKey(AliasesKey);
+
+fail2:
+    Log("fail2");
+
+    free(Location);
+
 fail1:
     Error = GetLastError();
 
@@ -852,80 +994,164 @@ fail1:
     return FALSE;
 }
 
-static HKEY
-OpenAliasSoftwareKey(
-    IN  PTCHAR  Name
+static BOOLEAN
+GetAliasSoftwareKeyName(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    OUT PTCHAR              *Name
     )
 {
-    BOOLEAN     Success;
-    HKEY        NetKey;
-    HKEY        SoftwareKey;
-    HRESULT     Error;
+    PTCHAR                  Location;
+    HKEY                    AliasesKey;
+    DWORD                   MaxValueLength;
+    DWORD                   NameLength;
+    DWORD                   Type;
+    HRESULT                 Error;
 
-    Success = OpenClassKey(&GUID_DEVCLASS_NET, &NetKey);
-    if (!Success)
+    Location = GetProperty(DeviceInfoSet,
+                           DeviceInfoData,
+                           SPDRP_LOCATION_INFORMATION);
+    if (Location == NULL)
         goto fail1;
 
-    Error = RegOpenKeyEx(NetKey,
-                         Name,
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         ALIASES_KEY(XENVIF),
                          0,
-                         KEY_ALL_ACCESS,
-                         &SoftwareKey);
+                         KEY_READ,
+                         &AliasesKey);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
         goto fail2;
     }
 
-    RegCloseKey(NetKey);
+    Error = RegQueryInfoKey(AliasesKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
 
-    return SoftwareKey;
+    NameLength = MaxValueLength + sizeof (TCHAR);
 
-fail2:
-    Log("fail2");
+    *Name = malloc(NameLength);
+    if (Name == NULL)
+        goto fail4;
 
-    RegCloseKey(NetKey);
+    memset(*Name, 0, NameLength);
 
-fail1:
-    Error = GetLastError();
+    Error = RegQueryValueEx(AliasesKey,
+                            Location,
+                            NULL,
+                            &Type,
+                            (LPBYTE)*Name,
+                            &NameLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail5;
+    }
 
-    {
-        PTCHAR  Message;
-        Message = GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail6;
     }
 
-    return NULL;
-}
+    Log("%s", (strlen(*Name) == 0) ? "[NONE]" : *Name);
 
-static HKEY
-OpenSoftwareKey(
-    IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData
-    )
-{
-    HKEY                    Key;
-    HRESULT                 Error;
+    if (strlen(*Name) == 0) {
+        free(*Name);
+        *Name = NULL;
+    }
 
-    Key = SetupDiOpenDevRegKey(DeviceInfoSet,
-                               DeviceInfoData,
-                               DICS_FLAG_GLOBAL,
-                               0,
-                               DIREG_DRV,
-                               KEY_ALL_ACCESS);
-    if (Key == INVALID_HANDLE_VALUE) {
-        SetLastError(ERROR_PATH_NOT_FOUND);
+    RegCloseKey(AliasesKey);
+
+    free(Location);
+
+    return TRUE;
+
+fail6:
+    Log("fail6");
+
+fail5:
+    Log("fail5");
+
+    free(*Name);
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+    RegCloseKey(AliasesKey);
+
+fail2:
+    Log("fail2");
+
+    free(Location);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static HKEY
+OpenAliasSoftwareKey(
+    IN  PTCHAR  Name
+    )
+{
+    HRESULT     Result;
+    TCHAR       KeyName[MAX_PATH];
+    HKEY        Key;
+    HRESULT     Error;
+
+    Result = StringCbPrintf(KeyName,
+                            MAX_PATH,
+                            "%s\\%s",
+                            CLASS_KEY,
+                            Name);
+    if (!SUCCEEDED(Result)) {
+        SetLastError(ERROR_BUFFER_OVERFLOW);
         goto fail1;
     }
 
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         KeyName,
+                         0,
+                         KEY_READ,
+                         &Key);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
     return Key;
 
+fail2:
+    Log("fail2");
+
 fail1:
     Error = GetLastError();
 
     {
         PTCHAR  Message;
-
         Message = GetErrorMessage(Error);
         Log("fail1 (%s)", Message);
         LocalFree(Message);
@@ -981,6 +1207,16 @@ GetInterfaceName(
 
     memset(RootDevice, 0, RootDeviceLength);
 
+    Error = RegQueryValueEx(LinkageKey,
+                            "RootDevice",
+                            NULL,
+                            &Type,
+                            (LPBYTE)RootDevice,
+                            &RootDeviceLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
     Error = RegQueryValueEx(LinkageKey,
                             "RootDevice",
                             NULL,
@@ -1665,214 +1901,308 @@ fail1:
 }
 
 static BOOLEAN
-RequestUnplug(
-    VOID          
-    )
-{
-    return TRUE;
-}
-
-static BOOLEAN
-RequestReboot(
-    IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData
+CopySettingsFromAlias(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PTCHAR                      Name
     )
 {
-    SP_DEVINSTALL_PARAMS    DeviceInstallParams;
-
-    DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
+    HKEY                            Source;
+    HKEY                            Destination;
+    BOOLEAN                         Success;
+    HRESULT                         Error;
 
-    if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
-                                       DeviceInfoData,
-                                       &DeviceInstallParams))
+    Source = OpenAliasSoftwareKey(Name);
+    if (Source == NULL)
         goto fail1;
 
-    DeviceInstallParams.Flags |= DI_NEEDREBOOT;
-
-    Log("Flags = %08x", DeviceInstallParams.Flags);
-
-    if (!SetupDiSetDeviceInstallParams(DeviceInfoSet,
-                                       DeviceInfoData,
-                                       &DeviceInstallParams))
+    Destination = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
+    if (Destination == NULL)
         goto fail2;
 
+    Success = CopySettings(Destination, Source);
+    if (!Success)
+        goto fail3;
+
     return TRUE;
 
-fail2:
-fail1:
-    return FALSE;
-}
+fail3:
+    Log("fail3");
 
-static FORCEINLINE HRESULT
-__DifInstallPreProcess(
-    IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData,
-    IN  PCOINSTALLER_CONTEXT_DATA   Context
-    )
-{
-    HKEY                            SoftwareKey;
-    PTCHAR                          Interface;
-    BOOLEAN                         NeedMigrateSettings;
+    RegCloseKey(Destination);
 
-    Log("====>");
+fail2:
+    Log("fail2");
 
-    SoftwareKey = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
+    RegCloseKey(Source);
 
-    if (SoftwareKey != NULL) {
-        Interface = GetInterfaceName(SoftwareKey);
-        RegCloseKey(SoftwareKey);
-    } else {
-        Interface = NULL;
-    }
+fail1:
+    Error = GetLastError();
 
-    if (Interface != NULL) {
-        free(Interface);
+    {
+        PTCHAR  Message;
 
-        NeedMigrateSettings = FALSE;
-    } else {
-        NeedMigrateSettings = TRUE;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
     }
 
-    Log("NeedMigrateSettings = %s",
-        (NeedMigrateSettings) ? "TRUE" : "FALSE");
-
-    Context->PrivateData = (PVOID)NeedMigrateSettings;
-
-    Log("<====");
-
-    return ERROR_DI_POSTPROCESSING_REQUIRED; 
+    return FALSE;
 }
 
-static FORCEINLINE HRESULT
-__DifInstallPostProcess(
+static BOOLEAN
+CopySettingsToAlias(
+    IN  PTCHAR                      Name,
     IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData,
-    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    IN  PSP_DEVINFO_DATA            DeviceInfoData
     )
 {
-    BOOLEAN                         NeedMigrateSettings;
-    BOOLEAN                         Success;
-    PTCHAR                          Description;
-    PTCHAR                          Location;
-    PETHERNET_ADDRESS               Address;
-    PTCHAR                          Name;
     HKEY                            Source;
     HKEY                            Destination;
+    BOOLEAN                         Success;
     HRESULT                         Error;
 
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
-
-    Log("====>");
-
-    Error = Context->InstallResult;
-    if (Error != NO_ERROR) {
-        SetLastError(Error);
-        goto fail1;
-    }
-
-    NeedMigrateSettings = (BOOLEAN)(ULONG_PTR)Context->PrivateData;
-
-    Description = GetProperty(DeviceInfoSet,
-                              DeviceInfoData,
-                              SPDRP_DEVICEDESC);
-    if (Description == NULL)
-        goto fail2;
-
-    Location = GetProperty(DeviceInfoSet,
-                           DeviceInfoData,
-                           SPDRP_LOCATION_INFORMATION);
-    if (Location == NULL)
-        goto fail3;
-
-    Success = SetFriendlyName(DeviceInfoSet,
-                              DeviceInfoData,
-                              Description,
-                              Location);
-    if (!Success)
-        goto fail4;
-
-    Address = GetPermanentAddress(Location);
-    if (Address == NULL)
-        goto fail5;
-
-    Success = FindAliasSoftwareKeyName(Address, &Name);
-    if (!Success)
-        goto fail6;
-
-    if (Name == NULL || !NeedMigrateSettings)
-        goto done;
-
-    Source = OpenAliasSoftwareKey(Name);
+    Source = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
     if (Source == NULL)
-        goto fail7;
+        goto fail2;
 
-    Destination = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
+    Destination = OpenAliasSoftwareKey(Name);
     if (Destination == NULL)
-        goto fail8;
-
-    Success = SetAliasSoftwareKeyName(Destination, Name);
-    if (!Success)
-        goto fail9;
+        goto fail1;
 
     Success = CopySettings(Destination, Source);
     if (!Success)
-        goto fail10;
+        goto fail3;
 
-    Success = RequestUnplug();
-    if (!Success)
-        goto fail11;
+    return TRUE;
 
-    Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
-    if (!Success)
-        goto fail12;
+fail3:
+    Log("fail3");
 
     RegCloseKey(Destination);
 
+fail2:
+    Log("fail2");
+
     RegCloseKey(Source);
 
-done:
-    if (Name != NULL)
-        free(Name);
+fail1:
+    Error = GetLastError();
 
-    free(Address);
+    {
+        PTCHAR  Message;
 
-    free(Location);
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
 
-    free(Description);
+    return FALSE;
+}
 
-    Log("<====");
+static BOOLEAN
+RequestUnplug(
+    VOID          
+    )
+{
+    HKEY    UnplugKey;
+    HRESULT Error;
 
-    return NO_ERROR;
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         UNPLUG_KEY(XENFILT),
+                         0,
+                         KEY_ALL_ACCESS,
+                         &UnplugKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
 
-fail12:
-    Log("fail12");
+    Error = RegSetValueEx(UnplugKey,
+                          "NICS",
+                          0,
+                          REG_SZ,
+                          (LPBYTE)"XENNET",
+                          (DWORD)sizeof ("XENNET"));
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
 
-fail11:
-    Log("fail11");
+    RegCloseKey(UnplugKey);
 
-fail10:
-    Log("fail10");
+    return TRUE;
 
-fail9:
-    Log("fail9");
+fail2:
+    Log("fail2");
 
-    RegCloseKey(Destination);
+    RegCloseKey(UnplugKey);
 
-fail8:
-    Log("fail8");
+fail1:
+    Error = GetLastError();
 
-    RegCloseKey(Source);
+    {
+        PTCHAR  Message;
 
-fail7:
-    Log("fail7");
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
 
-    free(Name);
+    return FALSE;
+}
 
-fail6:
-    Log("fail6");
+static BOOLEAN
+IncrementServiceCount(
+    OUT PDWORD  Count
+    )
+{
+    HKEY        ServiceKey;
+    DWORD       Value;
+    DWORD       ValueLength;
+    DWORD       Type;
+    HRESULT     Error;
 
-    free(Address);
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         SERVICE_KEY(XENNET),
+                         0,
+                         KEY_ALL_ACCESS,
+                         &ServiceKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    ValueLength = sizeof (DWORD);
+
+    Error = RegQueryValueEx(ServiceKey,
+                            "Count",
+                            NULL,
+                            &Type,
+                            (LPBYTE)&Value,
+                            &ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        if (Error == ERROR_FILE_NOT_FOUND) {
+            Value = 0;
+            goto done;
+        }
+
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    if (Type != REG_DWORD) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail3;
+    }
+
+done:
+    Value++;
+
+    Error = RegSetValueEx(ServiceKey,
+                          "Count",
+                          0,
+                          REG_DWORD,
+                          (LPBYTE)&Value,
+                          ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail4;
+    }
+
+    *Count = Value;
+
+    RegCloseKey(ServiceKey);
+
+    return TRUE;
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(ServiceKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+DecrementServiceCount(
+    OUT PDWORD  Count
+    )
+{
+    HKEY        ServiceKey;
+    DWORD       Value;
+    DWORD       ValueLength;
+    DWORD       Type;
+    HRESULT     Error;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         SERVICE_KEY(XENNET),
+                         0,
+                         KEY_ALL_ACCESS,
+                         &ServiceKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    ValueLength = sizeof (DWORD);
+
+    Error = RegQueryValueEx(ServiceKey,
+                            "Count",
+                            NULL,
+                            &Type,
+                            (LPBYTE)&Value,
+                            &ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    if (Type != REG_DWORD) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail3;
+    }
+
+    if (Value == 0) {
+        SetLastError(ERROR_INVALID_DATA);
+        goto fail4;
+    }
+
+    --Value;
+
+    Error = RegSetValueEx(ServiceKey,
+                          "Count",
+                          0,
+                          REG_DWORD,
+                          (LPBYTE)&Value,
+                          ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail5;
+    }
+
+    *Count = Value;
+
+    RegCloseKey(ServiceKey);
+
+    return TRUE;
 
 fail5:
     Log("fail5");
@@ -1880,12 +2210,230 @@ fail5:
 fail4:
     Log("fail4");
 
-    free(Location);
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(ServiceKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+RequestReboot(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData
+    )
+{
+    SP_DEVINSTALL_PARAMS    DeviceInstallParams;
+
+    DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
+
+    if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
+                                       DeviceInfoData,
+                                       &DeviceInstallParams))
+        goto fail1;
+
+    DeviceInstallParams.Flags |= DI_NEEDREBOOT;
+
+    Log("Flags = %08x", DeviceInstallParams.Flags);
+
+    if (!SetupDiSetDeviceInstallParams(DeviceInfoSet,
+                                       DeviceInfoData,
+                                       &DeviceInstallParams))
+        goto fail2;
+
+    return TRUE;
+
+fail2:
+fail1:
+    return FALSE;
+}
+
+static BOOLEAN
+IsUpgrade(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData
+    )
+{
+    HKEY                    SoftwareKey;
+    PTCHAR                  InterfaceName;
+
+    SoftwareKey = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
+
+    if (SoftwareKey == NULL)
+        return FALSE;
+
+    InterfaceName = GetInterfaceName(SoftwareKey);
+    RegCloseKey(SoftwareKey);
+
+    if (InterfaceName == NULL)
+        return FALSE;
+
+    free(InterfaceName);
+    return TRUE;
+}
+
+static FORCEINLINE HRESULT
+__DifInstallPreProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    PETHERNET_ADDRESS               Address;
+    PTCHAR                          Name;
+    BOOLEAN                         Success;
+    HRESULT                         Error;
+
+    Log("====>");
+
+    if (!IsUpgrade(DeviceInfoSet, DeviceInfoData)) {
+        Log("INITIAL INSTALLATION");
+
+        Address = GetPermanentAddress(DeviceInfoSet, DeviceInfoData);
+        if (Address == NULL)
+            goto fail1;
+
+        Success = FindAliasSoftwareKeyName(Address, &Name);
+        if (!Success)
+            goto fail2;
+
+        Success = SetAliasSoftwareKeyName(DeviceInfoSet,
+                                          DeviceInfoData,
+                                          Name);
+        if (!Success)
+            goto fail3;
+
+        if (Name != NULL)
+            free(Name);
+
+        free(Address);
+
+        Context->PrivateData = (PVOID)FALSE;
+    } else {
+        Log("UPGRADE INSTALLATION");
+
+        Context->PrivateData = (PVOID)TRUE;
+    }
+
+    Log("<====");
+
+    return ERROR_DI_POSTPROCESSING_REQUIRED; 
 
 fail3:
     Log("fail3");
 
-    free(Description);
+    free(Name);
+
+fail2:
+    Log("fail2");
+
+    free(Address);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
+}
+
+static FORCEINLINE HRESULT
+__DifInstallPostProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    BOOLEAN                         Upgrade;
+    BOOLEAN                         Success;
+    PTCHAR                          Name;
+    DWORD                           Count;
+    HRESULT                         Error;
+
+    UNREFERENCED_PARAMETER(DeviceInfoSet);
+    UNREFERENCED_PARAMETER(DeviceInfoData);
+
+    Log("====>");
+
+    Error = Context->InstallResult;
+    if (Error != NO_ERROR) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    Upgrade = (BOOLEAN)(ULONG_PTR)Context->PrivateData;
+
+    if (Upgrade)
+        goto done;
+
+    Success = SetFriendlyName(DeviceInfoSet,
+                              DeviceInfoData);
+    if (!Success)
+        goto fail2;
+
+    Success = GetAliasSoftwareKeyName(DeviceInfoSet,
+                                      DeviceInfoData,
+                                      &Name);
+    if (!Success)
+        goto fail3;
+
+    if (Name != NULL) {
+        Success = CopySettingsFromAlias(DeviceInfoSet,
+                                        DeviceInfoData,
+                                        Name);
+
+        free(Name);
+
+        if (!Success)
+            goto fail4;
+    }
+
+    Success = RequestUnplug();
+    if (!Success)
+        goto fail5;
+
+done:
+    Success = IncrementServiceCount(&Count);
+    if (!Success)
+        goto fail6;
+
+    if (Count == 1)
+        (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
+
+    return NO_ERROR;
+
+fail6:
+    Log("fail6");
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
 
 fail2:
     Log("fail2");
@@ -1950,13 +2498,60 @@ __DifRemovePreProcess(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
+    BOOLEAN                         Success;
+    PTCHAR                          Name;
+    DWORD                           Count;
+    HRESULT                         Error;
+
     UNREFERENCED_PARAMETER(Context);
 
-    Log("<===>");
+    Log("====>");
+
+    Success = GetAliasSoftwareKeyName(DeviceInfoSet,
+                                      DeviceInfoData,
+                                      &Name);
+    if (!Success)
+        goto fail1;
+
+    if (Name != NULL) {
+        Success = CopySettingsToAlias(Name,
+                                      DeviceInfoSet,
+                                      DeviceInfoData);
+
+        free(Name);
+
+        if (!Success)
+            goto fail2;
+    }
+
+    Success = DecrementServiceCount(&Count);
+    if (!Success)
+        goto fail3;    
+
+    Context->PrivateData = (Count == 0) ? (PVOID)TRUE : (PVOID)FALSE;
+
+    Log("<====");
 
     return ERROR_DI_POSTPROCESSING_REQUIRED; 
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
 }
 
 static FORCEINLINE HRESULT
@@ -1966,11 +2561,10 @@ __DifRemovePostProcess(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
+    BOOLEAN                         NeedReboot;
+    BOOLEAN                         Success;
     HRESULT                         Error;
 
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
-
     Log("====>");
 
     Error = Context->InstallResult;
@@ -1979,10 +2573,23 @@ __DifRemovePostProcess(
         goto fail1;
     }
 
+    NeedReboot = (BOOLEAN)(ULONG_PTR)Context->PrivateData;
+
+    if (!NeedReboot)
+        goto done;
+
+    Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
+    if (!Success)
+        goto fail2;
+
+done:
     Log("<====");
 
     return NO_ERROR;
 
+fail2:
+    Log("fail2");
+
 fail1:
     Error = GetLastError();
 
@@ -2079,15 +2686,8 @@ Entry(
             Error = DifInstall(DeviceInfoSet, DeviceInfoData, Context);
         } else {
             if (!Context->PostProcessing) {
-                Log("%s PreProcessing",
-                    FunctionName(Function));
-
                 Error = ERROR_DI_POSTPROCESSING_REQUIRED; 
             } else {
-                Log("%s PostProcessing (%08x)",
-                    FunctionName(Function),
-                    Context->InstallResult);
-
                 Error = NO_ERROR;
             }
         }