#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 NSI_KEY \
CONTROL_KEY ## "\\Nsi"
-#define ENUM_KEY "SYSTEM\\CurrentControlSet\\Enum"
-
static VOID
#pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024'
__Log(
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
+ )
+{
+ HKEY StatusKey;
+ HRESULT Error;
+ DWORD ValueLength;
+ DWORD Value;
+ DWORD Type;
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ STATUS_KEY,
+ 0,
+ KEY_READ,
+ &StatusKey);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ ValueLength = sizeof (Value);
+
+ Error = RegQueryValueEx(StatusKey,
+ "NeedReboot",
+ NULL,
+ &Type,
+ (LPBYTE)&Value,
+ &ValueLength);
+ if (Error != ERROR_SUCCESS) {
+ if (Error == ERROR_FILE_NOT_FOUND) {
+ Type = REG_DWORD;
+ Value = 0;
+ } else {
+ SetLastError(Error);
+ goto fail2;
+ }
+ }
+
+ if (Type != REG_DWORD) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail3;
+ }
+
+ *NeedReboot = (Value != 0) ? TRUE : FALSE;
+
+ if (*NeedReboot)
+ Log("NeedReboot");
+
+ RegCloseKey(StatusKey);
+
+ return TRUE;
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(StatusKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+ Message = __GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
static BOOLEAN
RequestReboot(
IN HDEVINFO DeviceInfoSet,
BOOLEAN Success;
ETHERNET_ADDRESS Address;
PTCHAR SoftwareKeyName;
+ BOOLEAN NeedReboot;
HRESULT Error;
UNREFERENCED_PARAMETER(Context);
RegisterInterface("XENVIF", "VIF", XENVIF_VIF_INTERFACE_VERSION_MAX);
RegisterInterface("XENBUS", "CACHE", XENBUS_CACHE_INTERFACE_VERSION_MAX);
- if (SoftwareKeyName != NULL) {
- (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
+ NeedReboot = FALSE;
- free(SoftwareKeyName);
- }
+ Success = CheckStatus(&NeedReboot);
+ if (Success && NeedReboot)
+ (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
Log("<====");
IN PCOINSTALLER_CONTEXT_DATA Context
)
{
+ BOOLEAN Success;
+ DWORD Count;
+
+ UNREFERENCED_PARAMETER(DeviceInfoSet);
+ UNREFERENCED_PARAMETER(DeviceInfoData);
UNREFERENCED_PARAMETER(Context);
Log("====>");
- (VOID) DeregisterAllInterfaces("XENVIF");
- (VOID) DeregisterAllInterfaces("XENBUS");
- (VOID) RemoveUnplugService("NICS", "XENNET");
- (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
+ Success = GetEnumCount(&Count);
+
+ if (Success && Count == 1) {
+ (VOID) DeregisterAllInterfaces("XENVIF");
+ (VOID) DeregisterAllInterfaces("XENBUS");
+ (VOID) RemoveUnplugService("NICS", "XENNET");
+ }
Log("<====");