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

[win-pv-devel] [PATCH] Re-instate code network settings code in the co-installer



This functionality was moved into XENVIF when it transpired that it did not
work with Windows 10. However, attempting to mess with network settings in
a driver has also proved to have problematic corner cases.

This patch re-instates old code but changes the mechnism for acquiring
network settings from an emulated device. Instead of attempting to copy
settings to a new stack binding (which failed on Windows 10 because the
stack binding was not set up), the stack binding of the emulated device is
cloned. This is done in post-install phase if the emulated device is online
(otherwise Windows will refuse to start the PV device) or in pre-install
phase if the emulated device is offline, as is the case when re-installing
XENNET. This appears to work reliably across all variants of Windows.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/coinst/coinst.c | 1624 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 1562 insertions(+), 62 deletions(-)

diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c
index acbb5ff..371414a 100644
--- a/src/coinst/coinst.c
+++ b/src/coinst/coinst.c
@@ -55,6 +55,17 @@ __user_code;
 
 #define SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
 
+#define SERVICE_KEY(_Driver)    \
+        SERVICES_KEY ## "\\" ## #_Driver
+
+#define ADDRESSES_KEY   \
+        SERVICE_KEY(XENVIF) ## "\\Addresses"
+
+#define CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control"
+
+#define CLASS_KEY   \
+        CONTROL_KEY ## "\\Class"
+
 static VOID
 #pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds 
/analyze:stacksize'1024'
 __Log(
@@ -309,35 +320,92 @@ fail1:
     return FALSE;
 }
 
-static FORCEINLINE HRESULT
-__DifInstallPreProcess(
-    IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData,
-    IN  PCOINSTALLER_CONTEXT_DATA   Context
+static BOOLEAN
+OpenSoftwareKey(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    OUT PHKEY               Key
     )
 {
-    HRESULT                         Error;
-    BOOLEAN                         Success;
-    BOOLEAN                         Allow;
+    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;
+    }
 
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
-    UNREFERENCED_PARAMETER(Context);
+    return TRUE;
 
-    Log("====>");
+fail1:
+    Error = GetLastError();
 
-    Success = AllowInstall(&Allow);
-    if (!Success)
-        goto fail1;
+    {
+        PTCHAR  Message;
 
-    if (!Allow) {
-        SetLastError(ERROR_ACCESS_DENIED);
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static PTCHAR
+GetProperty(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    IN  DWORD               Index
+    )
+{
+    DWORD                   Type;
+    DWORD                   PropertyLength;
+    PTCHAR                  Property;
+    HRESULT                 Error;
+
+    if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+                                          DeviceInfoData,
+                                          Index,
+                                          &Type,
+                                          NULL,
+                                          0,
+                                          &PropertyLength)) {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            goto fail1;
+    }
+
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
         goto fail2;
     }
 
-    Log("<====");
+    PropertyLength += sizeof (TCHAR);
+
+    Property = calloc(1, PropertyLength);
+    if (Property == NULL)
+        goto fail3;
+
+    if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+                                          DeviceInfoData,
+                                          Index,
+                                          NULL,
+                                          (PBYTE)Property,
+                                          PropertyLength,
+                                          NULL))
+        goto fail4;
+
+    return Property;
+
+fail4:
+    free(Property);
 
-    return NO_ERROR; 
+fail3:
+    Log("fail3");
 
 fail2:
     Log("fail2");
@@ -353,69 +421,1501 @@ fail1:
         LocalFree(Message);
     }
 
-    return Error;
+    return NULL;
 }
 
