From: Paul Durrant Date: Mon, 9 Sep 2013 14:02:11 +0000 (+0100) Subject: Update the co-installer to match how we do alias detection in xenvif X-Git-Tag: 8.1.0-rc1~54 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=bfa256bf9dfc149c928eeba9275fab7046dcd851;p=pvdrivers%2Fwin%2Fxennet.git Update the co-installer to match how we do alias detection in xenvif Signed-off-by: Paul Durrant --- diff --git a/build.py b/build.py index b363790..a7b4558 100644 --- 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 diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c index 6d590c1..90bc0b9 100644 --- a/src/coinst/coinst.c +++ b/src/coinst/coinst.c @@ -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; } }