#define SERVICE_KEY(_Driver) \
SERVICES_KEY ## "\\" ## #_Driver
-#define PARAMETERS_KEY(_Driver) \
- SERVICE_KEY(_Driver) ## "\\Parameters"
-
-#define ADDRESSES_KEY \
- SERVICE_KEY(XENVIF) ## "\\Addresses"
-
#define STATUS_KEY \
SERVICE_KEY(XENVIF) ## "\\Status"
-#define ENUM_KEY \
- SERVICE_KEY(XENVIF) ## "\\Enum"
-
-#define UNPLUG_KEY \
- SERVICE_KEY(XENFILT) ## "\\Unplug"
-
-#define CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control"
-
-#define CLASS_KEY \
- CONTROL_KEY ## "\\Class"
-
-#define NSI_KEY \
- CONTROL_KEY ## "\\Nsi"
-
static VOID
#pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024'
__Log(
return FALSE;
}
-static BOOLEAN
-InstallUnplugService(
- IN PTCHAR ClassName,
- IN PTCHAR ServiceName
- )
-{
- HKEY UnplugKey;
- HRESULT Error;
- DWORD Type;
- DWORD OldLength;
- DWORD NewLength;
- PTCHAR ServiceNames;
- ULONG Offset;
-
- Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
- UNPLUG_KEY,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &UnplugKey,
- NULL);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail1;
- }
-
- Error = RegQueryValueEx(UnplugKey,
- ClassName,
- NULL,
- &Type,
- NULL,
- &OldLength);
- if (Error != ERROR_SUCCESS) {
- if (Error == ERROR_FILE_NOT_FOUND) {
- Type = REG_MULTI_SZ;
- OldLength = sizeof (TCHAR);
- } else {
- SetLastError(Error);
- goto fail2;
- }
- }
-
- if (Type != REG_MULTI_SZ) {
- SetLastError(ERROR_BAD_FORMAT);
- goto fail3;
- }
-
- NewLength = OldLength + (DWORD)((strlen(ServiceName) + 1) * sizeof (TCHAR));
-
- ServiceNames = calloc(1, NewLength);
- if (ServiceNames == NULL)
- goto fail4;
-
- Offset = 0;
- if (OldLength != sizeof (TCHAR)) {
- Error = RegQueryValueEx(UnplugKey,
- ClassName,
- NULL,
- &Type,
- (LPBYTE)ServiceNames,
- &OldLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(ERROR_BAD_FORMAT);
- goto fail5;
- }
-
- while (ServiceNames[Offset] != '\0') {
- ULONG ServiceNameLength;
-
- ServiceNameLength = (ULONG)strlen(&ServiceNames[Offset]) / sizeof (TCHAR);
-
- if (_stricmp(&ServiceNames[Offset], ServiceName) == 0) {
- Log("%s already present", ServiceName);
- goto done;
- }
-
- Offset += ServiceNameLength + 1;
- }
- }
-
- memmove(&ServiceNames[Offset], ServiceName, strlen(ServiceName));
- Log("added %s", ServiceName);
-
- Error = RegSetValueEx(UnplugKey,
- ClassName,
- 0,
- REG_MULTI_SZ,
- (LPBYTE)ServiceNames,
- NewLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail6;
- }
-
-done:
- free(ServiceNames);
-
- RegCloseKey(UnplugKey);
-
- return TRUE;
-
-fail6:
- Log("fail5");
-
-fail5:
- Log("fail5");
-
- free(ServiceNames);
-
-fail4:
- Log("fail5");
-
-fail3:
- Log("fail5");
-
-fail2:
- Log("fail5");
-
- RegCloseKey(UnplugKey);
-
-fail1:
- Error = GetLastError();
-
- {
- PTCHAR Message;
-
- Message = __GetErrorMessage(Error);
- Log("fail1 (%s)", Message);
- LocalFree(Message);
- }
-
- return FALSE;
-}
-
-static BOOLEAN
-RemoveUnplugService(
- IN PTCHAR ClassName,
- IN PTCHAR ServiceName
- )
-{
- HKEY UnplugKey;
- HRESULT Error;
- DWORD Type;
- DWORD OldLength;
- DWORD NewLength;
- PTCHAR ServiceNames;
- ULONG Offset;
- ULONG ServiceNameLength;
-
- Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- UNPLUG_KEY,
- 0,
- KEY_ALL_ACCESS,
- &UnplugKey);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail1;
- }
-
- Error = RegQueryValueEx(UnplugKey,
- ClassName,
- NULL,
- &Type,
- NULL,
- &OldLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail2;
- }
-
- if (Type != REG_MULTI_SZ) {
- SetLastError(ERROR_BAD_FORMAT);
- goto fail3;
- }
-
- ServiceNames = calloc(1, OldLength);
- if (ServiceNames == NULL)
- goto fail4;
-
- Error = RegQueryValueEx(UnplugKey,
- ClassName,
- NULL,
- &Type,
- (LPBYTE)ServiceNames,
- &OldLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(ERROR_BAD_FORMAT);
- goto fail5;
- }
-
- Offset = 0;
- ServiceNameLength = 0;
- while (ServiceNames[Offset] != '\0') {
- ServiceNameLength = (ULONG)strlen(&ServiceNames[Offset]) / sizeof (TCHAR);
-
- if (_stricmp(&ServiceNames[Offset], ServiceName) == 0)
- goto remove;
-
- Offset += ServiceNameLength + 1;
- }
-
- goto done;
-
-remove:
- NewLength = OldLength - ((ServiceNameLength + 1) * sizeof (TCHAR));
-
- memmove(&ServiceNames[Offset],
- &ServiceNames[Offset + ServiceNameLength + 1],
- (NewLength - Offset) * sizeof (TCHAR));
-
- Log("removed %s", ServiceName);
-
- Error = RegSetValueEx(UnplugKey,
- ClassName,
- 0,
- REG_MULTI_SZ,
- (LPBYTE)ServiceNames,
- NewLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail6;
- }
-
-done:
- free(ServiceNames);
-
- RegCloseKey(UnplugKey);
-
- return TRUE;
-
-fail6:
- Log("fail6");
-
-fail5:
- Log("fail5");
-
- free(ServiceNames);
-
-fail4:
- Log("fail4");
-
-fail3:
- Log("fail3");
-
-fail2:
- Log("fail2");
-
- RegCloseKey(UnplugKey);
-
-fail1:
- Error = GetLastError();
-
- {
- PTCHAR Message;
-
- Message = __GetErrorMessage(Error);
- Log("fail1 (%s)", Message);
- LocalFree(Message);
- }
-
- 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
-RegisterInterface(
- IN PTCHAR ProviderName,
- IN PTCHAR InterfaceName,
- IN DWORD InterfaceVersion
- )
-{
- HKEY Key;
- HKEY InterfacesKey;
- HRESULT Error;
-
- InterfacesKey = OpenInterfacesKey(ProviderName);
- if (InterfacesKey == NULL)
- goto fail1;
-
- Error = RegCreateKeyEx(InterfacesKey,
- "XENNET",
- 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;
- }
-
- 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;
-}
-
-static BOOLEAN
-DeregisterAllInterfaces(
- IN PTCHAR ProviderName
- )
-{
- HKEY InterfacesKey;
- HRESULT Error;
-
- InterfacesKey = OpenInterfacesKey(ProviderName);
- if (InterfacesKey == NULL) {
- goto fail1;
- }
-
- Error = RegDeleteTree(InterfacesKey,
- "XENNET");
- 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 BOOLEAN
-GetEnumCount(
- OUT PDWORD Count
- )
-{
- HKEY EnumKey;
- HRESULT Error;
- DWORD ValueLength;
- DWORD Value;
- DWORD Type;
-
- Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- ENUM_KEY,
- 0,
- KEY_READ,
- &EnumKey);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail1;
- }
-
- ValueLength = sizeof (Value);
-
- Error = RegQueryValueEx(EnumKey,
- "Count",
- NULL,
- &Type,
- (LPBYTE)&Value,
- &ValueLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail2;
- }
-
- if (Type != REG_DWORD) {
- SetLastError(ERROR_BAD_FORMAT);
- goto fail3;
- }
-
- *Count = Value;
- Log("%u", *Count);
-
- RegCloseKey(EnumKey);
-
- return TRUE;
-
-fail3:
- Log("fail3");
-
-fail2:
- Log("fail2");
-
- RegCloseKey(EnumKey);
-
-fail1:
- Error = GetLastError();
-
- {
- PTCHAR Message;
- Message = __GetErrorMessage(Error);
- Log("fail1 (%s)", Message);
- LocalFree(Message);
- }
-
- return FALSE;
-}
-
static BOOLEAN
CheckStatus(
OUT PBOOLEAN NeedReboot
if (!Success)
goto fail1;
- Success = InstallUnplugService("NICS", "XENNET");
- if (!Success)
- goto fail2;
-
- RegisterInterface("XENVIF", "VIF", XENVIF_VIF_INTERFACE_VERSION_MAX);
- RegisterInterface("XENBUS", "CACHE", XENBUS_CACHE_INTERFACE_VERSION_MAX);
-
NeedReboot = FALSE;
Success = CheckStatus(&NeedReboot);
return NO_ERROR;
-fail2:
- Log("fail2");
-
fail1:
Error = GetLastError();
IN PCOINSTALLER_CONTEXT_DATA Context
)
{
- BOOLEAN Success;
- DWORD Count;
-
UNREFERENCED_PARAMETER(DeviceInfoSet);
UNREFERENCED_PARAMETER(DeviceInfoData);
UNREFERENCED_PARAMETER(Context);
- Log("====>");
-
- Success = GetEnumCount(&Count);
-
- if (Success && Count == 1) {
- (VOID) DeregisterAllInterfaces("XENVIF");
- (VOID) DeregisterAllInterfaces("XENBUS");
- (VOID) RemoveUnplugService("NICS", "XENNET");
- }
-
- Log("<====");
+ Log("<===>");
return NO_ERROR;
}