-static FORCEINLINE HRESULT
-__DifInstallPostProcess(
-    IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData,
-    IN  PCOINSTALLER_CONTEXT_DATA   Context
+static BOOLEAN
+GetLocation(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    OUT PTCHAR              *Location
     )
 {
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
-    UNREFERENCED_PARAMETER(Context);
+    HRESULT                 Error;
 
-    Log("<===>");
+    *Location = GetProperty(DeviceInfoSet,
+                            DeviceInfoData,
+                            SPDRP_LOCATION_INFORMATION);
+    if (*Location == NULL)
+        goto fail1;
 
-    return NO_ERROR;
+    Log("%s", *Location);
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
 }
 
-static DECLSPEC_NOINLINE HRESULT
-DifInstall(
-    IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData,
-    IN  PCOINSTALLER_CONTEXT_DATA   Context
+static BOOLEAN
+ParseMacAddress(
+    IN  PCHAR               Buffer,
+    OUT PETHERNET_ADDRESS   Address
     )
 {
-    HRESULT                         Error;
+    ULONG                   Length;
+    HRESULT                 Error;
 
-    if (!Context->PostProcessing) {
-        Error = __DifInstallPreProcess(DeviceInfoSet, DeviceInfoData, Context);
-        if (Error == NO_ERROR)
-            Error = ERROR_DI_POSTPROCESSING_REQUIRED; 
-    } else {
-        Error = Context->InstallResult;
-        
-        if (Error == NO_ERROR) {
-            (VOID) __DifInstallPostProcess(DeviceInfoSet, DeviceInfoData, 
Context);
-        } else {
-            PTCHAR  Message;
+    Length = 0;
+    for (;;) {
+        CHAR    Character;
+        UCHAR   Byte;
 
-            Message = __GetErrorMessage(Error);
-            Log("NOT RUNNING (__DifInstallPreProcess Error: %s)", Message);
-            LocalFree(Message);
-        }
+        Character = *Buffer++;
+        if (Character == '\0')
+            break;
+
+        if (Character >= '0' && Character <= '9')
+            Byte = Character - '0';
+        else if (Character >= 'A' && Character <= 'F')
+            Byte = 0x0A + Character - 'A';
+        else if (Character >= 'a' && Character <= 'f')
+            Byte = 0x0A + Character - 'a';
+        else
+            break;
+
+        Byte <<= 4;
+
+        Character = *Buffer++;
+        if (Character == '\0')
+            break;
+
+        if (Character >= '0' && Character <= '9')
+            Byte += Character - '0';
+        else if (Character >= 'A' && Character <= 'F')
+            Byte += 0x0A + Character - 'A';
+        else if (Character >= 'a' && Character <= 'f')
+            Byte += 0x0A + Character - 'a';
+        else
+            break;
+
+        Address->Byte[Length++] = Byte;
+
+        // Skip over any separator
+        if (*Buffer == ':' || *Buffer == '-')
+            Buffer++;
     }
 
-    return Error;
+    if (Length != ETHERNET_ADDRESS_LENGTH) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail1;
+    }
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
 }
 
-static FORCEINLINE HRESULT
-__DifRemovePreProcess(
-    IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData,
-    IN  PCOINSTALLER_CONTEXT_DATA   Context
+static BOOLEAN
+GetPermanentAddress(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    OUT PETHERNET_ADDRESS   Address
     )
 {
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
-    UNREFERENCED_PARAMETER(Context);
+    PTCHAR                  Location;
+    HRESULT                 Error;
+    HKEY                    AddressesKey;
+    DWORD                   MaxValueLength;
+    DWORD                   BufferLength;
+    PTCHAR                  Buffer;
+    DWORD                   Type;
+    BOOLEAN                 Success;
 
-    Log("<===>");
+    Log("====>");
 
-    return NO_ERROR;
+    Success = GetLocation(DeviceInfoSet,
+                          DeviceInfoData,
+                          &Location);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         ADDRESSES_KEY,
+                         0,
+                         KEY_READ,
+                         &AddressesKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    Error = RegQueryInfoKey(AddressesKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
+
+    BufferLength = MaxValueLength + sizeof (TCHAR);
+
+    Buffer = calloc(1, BufferLength);
+    if (Buffer == NULL)
+        goto fail4;
+
+    Error = RegQueryValueEx(AddressesKey,
+                            Location,
+                            NULL,
+                            &Type,
+                            (LPBYTE)Buffer,
+                            &BufferLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail5;
+    }
+
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail6;
+    }
+
+    Success = ParseMacAddress(Buffer, Address);
+    if (!Success)
+        goto fail7;
+
+    free(Buffer);
+
+    RegCloseKey(AddressesKey);
+
+    free(Location);
+
+    Log("%02X:%02X:%02X:%02X:%02X:%02X",
+        Address->Byte[0],
+        Address->Byte[1],
+        Address->Byte[2],
+        Address->Byte[3],
+        Address->Byte[4],
+        Address->Byte[5]);
+
+    Log("<====");
+
+    return TRUE;
+
+fail7:
+    Log("fail7");
+
+fail6:
+    Log("fail6");
+
+fail5:
+    Log("fail5");
+
+    free(Buffer);
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+    RegCloseKey(AddressesKey);
+
+fail2:
+    Log("fail2");
+
+    free(Location);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+GetNetLuid(
+    IN  PETHERNET_ADDRESS   Address,
+    OUT PNET_LUID           *NetLuid
+    )
+{
+    PMIB_IF_TABLE2          Table;
+    DWORD                   Index;
+    PMIB_IF_ROW2            Row;
+    HRESULT                 Error;
+
+    Error = GetIfTable2(&Table);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    for (Index = 0; Index < Table->NumEntries; Index++) {
+        Row = &Table->Table[Index];
+
+        Log("checking %ws (%ws)",
+            Row->Alias,
+            Row->Description);
+
+        if (!Row->InterfaceAndOperStatusFlags.ConnectorPresent)
+            continue;
+
+        if (Row->PhysicalAddressLength != sizeof (ETHERNET_ADDRESS))
+            continue;
+
+        if (memcmp(Row->PermanentPhysicalAddress,
+                   Address,
+                   sizeof (ETHERNET_ADDRESS)) != 0)
+            continue;
+
+        if (Row->OperStatus != IfOperStatusUp)
+            continue;
+
+        goto found;
+    }
+
+    *NetLuid = NULL;
+    goto done;
+
+found:
+    *NetLuid = calloc(1, sizeof (NET_LUID));
+    if (*NetLuid == NULL)
+        goto fail2;
+
+    (*NetLuid)->Value = Row->InterfaceLuid.Value;
+
+    Log("%08x.%08x",
+        (*NetLuid)->Info.IfType,
+        (*NetLuid)->Info.NetLuidIndex);
+
+done:
+    FreeMibTable(Table);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    FreeMibTable(Table);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+OpenClassKey(
+    IN  const GUID  *Guid,
+    OUT PHKEY       Key
+    )
+{
+    TCHAR           KeyName[MAX_PATH];
+    HRESULT         Result;
+    HRESULT         Error;
+
+    Result = StringCbPrintf(KeyName,
+                            MAX_PATH,
+                            
"%s\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+                            CLASS_KEY,
+                            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]);
+    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 TRUE;
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+FindAliasByAddress(
+    IN  PETHERNET_ADDRESS   Address,
+    OUT PTCHAR              *SoftwareKeyName
+    )
+{
+    const GUID              *Guid = &GUID_DEVCLASS_NET;
+    BOOLEAN                 Success;
+    PNET_LUID               NetLuid;
+    HKEY                    NetKey;
+    HRESULT                 Error;
+    DWORD                   SubKeys;
+    DWORD                   MaxSubKeyLength;
+    DWORD                   SubKeyLength;
+    PTCHAR                  SubKeyName;
+    DWORD                   Index;
+    HKEY                    SubKey;
+
+    Log("====>");
+
+    Success = GetNetLuid(Address, &NetLuid);
+    if (!Success)
+        goto fail1;
+
+    *SoftwareKeyName = NULL;
+
+    if (NetLuid == NULL)
+        goto done;
+
+    Success = OpenClassKey(Guid, &NetKey);
+    if (!Success)
+        goto fail2;
+
+    Error = RegQueryInfoKey(NetKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &SubKeys,
+                            &MaxSubKeyLength,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
+
+    SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+
+    SubKeyName = calloc(1, SubKeyLength);
+    if (SubKeyName == NULL)
+        goto fail4;
+
+    for (Index = 0; Index < SubKeys; Index++) {
+        DWORD   Length;
+        DWORD   Type;
+        DWORD   IfType;
+        DWORD   NetLuidIndex;
+
+        SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+        memset(SubKeyName, 0, SubKeyLength);
+
+        Error = RegEnumKeyEx(NetKey,
+                             Index,
+                             (LPTSTR)SubKeyName,
+                             &SubKeyLength,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail5;
+        }
+
+        Error = RegOpenKeyEx(NetKey,
+                             SubKeyName,
+                             0,
+                             KEY_READ,
+                             &SubKey);
+        if (Error != ERROR_SUCCESS)
+            continue;
+
+        Length = sizeof (DWORD);
+        Error = RegQueryValueEx(SubKey,
+                                "*IfType",
+                                NULL,
+                                &Type,
+                                (LPBYTE)&IfType,
+                                &Length);
+        if (Error != ERROR_SUCCESS ||
+            Type != REG_DWORD)
+            goto loop;
+
+        Length = sizeof (DWORD);
+        Error = RegQueryValueEx(SubKey,
+                                "NetLuidIndex",
+                                NULL,
+                                &Type,
+                                (LPBYTE)&NetLuidIndex,
+                                &Length);
+        if (Error != ERROR_SUCCESS ||
+            Type != REG_DWORD)
+            goto loop;
+
+        if (NetLuid->Info.IfType == IfType &&
+            NetLuid->Info.NetLuidIndex == NetLuidIndex) {
+            *SoftwareKeyName = SubKeyName;
+
+            RegCloseKey(SubKey);
+            break;
+        }
+
+loop:
+        RegCloseKey(SubKey);
+    }
+
+    if (*SoftwareKeyName == NULL)
+        free(SubKeyName);
+
+    RegCloseKey(NetKey);
+
+    free(NetLuid);
+
+done:
+    Log("%s", (*SoftwareKeyName == NULL) ? "[NONE]" : *SoftwareKeyName);
+
+    Log("<====");
+
+    return TRUE;
+
+fail5:
+    Log("fail5");
+
+    free(SubKeyName);
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+    RegCloseKey(NetKey);
+
+fail2:
+    Log("fail2");
+
+    free(NetLuid);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+LinkAliasToLocation(
+    IN  PTCHAR  Location,
+    IN  PTCHAR  SoftwareKeyName
+    )
+{
+    const GUID  *Guid = &GUID_DEVCLASS_NET;
+    HKEY        NetKey;
+    HRESULT     Error;
+    HKEY        SoftwareKey;
+    DWORD       LocationLength;
+    BOOLEAN     Success;
+
+    Log("====>");
+
+    Success = OpenClassKey(Guid, &NetKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(NetKey,
+                         SoftwareKeyName,
+                         0,
+                         KEY_ALL_ACCESS,
+                         &SoftwareKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    LocationLength = (DWORD)((strlen(Location) + 1) * sizeof (TCHAR));
+
+    Error = RegSetValueEx(SoftwareKey,
+                          "VIF",
+                          0,
+                          REG_SZ,
+                          (LPBYTE)Location,
+                          LocationLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
+
+    Log("VIF = %s", Location);
+
+    RegCloseKey(SoftwareKey);
+
+    RegCloseKey(NetKey);
+
+    Log("<====");
+
+    return TRUE;
+
+fail3:
+    Log("fail3");
+
+    RegCloseKey(SoftwareKey);
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(NetKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+FindAliasByLocation(
+    IN  PTCHAR  Location,
+    OUT PTCHAR  *SoftwareKeyName
+    )
+{
+    const GUID  *Guid = &GUID_DEVCLASS_NET;
+    BOOLEAN     Success;
+    HKEY        NetKey;
+    HRESULT     Error;
+    DWORD       SubKeys;
+    DWORD       MaxSubKeyLength;
+    DWORD       SubKeyLength;
+    PTCHAR      SubKeyName;
+    DWORD       Index;
+    DWORD       VifLength;
+    PTCHAR      Vif;
+    HKEY        SubKey;
+
+    Log("====>");
+
+    *SoftwareKeyName = NULL;
+
+    Success = OpenClassKey(Guid, &NetKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegQueryInfoKey(NetKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &SubKeys,
+                            &MaxSubKeyLength,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+
+    SubKeyName = calloc(1, SubKeyLength);
+    if (SubKeyName == NULL)
+        goto fail3;
+
+    for (Index = 0; Index < SubKeys; Index++) {
+        DWORD   MaxValueLength;
+        DWORD   Type;
+
+        SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+        memset(SubKeyName, 0, SubKeyLength);
+
+        Error = RegEnumKeyEx(NetKey,
+                             Index,
+                             (LPTSTR)SubKeyName,
+                             &SubKeyLength,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail4;
+        }
+
+        Error = RegOpenKeyEx(NetKey,
+                             SubKeyName,
+                             0,
+                             KEY_READ,
+                             &SubKey);
+        if (Error != ERROR_SUCCESS)
+            continue;
+
+        Error = RegQueryInfoKey(SubKey,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                &MaxValueLength,
+                                NULL,
+                                NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail5;
+        }
+
+        VifLength = MaxValueLength + sizeof (TCHAR);
+
+        Vif = calloc(1, VifLength);
+        if (Vif == NULL)
+            goto fail6;
+
+        Error = RegQueryValueEx(SubKey,
+                                "VIF",
+                                NULL,
+                                &Type,
+                                (LPBYTE)Vif,
+                                &VifLength);
+        if (Error != ERROR_SUCCESS ||
+            Type != REG_SZ)
+            goto loop;
+
+        if (strcmp(Vif, Location) == 0) {
+            *SoftwareKeyName = SubKeyName;
+
+            free(Vif);
+
+            RegCloseKey(SubKey);
+            break;
+        }
+
+loop:
+        free(Vif);
+
+        RegCloseKey(SubKey);
+    }
+
+    if (*SoftwareKeyName == NULL)
+        free(SubKeyName);
+
+    RegCloseKey(NetKey);
+
+    Log("%s", (*SoftwareKeyName == NULL) ? "[NONE]" : *SoftwareKeyName);
+
+    Log("<====");
+
+    return TRUE;
+
+fail6:
+    Log("fail6");
+
+fail5:
+    Log("fail5");
+
+    RegCloseKey(SubKey);
+
+fail4:
+    Log("fail4");
+
+    free(SubKeyName);
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(NetKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+CopyKeyValues(
+    IN  HKEY    DestinationKey,
+    IN  HKEY    SourceKey
+    )
+{
+    HRESULT     Error;
+    DWORD       Values;
+    DWORD       MaxValueNameLength;
+    PTCHAR      ValueName;
+    DWORD       MaxValueLength;
+    LPBYTE      Value;
+    DWORD       Index;
+
+    Error = RegQueryInfoKey(SourceKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &Values,
+                            &MaxValueNameLength,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    if (Values == 0)
+        goto done;
+
+    MaxValueNameLength += sizeof (TCHAR);
+
+    ValueName = calloc(1, MaxValueNameLength);
+    if (ValueName == NULL)
+        goto fail2;
+
+    Value = calloc(1, MaxValueLength);
+    if (Value == NULL)
+        goto fail3;
+
+    for (Index = 0; Index < Values; Index++) {
+        DWORD   ValueNameLength;
+        DWORD   ValueLength;
+        DWORD   Type;
+
+        ValueNameLength = MaxValueNameLength;
+        memset(ValueName, 0, ValueNameLength);
+
+        ValueLength = MaxValueLength;
+        memset(Value, 0, ValueLength);
+
+        Error = RegEnumValue(SourceKey,
+                             Index,
+                             (LPTSTR)ValueName,
+                             &ValueNameLength,
+                             NULL,
+                             &Type,
+                             Value,
+                             &ValueLength);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail4;
+        }
+
+        Error = RegSetValueEx(DestinationKey,
+                              ValueName,
+                              0,
+                              Type,
+                              Value,
+                              ValueLength);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail5;
+        }
+
+        Log("COPIED %s", ValueName);
+    }
+
+    free(Value);
+    free(ValueName);
+
+done:
+    return TRUE;
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+    free(Value);
+
+fail3:
+    Log("fail3");
+
+    free(ValueName);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Log("fail1");
+
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+CopySubKey(
+    IN  HKEY    DestinationKey,
+    IN  HKEY    SourceKey,
+    IN  PTCHAR  SubKeyName
+    )
+{
+    HRESULT     Error;
+    HKEY        DestinationSubKey;
+    HKEY        SourceSubKey;
+
+    Log("====>");
+
+    Log("%s", SubKeyName);
+
+    Error = RegOpenKeyEx(SourceKey,
+                         SubKeyName,
+                         0,
+                         KEY_READ,
+                         &SourceSubKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    Error = RegCreateKeyEx(DestinationKey,
+                           SubKeyName,
+                           0,
+                           NULL,
+                           REG_OPTION_NON_VOLATILE,
+                           KEY_ALL_ACCESS,
+                           NULL,
+                           &DestinationSubKey,
+                           NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    CopyKeyValues(DestinationSubKey, SourceSubKey);
+
+    RegCloseKey(DestinationSubKey);
+    RegCloseKey(SourceSubKey);
+
+    Log("<====");
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(SourceSubKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+CopyValue(
+    IN  HKEY    DestinationKey,
+    IN  HKEY    SourceKey,
+    IN  PTCHAR  ValueName
+    )
+{
+    HRESULT     Error;
+    DWORD       MaxValueLength;
+    LPBYTE      Value;
+    DWORD       ValueLength;
+    DWORD       Type;
+
+    Log("====>");
+
+    Error = RegQueryInfoKey(SourceKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    ValueLength = MaxValueLength;
+
+    Value = calloc(1, ValueLength);
+    if (Value == NULL)
+        goto fail2;
+
+    memset(Value, 0, ValueLength);
+
+    Error = RegQueryValueEx(SourceKey,
+                            ValueName,
+                            NULL,
+                            &Type,
+                            (LPBYTE)Value,
+                            &ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
+
+    Error = RegSetValueEx(DestinationKey,
+                          ValueName,
+                          0,
+                          Type,
+                          Value,
+                          ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail4;
+    }
+
+    Log("COPIED %s", ValueName);
+
+    free(Value);
+
+    Log("<====");
+
+    return TRUE;
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+    free(Value);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Log("fail1");
+
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+StealLinkageFromAlias(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    IN  PTCHAR              SoftwareKeyName
+    )
+{
+    const GUID              *Guid = &GUID_DEVCLASS_NET;
+    BOOLEAN                 Success;
+    HKEY                    NetKey;
+    HRESULT                 Error;
+    HKEY                    SourceKey;
+    HKEY                    DestinationKey;
+
+    Log("====>");
+
+    Success = OpenClassKey(Guid, &NetKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(NetKey,
+                         SoftwareKeyName,
+                         0,
+                         KEY_ALL_ACCESS,
+                         &SourceKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    Success = OpenSoftwareKey(DeviceInfoSet,
+                              DeviceInfoData,
+                              &DestinationKey);
+    if (!Success)
+        goto fail3;
+
+    Success = CopyValue(DestinationKey,
+                        SourceKey,
+                        "NetCfgInstanceID");
+    if (!Success)
+        goto fail4;
+
+    Success = CopyValue(DestinationKey,
+                        SourceKey,
+                        "NetLuidIndex");
+    if (!Success)
+        goto fail5;
+
+    Success = CopySubKey(DestinationKey,
+                         SourceKey,
+                         "Linkage");
+    if (!Success)
+        goto fail6;
+
+    RegCloseKey(DestinationKey);
+
+    RegCloseKey(SourceKey);
+
+    RegCloseKey(NetKey);
+
+    Log("<====");
+
+    return TRUE;
+
+fail6:
+    Log("fail6");
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+    RegCloseKey(DestinationKey);
+
+fail3:
+    Log("fail3");
+
+    RegCloseKey(SourceKey);
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(NetKey);
+
+fail1:
+    Log("fail1");
+
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+ClearStolenLinkage(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData
+    )
+{
+    BOOLEAN                 Success;
+    HKEY                    SoftwareKey;
+    HRESULT                 Error;
+
+    Log("====>");
+
+    Success = OpenSoftwareKey(DeviceInfoSet,
+                              DeviceInfoData,
+                              &SoftwareKey);
+    if (!Success)
+        goto fail1;
+
+    (VOID) RegDeleteKey(SoftwareKey, "Linkage");
+    (VOID) RegDeleteValue(SoftwareKey, "NetLuidIndex");
+    (VOID) RegDeleteValue(SoftwareKey, "NetCfgInstanceID");
+
+    RegCloseKey(SoftwareKey);
+
+    Log("<====");
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static FORCEINLINE HRESULT
+__DifInstallPreProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    HRESULT                         Error;
+    BOOLEAN                         Success;
+    BOOLEAN                         Allow;
+    ETHERNET_ADDRESS                Address;
+    PTCHAR                          Location;
+    PTCHAR                          SoftwareKeyName;
+
+    Log("====>");
+
+    Context->PrivateData = NULL;
+
+    Success = AllowInstall(&Allow);
+    if (!Success)
+        goto fail1;
+
+    if (!Allow) {
+        SetLastError(ERROR_ACCESS_DENIED);
+        goto fail2;
+    }
+
+    Location = NULL;
+
+    Success = GetLocation(DeviceInfoSet,
+                          DeviceInfoData,
+                          &Location);
+    if (!Success)
+        goto fail3;
+
+    Success = GetPermanentAddress(DeviceInfoSet,
+                                  DeviceInfoData,
+                                  &Address);
+    if (!Success)
+        goto fail4;
+
+    SoftwareKeyName = NULL;
+
+    Success = FindAliasByAddress(&Address,
+                                 &SoftwareKeyName);
+    if (!Success)
+        goto fail5;
+
+    if (SoftwareKeyName != NULL) {
+        Success = LinkAliasToLocation(Location,
+                                      SoftwareKeyName);
+
+        free(SoftwareKeyName);
+
+        if (!Success)
+            goto fail6;
+
+        Context->PrivateData = (PVOID)TRUE;
+        goto done;
+    }
+
+    SoftwareKeyName = NULL;
+
+    Success = FindAliasByLocation(Location,
+                                  &SoftwareKeyName);
+    if (!Success)
+        goto fail7;
+
+    if (SoftwareKeyName != NULL) {
+        Success = StealLinkageFromAlias(DeviceInfoSet,
+                                        DeviceInfoData,
+                                        SoftwareKeyName);
+
+        free(SoftwareKeyName);
+
+        if (!Success)
+            goto fail8;
+    }
+
+done:
+    Log("<====");
+
+    return NO_ERROR;
+
+fail8:
+    Log("fail8");
+
+fail7:
+    Log("fail7");
+
+fail6:
+    Log("fail6");
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+    free(Location);
+
+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
+__DifInstallPostProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    HRESULT                         Error;
+    BOOLEAN                         Success;
+    PTCHAR                          Location;
+    PTCHAR                          SoftwareKeyName;
+
+    Log("====>");
+
+    if (Context->PrivateData == NULL)
+        goto done;
+
+    Location = NULL;
+
+    Success = GetLocation(DeviceInfoSet,
+                          DeviceInfoData,
+                          &Location);
+    if (!Success)
+        goto fail1;
+
+    SoftwareKeyName = NULL;
+
+    Success = FindAliasByLocation(Location,
+                                  &SoftwareKeyName);
+    if (!Success)
+        goto fail2;
+
+    if (SoftwareKeyName != NULL) {
+        Success = StealLinkageFromAlias(DeviceInfoSet,
+                                        DeviceInfoData,
+                                        SoftwareKeyName);
+
+        free(SoftwareKeyName);
+
+        if (!Success)
+            goto fail3;
+    }
+
+done:
+    Log("<====");
+
+    return NO_ERROR;
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+    free(Location);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
+}
+
+static DECLSPEC_NOINLINE HRESULT
+DifInstall(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    HRESULT                         Error;
+
+    if (!Context->PostProcessing) {
+        Error = __DifInstallPreProcess(DeviceInfoSet, DeviceInfoData, Context);
+        if (Error == NO_ERROR)
+            Error = ERROR_DI_POSTPROCESSING_REQUIRED;
+    } else {
+        Error = Context->InstallResult;
+
+        if (Error == NO_ERROR) {
+            (VOID) __DifInstallPostProcess(DeviceInfoSet, DeviceInfoData, 
Context);
+        } else {
+            PTCHAR  Message;
+
+            Message = __GetErrorMessage(Error);
+            Log("NOT RUNNING (__DifInstallPreProcess Error: %s)", Message);
+            LocalFree(Message);
+        }
+    }
+
+    return Error;
+}
+
+static FORCEINLINE HRESULT
+__DifRemovePreProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    HRESULT                         Error;
+    BOOLEAN                         Success;
+    PTCHAR                          Location;
+    PTCHAR                          SoftwareKeyName;
+
+    UNREFERENCED_PARAMETER(Context);
+
+    Log("====>");
+
+    Location = NULL;
+
+    Success = GetLocation(DeviceInfoSet,
+                          DeviceInfoData,
+                          &Location);
+    if (!Success)
+        goto fail1;
+
+    SoftwareKeyName = NULL;
+
+    Success = FindAliasByLocation(Location,
+                                  &SoftwareKeyName);
+
+    if (!Success)
+        goto fail2;
+
+    if (SoftwareKeyName != NULL) {
+        free(SoftwareKeyName);
+
+        (VOID) ClearStolenLinkage(DeviceInfoSet,
+                                  DeviceInfoData);
+    }
+
+    Log("<====");
+
+    return NO_ERROR;
+
+fail2:
+    Log("fail2");
+
+    free(Location);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
 }
 
 static FORCEINLINE HRESULT
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

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