[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 3/4] Remove interface subscriber checks from the co-installer...
...and replace with a scan of child driver software keys to check that the revision number in the MatchingDeviceId value is supported. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- src/coinst/coinst.c | 835 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 510 insertions(+), 325 deletions(-) diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c index 82bd86e..0c0ac61 100644 --- a/src/coinst/coinst.c +++ b/src/coinst/coinst.c @@ -34,17 +34,11 @@ #include <stdio.h> #include <stdlib.h> #include <strsafe.h> - -#include <debug_interface.h> -#include <suspend_interface.h> -#include <evtchn_interface.h> -#include <store_interface.h> -#include <range_set_interface.h> -#include <cache_interface.h> -#include <gnttab_interface.h> -#include <vif_interface.h> +#include <malloc.h> +#include <assert.h> #include <version.h> +#include <revision.h> __user_code; @@ -58,6 +52,13 @@ __user_code; #define UNPLUG_KEY \ SERVICE_KEY(XENFILT) ## "\\Unplug" +#define CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control" + +#define CLASS_KEY \ + CONTROL_KEY ## "\\Class" + +#define ENUM_KEY "SYSTEM\\CurrentControlSet\\Enum" + static VOID #pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024' __Log( @@ -186,79 +187,157 @@ __FunctionName( #undef _NAME } -struct _INTERFACE_ENTRY { - const TCHAR *ProviderName; - const TCHAR *InterfaceName; - DWORD VersionMin; - DWORD VersionMax; -}; +static BOOLEAN +OpenEnumKey( + OUT PHKEY EnumKey + ) +{ + HRESULT Error; -#define DEFINE_INTERFACE_ENTRY(_ProviderName, _InterfaceName) \ - { #_ProviderName, \ - #_InterfaceName, \ - _ProviderName ## _ ## _InterfaceName ## _INTERFACE_VERSION_MIN, \ - _ProviderName ## _ ## _InterfaceName ## _INTERFACE_VERSION_MAX \ + Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + ENUM_KEY, + 0, + KEY_READ, + EnumKey); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail1; } -static struct _INTERFACE_ENTRY InterfaceTable[] = { - DEFINE_INTERFACE_ENTRY(XENVIF, VIF), - { NULL, NULL, 0, 0 } -}; + return TRUE; + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return FALSE; +} static BOOLEAN -SupportInterfaceVersion( - IN PTCHAR ProviderName, - IN PTCHAR InterfaceName, - IN DWORD Version +OpenBusKey( + IN PTCHAR BusKeyName, + OUT PHKEY BusKey ) { - BOOLEAN Supported; - struct _INTERFACE_ENTRY *Entry; - - Supported = FALSE; - SetLastError(ERROR_REVISION_MISMATCH); - - for (Entry = InterfaceTable; Entry->ProviderName != NULL; Entry++) { - if (_stricmp(ProviderName, Entry->ProviderName) == 0 && - _stricmp(InterfaceName, Entry->InterfaceName) == 0 && - Version >= Entry->VersionMin && - Version <= Entry->VersionMax) { - Supported = TRUE; - break; - } + BOOLEAN Success; + HKEY EnumKey; + HRESULT Error; + + Success = OpenEnumKey(&EnumKey); + if (!Success) + goto fail1; + + Error = RegOpenKeyEx(EnumKey, + BusKeyName, + 0, + KEY_READ, + BusKey); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail2; + } + + RegCloseKey(EnumKey); + + return TRUE; + +fail2: + Log("fail2"); + + RegCloseKey(EnumKey); + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); } - Log("%s_%s_INTERFACE VERSION %d %s", - ProviderName, - InterfaceName, - Version, - (Supported) ? "SUPPORTED" : "NOT SUPPORTED"); + return FALSE; +} + +static BOOLEAN +OpenDeviceKey( + IN PTCHAR BusKeyName, + IN PTCHAR DeviceKeyName, + OUT PHKEY DeviceKey + ) +{ + BOOLEAN Success; + HKEY BusKey; + HRESULT Error; + + Success = OpenBusKey(BusKeyName, &BusKey); + if (!Success) + goto fail1; + + Error = RegOpenKeyEx(BusKey, + DeviceKeyName, + 0, + KEY_READ, + DeviceKey); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail2; + } + + RegCloseKey(BusKey); + + return TRUE; + +fail2: + Log("fail2"); + + RegCloseKey(BusKey); + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; - return Supported; + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return FALSE; } static BOOLEAN -SupportSubscriberInterfaces( - IN PTCHAR ProviderName, - IN HKEY SubscriberKey +GetDriverKeyName( + IN HKEY DeviceKey, + OUT PTCHAR *Name ) { - DWORD Values; - DWORD MaxInterfaceNameLength; - DWORD InterfaceNameLength; - PTCHAR InterfaceName; - DWORD Index; HRESULT Error; + DWORD SubKeys; + DWORD MaxSubKeyLength; + DWORD SubKeyLength; + PTCHAR SubKeyName; + DWORD Index; + HKEY SubKey; + PTCHAR DriverKeyName; - Error = RegQueryInfoKey(SubscriberKey, + Error = RegQueryInfoKey(DeviceKey, NULL, NULL, NULL, + &SubKeys, + &MaxSubKeyLength, NULL, NULL, NULL, - &Values, - &MaxInterfaceNameLength, NULL, NULL, NULL); @@ -267,55 +346,92 @@ SupportSubscriberInterfaces( goto fail1; } - if (Values == 0) - goto done; + SubKeyLength = MaxSubKeyLength + sizeof (TCHAR); - MaxInterfaceNameLength += sizeof (TCHAR); - - InterfaceNameLength = MaxInterfaceNameLength; - - InterfaceName = malloc(InterfaceNameLength); - if (InterfaceName == NULL) + SubKeyName = malloc(SubKeyLength); + if (SubKeyName == NULL) goto fail2; - for (Index = 0; Index < Values; Index++) { - DWORD InterfaceNameLength; - DWORD Type; - DWORD Value; - DWORD ValueLength; + SubKey = NULL; + DriverKeyName = NULL; - InterfaceNameLength = MaxInterfaceNameLength; - memset(InterfaceName, 0, InterfaceNameLength); + for (Index = 0; Index < SubKeys; Index++) { + DWORD MaxValueLength; + DWORD DriverKeyNameLength; + DWORD Type; - ValueLength = sizeof (DWORD); + SubKeyLength = MaxSubKeyLength + sizeof (TCHAR); + memset(SubKeyName, 0, SubKeyLength); - Error = RegEnumValue(SubscriberKey, + Error = RegEnumKeyEx(DeviceKey, Index, - (LPTSTR)InterfaceName, - &InterfaceNameLength, + (LPTSTR)SubKeyName, + &SubKeyLength, + NULL, + NULL, NULL, - &Type, - (LPBYTE)&Value, - &ValueLength); + NULL); if (Error != ERROR_SUCCESS) { SetLastError(Error); goto fail3; } - if (Type != REG_DWORD) { - SetLastError(ERROR_BAD_FORMAT); + Error = RegOpenKeyEx(DeviceKey, + 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 fail4; } - if (!SupportInterfaceVersion(ProviderName, - InterfaceName, - Value)) + DriverKeyNameLength = MaxValueLength + sizeof (TCHAR); + + DriverKeyName = calloc(1, DriverKeyNameLength); + if (DriverKeyName == NULL) goto fail5; + + Error = RegQueryValueEx(SubKey, + "Driver", + NULL, + &Type, + (LPBYTE)DriverKeyName, + &DriverKeyNameLength); + if (Error == ERROR_SUCCESS && + Type == REG_SZ) + break; + + free(DriverKeyName); + DriverKeyName = NULL; + + RegCloseKey(SubKey); + SubKey = NULL; } - free(InterfaceName); + Log("%s", (DriverKeyName != NULL) ? DriverKeyName : "none found"); -done: + if (SubKey != NULL) + RegCloseKey(SubKey); + + free(SubKeyName); + + *Name = DriverKeyName; return TRUE; fail5: @@ -324,11 +440,14 @@ fail5: fail4: Log("fail4"); + if (SubKey != NULL) + RegCloseKey(SubKey); + fail3: Log("fail3"); - free(InterfaceName); - + free(SubKeyName); + fail2: Log("fail2"); @@ -347,129 +466,375 @@ fail1: } static BOOLEAN -SupportRegisteredSubscribers( - IN PTCHAR ProviderName +OpenClassKey( + OUT PHKEY ClassKey ) { - TCHAR InterfacesKeyName[MAX_PATH]; - HKEY InterfacesKey; - DWORD SubKeys; - DWORD MaxSubKeyNameLength; - DWORD Index; - DWORD SubKeyNameLength; - PTCHAR SubKeyName; - HKEY SubKey; - HRESULT Result; HRESULT Error; - Result = StringCbPrintf(InterfacesKeyName, - MAX_PATH, - "%s\\%s\\Interfaces", - SERVICES_KEY, - ProviderName); - if (!SUCCEEDED(Result)) { - SetLastError(ERROR_BUFFER_OVERFLOW); + Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + CLASS_KEY, + 0, + KEY_READ, + ClassKey); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); goto fail1; } - Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE, - InterfacesKeyName, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &InterfacesKey, - NULL); + return TRUE; + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return FALSE; +} + +static BOOLEAN +OpenDriverKey( + IN PTCHAR DriverKeyName, + OUT PHKEY DriverKey + ) +{ + BOOLEAN Success; + HKEY ClassKey; + HRESULT Error; + + Success = OpenClassKey(&ClassKey); + if (!Success) + goto fail1; + + Error = RegOpenKeyEx(ClassKey, + DriverKeyName, + 0, + KEY_READ, + DriverKey); if (Error != ERROR_SUCCESS) { SetLastError(Error); goto fail2; } - Error = RegQueryInfoKey(InterfacesKey, + RegCloseKey(ClassKey); + + return TRUE; + +fail2: + Log("fail2"); + + RegCloseKey(ClassKey); + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return FALSE; +} + +#define DEFINE_REVISION(_N, _C, _V) \ + (_N) + +static DWORD DeviceRevision[] = { + DEFINE_REVISION_TABLE +}; + +#undef DEFINE_REVISION + +static BOOLEAN +SupportDeviceID( + IN PTCHAR DeviceID + ) +{ + unsigned int Revision; + int Count; + DWORD Index; + HRESULT Error; + + DeviceID = strrchr(DeviceID, '&'); + assert(DeviceID != NULL); + DeviceID++; + + Count = sscanf_s(DeviceID, + "REV_%8x", + &Revision); + if (Count != 1) { + SetLastError(ERROR_BAD_FORMAT); + goto fail1; + } + + for (Index = 0; Index < ARRAYSIZE(DeviceRevision); Index++) { + if (Revision == DeviceRevision[Index]) + goto found; + } + + SetLastError(ERROR_FILE_NOT_FOUND); + goto fail2; + +found: + Log("%x", Revision); + + return TRUE; + +fail2: + Log("fail2"); + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return FALSE; +} + +static BOOLEAN +GetMatchingDeviceID( + IN HKEY DriverKey, + OUT PTCHAR *MatchingDeviceID + ) +{ + HRESULT Error; + DWORD MaxValueLength; + DWORD MatchingDeviceIDLength; + DWORD Type; + DWORD Index; + + Error = RegQueryInfoKey(DriverKey, + NULL, NULL, NULL, NULL, - &SubKeys, - &MaxSubKeyNameLength, NULL, NULL, NULL, NULL, + &MaxValueLength, NULL, NULL); if (Error != ERROR_SUCCESS) { SetLastError(Error); + goto fail1; + } + + MatchingDeviceIDLength = MaxValueLength + sizeof (TCHAR); + + *MatchingDeviceID = calloc(1, MatchingDeviceIDLength); + if (*MatchingDeviceID == NULL) + goto fail2; + + Error = RegQueryValueEx(DriverKey, + "MatchingDeviceId", + NULL, + &Type, + (LPBYTE)*MatchingDeviceID, + &MatchingDeviceIDLength); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); goto fail3; } - SubKeyNameLength = MaxSubKeyNameLength + sizeof (TCHAR); + if (Type != REG_SZ) { + SetLastError(ERROR_BAD_FORMAT); + goto fail4; + } + + for (Index = 0; Index < strlen(*MatchingDeviceID); Index++) + (*MatchingDeviceID)[Index] = (CHAR)toupper((*MatchingDeviceID)[Index]); + + Log("%s", *MatchingDeviceID); + + return TRUE; + +fail4: + Log("fail4"); + +fail3: + Log("fail3"); + + free(*MatchingDeviceID); + +fail2: + Log("fail2"); + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return FALSE; +} + +static BOOLEAN +SupportChildDrivers( + VOID + ) +{ + BOOLEAN Success; + HKEY XenbusKey; + HRESULT Error; + DWORD SubKeys; + DWORD MaxSubKeyLength; + DWORD SubKeyLength; + PTCHAR SubKeyName; + HKEY DeviceKey; + PTCHAR DriverKeyName; + HKEY DriverKey; + PTCHAR MatchingDeviceID; + DWORD Index; + + Log("====>"); + + Success = OpenBusKey("XENVIF", &XenbusKey); + if (!Success) { + // If there is no key then this must be a fresh installation + if (GetLastError() == ERROR_FILE_NOT_FOUND) + goto done; + + goto fail1; + } + + Error = RegQueryInfoKey(XenbusKey, + NULL, + NULL, + NULL, + &SubKeys, + &MaxSubKeyLength, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail2; + } + + SubKeyLength = MaxSubKeyLength + sizeof (TCHAR); - SubKeyName = malloc(SubKeyNameLength); + SubKeyName = malloc(SubKeyLength); if (SubKeyName == NULL) - goto fail4; + goto fail3; for (Index = 0; Index < SubKeys; Index++) { - SubKeyNameLength = MaxSubKeyNameLength + sizeof (TCHAR); - memset(SubKeyName, 0, SubKeyNameLength); + SubKeyLength = MaxSubKeyLength + sizeof (TCHAR); + memset(SubKeyName, 0, SubKeyLength); - Error = RegEnumKeyEx(InterfacesKey, + Error = RegEnumKeyEx(XenbusKey, Index, (LPTSTR)SubKeyName, - &SubKeyNameLength, + &SubKeyLength, NULL, NULL, NULL, NULL); if (Error != ERROR_SUCCESS) { SetLastError(Error); - goto fail5; + goto fail4; } - Error = RegOpenKeyEx(InterfacesKey, - SubKeyName, - 0, - KEY_READ, - &SubKey); - if (Error != ERROR_SUCCESS) + Success = OpenDeviceKey("XENBUS", SubKeyName, &DeviceKey); + if (!Success) + goto fail5; + + Success = GetDriverKeyName(DeviceKey, &DriverKeyName); + if (!Success) goto fail6; - if (!SupportSubscriberInterfaces(ProviderName, SubKey)) + if (DriverKeyName == NULL) + goto loop; + + Success = OpenDriverKey(DriverKeyName, &DriverKey); + if (!Success) goto fail7; - RegCloseKey(SubKey); + Success = GetMatchingDeviceID(DriverKey, &MatchingDeviceID); + if (!Success) + goto fail8; + + Success = SupportDeviceID(MatchingDeviceID); + if (!Success) + goto fail9; + + free(MatchingDeviceID); + + RegCloseKey(DriverKey); + + free(DriverKeyName); + + loop: + RegCloseKey(DeviceKey); } free(SubKeyName); - RegCloseKey(InterfacesKey); + RegCloseKey(XenbusKey); + +done: + Log("<===="); return TRUE; +fail9: + Log("fail9"); + + free(MatchingDeviceID); + +fail8: + Log("fail8"); + + RegCloseKey(DriverKey); + fail7: Log("fail7"); - RegCloseKey(SubKey); + free(DriverKeyName); fail6: Log("fail6"); + RegCloseKey(DeviceKey); + fail5: Log("fail5"); - free(SubKeyName); - fail4: Log("fail4"); - + + free(SubKeyName); + fail3: Log("fail3"); - RegCloseKey(InterfacesKey); - fail2: Log("fail2"); - + + RegCloseKey(XenbusKey); + fail1: Error = GetLastError(); @@ -749,176 +1114,6 @@ fail1: return FALSE; } -static HKEY -OpenInterfacesKey( - IN PTCHAR ProviderName - ) -{ - HRESULT Result; - TCHAR KeyName[MAX_PATH]; - HKEY Key; - HRESULT Error; - - Result = StringCbPrintf(KeyName, - MAX_PATH, - "%s\\%s\\Interfaces", - SERVICES_KEY, - ProviderName); - if (!SUCCEEDED(Result)) { - SetLastError(ERROR_BUFFER_OVERFLOW); - goto fail1; - } - - Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - KeyName, - 0, - KEY_ALL_ACCESS, - &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); - } - - return NULL; -} - -static BOOLEAN -SubscribeInterface( - IN PTCHAR ProviderName, - IN PTCHAR SubscriberName, - IN PTCHAR InterfaceName, - IN DWORD InterfaceVersion - ) -{ - HKEY Key; - HKEY InterfacesKey; - HRESULT Error; - - InterfacesKey = OpenInterfacesKey(ProviderName); - if (InterfacesKey == NULL) - goto fail1; - - Error = RegCreateKeyEx(InterfacesKey, - SubscriberName, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &Key, - NULL); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail2; - } - - Error = RegSetValueEx(Key, - InterfaceName, - 0, - REG_DWORD, - (const BYTE *)&InterfaceVersion, - sizeof(DWORD)); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail3; - } - - Log("%s: %s_%s_INTERFACE_VERSION %u", - SubscriberName, - ProviderName, - InterfaceName, - InterfaceVersion); - - RegCloseKey(Key); - RegCloseKey(InterfacesKey); - - return TRUE; - -fail3: - RegCloseKey(Key); - -fail2: - RegCloseKey(InterfacesKey); - -fail1: - Error = GetLastError(); - - { - PTCHAR Message; - Message = GetErrorMessage(Error); - Log("fail1 (%s)", Message); - LocalFree(Message); - } - - return FALSE; -} - -#define SUBSCRIBE_INTERFACE(_ProviderName, _SubscriberName, _InterfaceName) \ - do { \ - (VOID) SubscribeInterface(#_ProviderName, \ - #_SubscriberName, \ - #_InterfaceName, \ - _ProviderName ## _ ## _InterfaceName ## _INTERFACE_VERSION_MAX); \ - } while (FALSE); - -static BOOLEAN -UnsubscribeInterfaces( - IN PTCHAR ProviderName, - IN PTCHAR SubscriberName - ) -{ - HKEY InterfacesKey; - HRESULT Error; - - Log("%s: %s", SubscriberName, ProviderName); - - InterfacesKey = OpenInterfacesKey(ProviderName); - if (InterfacesKey == NULL) { - goto fail1; - } - - Error = RegDeleteTree(InterfacesKey, - SubscriberName); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail2; - } - - RegCloseKey(InterfacesKey); - - return TRUE; - -fail2: - RegCloseKey(InterfacesKey); - -fail1: - Error = GetLastError(); - - { - PTCHAR Message; - Message = GetErrorMessage(Error); - Log("fail1 (%s)", Message); - LocalFree(Message); - } - - return FALSE; -} - static HRESULT DifInstallPreProcess( IN HDEVINFO DeviceInfoSet, @@ -935,7 +1130,7 @@ DifInstallPreProcess( Log("====>"); - Success = SupportRegisteredSubscribers("XENVIF"); + Success = SupportChildDrivers(); if (!Success) goto fail1; @@ -970,14 +1165,6 @@ DifInstallPostProcess( Log("====>"); - SUBSCRIBE_INTERFACE(XENBUS, XENVIF, DEBUG); - SUBSCRIBE_INTERFACE(XENBUS, XENVIF, SUSPEND); - SUBSCRIBE_INTERFACE(XENBUS, XENVIF, EVTCHN); - SUBSCRIBE_INTERFACE(XENBUS, XENVIF, STORE); - SUBSCRIBE_INTERFACE(XENBUS, XENVIF, RANGE_SET); - SUBSCRIBE_INTERFACE(XENBUS, XENVIF, CACHE); - SUBSCRIBE_INTERFACE(XENBUS, XENVIF, GNTTAB); - (VOID) InstallUnplugService("NICS", "XENVIF"); Log("<===="); @@ -1056,8 +1243,6 @@ DifRemovePreProcess( (VOID) RemoveUnplugService("NICS", "XENVIF"); - UnsubscribeInterfaces("XENBUS", "XENVIF"); - Log("<===="); return NO_ERROR; -- 2.1.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |