[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |