#define Log(_Format, ...) \
__Log(__MODULE__ "|" __FUNCTION__ ": " _Format, __VA_ARGS__)
-static PTCHAR
-GetErrorMessage(
+static FORCEINLINE PTCHAR
+__GetErrorMessage(
IN DWORD Error
)
{
return Message;
}
-static const CHAR *
-FunctionName(
+static FORCEINLINE const CHAR *
+__FunctionName(
IN DI_FUNCTION Function
)
{
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
return NULL;
}
-static BOOLEAN
-SetFriendlyName(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData,
- IN WORD DeviceId,
- IN BOOLEAN Active
- )
-{
- TCHAR FriendlyName[MAX_PATH];
- DWORD FriendlyNameLength;
- HRESULT Result;
- HRESULT Error;
-
- Result = StringCbPrintf(FriendlyName,
- MAX_PATH,
- "XenServer PV Bus (%04X) %s",
- DeviceId,
- (Active)? "[ACTIVE]" : "");
- if (!SUCCEEDED(Result))
- goto fail1;
-
- Log("%s", FriendlyName);
-
- FriendlyNameLength = (DWORD)(strlen(FriendlyName) + sizeof (TCHAR));
-
- if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
- DeviceInfoData,
- SPDRP_FRIENDLYNAME,
- (PBYTE)FriendlyName,
- FriendlyNameLength))
- 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
AllowInstall(
VOID
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
PTCHAR DeviceInstance;
PTCHAR ActiveDeviceInstance;
DWORD DeviceId;
- BOOLEAN Active;
BOOLEAN Success;
Log("====>");
goto fail4;
}
- Active = (ActiveDeviceInstance != NULL &&
- strcmp(DeviceInstance, ActiveDeviceInstance) == 0) ?
- TRUE :
- FALSE;
-
- Success = SetFriendlyName(DeviceInfoSet,
- DeviceInfoData,
- (WORD)DeviceId,
- Active);
- if (!Success)
- goto fail5;
-
- if (!Active)
+ if (ActiveDeviceInstance == NULL ||
+ strcmp(DeviceInstance, ActiveDeviceInstance) != 0)
goto done;
Success = InstallFilter(&GUID_DEVCLASS_SYSTEM, "XENFILT");
if (!Success)
- goto fail6;
+ goto fail5;
Success = InstallFilter(&GUID_DEVCLASS_HDC, "XENFILT");
if (!Success)
- goto fail7;
+ goto fail6;
Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
if (!Success)
- goto fail8;
+ goto fail7;
done:
if (ActiveDeviceInstance != NULL)
return NO_ERROR;
-fail8:
- Log("fail8");
-
- (VOID) RemoveFilter(&GUID_DEVCLASS_HDC, "XENFILT");
-
fail7:
Log("fail7");
- (VOID) RemoveFilter(&GUID_DEVCLASS_SYSTEM, "XENFILT");
+ (VOID) RemoveFilter(&GUID_DEVCLASS_HDC, "XENFILT");
fail6:
Log("fail6");
+ (VOID) RemoveFilter(&GUID_DEVCLASS_SYSTEM, "XENFILT");
+
fail5:
Log("fail5");
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
{
PTCHAR Message;
- Message = GetErrorMessage(Error);
+ Message = __GetErrorMessage(Error);
Log("fail1 (%s)", Message);
LocalFree(Message);
}
if (!Context->PostProcessing) {
Log("%s PreProcessing",
- FunctionName(Function));
+ __FunctionName(Function));
} else {
Log("%s PostProcessing (%08x)",
- FunctionName(Function),
+ __FunctionName(Function),
Context->InstallResult);
}
if (!NT_SUCCESS(status))
goto fail4;
- Info->Name[Info->NameLength] = '\0';
+ Info->Name[Info->NameLength / sizeof (WCHAR)] = '\0';
Cursor = wcsrchr(Info->Name, L'\\');
ASSERT(Cursor != NULL);
ErrorControl=%SERVICE_ERROR_NORMAL%
ServiceBinary=%12%\xenfilt.sys
LoadOrderGroup="Boot Bus Extender"
-AddReg = XenFilt_Parameters
+AddReg = XenFilt_Parameters, XenFilt_Unplug
[XenFilt_Parameters]
HKR,"Parameters",,0x00000010
HKR,"Parameters","ACPI\PNP0A03",0x00000000,"DEVICE"
HKR,"Parameters","PCIIDE\IDEChannel",0x00000000,"DISK"
+[XenFilt_Unplug]
+HKR,"Unplug",,0x00000010
+
[XenBus_Inst.CoInstallers]
CopyFiles=CoInst_CopyFiles
AddReg=CoInst_AddReg
)
{
BOOLEAN NeedInvalidate;
+ HANDLE ParametersKey;
+ ULONG Enumerate;
PLIST_ENTRY ListEntry;
ULONG Index;
NeedInvalidate = FALSE;
+ ParametersKey = DriverGetParametersKey();
+
+ if (ParametersKey != NULL) {
+ NTSTATUS status;
+
+ status = RegistryQueryDwordValue(ParametersKey,
+ "Enumerate",
+ &Enumerate);
+ if (!NT_SUCCESS(status))
+ Enumerate = 1;
+ } else {
+ Enumerate = 1;
+ }
+
+ if (Enumerate == 0)
+ goto done;
+
__FdoAcquireMutex(Fdo);
ListEntry = Fdo->Dx->ListEntry.Flink;
__FdoReleaseMutex(Fdo);
+done:
Trace("<====\n");
return NeedInvalidate;
State |= PNP_DEVICE_NOT_DISABLEABLE;
}
+ if (!__FdoIsActive(Fdo)) {
+ Info("%s: not active\n", __FdoGetName(Fdo));
+ State |= PNP_DEVICE_DONT_DISPLAY_IN_UI;
+ }
+
Irp->IoStatus.Information = State;
Irp->IoStatus.Status = STATUS_SUCCESS;
if (NT_SUCCESS(status))
__DriverSetParametersKey(ParametersKey);
- status = RegistryCreateSubKey(ServiceKey,
- "Unplug",
- REG_OPTION_NON_VOLATILE,
- &UnplugKey);
+ status = RegistryOpenSubKey(ServiceKey, "Unplug", KEY_READ, &UnplugKey);
if (!NT_SUCCESS(status))
goto fail3;
FdoDestroy(Fdo);
}
+PXENFILT_EMULATED_INTERFACE
+FdoGetEmulatedInterface(
+ IN PXENFILT_FDO Fdo
+ )
+{
+ return &Fdo->EmulatedInterface;
+}
+
+static FORCEINLINE PXENFILT_UNPLUG_INTERFACE
+__FdoGetUnplugInterface(
+ IN PXENFILT_FDO Fdo
+ )
+{
+ return &Fdo->UnplugInterface;
+}
+
+PXENFILT_UNPLUG_INTERFACE
+FdoGetUnplugInterface(
+ IN PXENFILT_FDO Fdo
+ )
+{
+ return __FdoGetUnplugInterface(Fdo);
+}
+
static FORCEINLINE VOID
__FdoEnumerate(
IN PXENFILT_FDO Fdo,
Error("fail1 (%08x)\n", status);
}
-static FORCEINLINE NTSTATUS
+static FORCEINLINE VOID
__FdoS4ToS3(
- IN PXENFILT_FDO Fdo
+ IN PXENFILT_FDO Fdo
)
{
- KIRQL Irql;
- NTSTATUS status;
+ KIRQL Irql;
+ PXENFILT_UNPLUG_INTERFACE UnplugInterface;
ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemHibernate);
KeRaiseIrql(DISPATCH_LEVEL, &Irql); // Flush out any attempt to use pageable memory
- status = UnplugInitialize(&Fdo->UnplugInterface);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
+ UnplugInterface = __FdoGetUnplugInterface(Fdo);
- KeLowerIrql(Irql);
+ UNPLUG(Acquire, UnplugInterface);
+ UNPLUG(Replay, UnplugInterface);
+ UNPLUG(Release, UnplugInterface);
- Trace("<====\n");
-
- return STATUS_SUCCESS;
-
-fail1:
- Error("fail1 (%08x)\n", status);
+ __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
KeLowerIrql(Irql);
-
- return status;
}
static FORCEINLINE VOID
{
ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemSleeping3);
- UnplugTeardown(&Fdo->UnplugInterface);
-
__FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
}
-PXENFILT_EMULATED_INTERFACE
-FdoGetEmulatedInterface(
- IN PXENFILT_FDO Fdo
- )
-{
- return &Fdo->EmulatedInterface;
-}
-
-PXENFILT_UNPLUG_INTERFACE
-FdoGetUnplugInterface(
- IN PXENFILT_FDO Fdo
- )
-{
- return &Fdo->UnplugInterface;
-}
-
__drv_functionClass(IO_COMPLETION_ROUTINE)
__drv_sameIRQL
static NTSTATUS
__FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
- status = __FdoS4ToS3(Fdo);
- if (!NT_SUCCESS(status))
- goto fail3;
-
+ __FdoS4ToS3(Fdo);
+
__FdoSetSystemPowerState(Fdo, PowerSystemWorking);
__FdoSetDevicePowerState(Fdo, PowerDeviceD0);
return status;
-fail3:
- Error("fail3\n");
-
- __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
-
fail2:
Error("fail2\n");
if (SystemState < PowerSystemHibernate &&
__FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) {
__FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
- (VOID) __FdoS4ToS3(Fdo);
+ __FdoS4ToS3(Fdo);
}
__FdoSetSystemPowerState(Fdo, SystemState);
if (!NT_SUCCESS(status))
goto fail8;
+ status = UnplugInitialize(&Fdo->UnplugInterface);
+ if (!NT_SUCCESS(status))
+ goto fail9;
+
InitializeMutex(&Fdo->Mutex);
InitializeListHead(&Dx->ListEntry);
Fdo->References = 1;
return STATUS_SUCCESS;
+fail9:
+ Error("fail9\n");
+
+ EmulatedTeardown(&Fdo->EmulatedInterface);
+
fail8:
Error("fail8\n");
RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
+ UnplugTeardown(&Fdo->UnplugInterface);
+
EmulatedTeardown(&Fdo->EmulatedInterface);
Fdo->Type = XENFILT_EMULATED_OBJECT_TYPE_INVALID;
static FORCEINLINE NTSTATUS
__UnplugPreamble(
- IN PXENFILT_UNPLUG_CONTEXT Context
+ IN PXENFILT_UNPLUG_CONTEXT Context,
+ IN BOOLEAN Locked
)
{
- KIRQL Irql;
+ KIRQL Irql = PASSIVE_LEVEL;
USHORT Magic;
UCHAR Version;
NTSTATUS status;
- AcquireHighLock(&Context->Lock, &Irql);
+ if (!Locked)
+ AcquireHighLock(&Context->Lock, &Irql);
// See docs/misc/hvm-emulated-unplug.markdown for details of the
// protocol in use here
Magic = READ_PORT_USHORT((PUSHORT)0x10);
+
+ if (Magic == 0xd249) {
+ Context->BlackListed = TRUE;
+ goto done;
+ }
status = STATUS_NOT_SUPPORTED;
if (Magic != 0x49d2)
Context->BlackListed = TRUE;
}
- ReleaseHighLock(&Context->Lock, Irql);
+done:
+ LogPrintf(LOG_LEVEL_WARNING,
+ "UNPLUG: PRE-AMBLE (DRIVERS %s)\n",
+ (Context->BlackListed) ? "BLACKLISTED" : "NOT BLACKLISTED");
- Info("DONE %s\n", (Context->BlackListed) ? "[BLACKLISTED]" : "");
+ if (!Locked)
+ ReleaseHighLock(&Context->Lock, Irql);
return STATUS_SUCCESS;
fail1:
- ReleaseHighLock(&Context->Lock, Irql);
-
Error("fail1 (%08x)\n", status);
+ if (!Locked)
+ ReleaseHighLock(&Context->Lock, Irql);
+
return status;
}
status = RegistryQuerySzValue(UnplugKey,
"DISKS",
&ServiceName);
- if (!NT_SUCCESS(status)) {
- Info("NO PV SERVICE\n");
+ if (!NT_SUCCESS(status))
goto done;
- }
status = RtlStringCbPrintfA(ServiceKeyName,
sizeof (ServiceKeyName),
ServiceKeyName,
KEY_READ,
&ServiceKey);
- if (!NT_SUCCESS(status)) {
- Info("%Z: NO SERVICE KEY\n", ServiceName);
+ if (!NT_SUCCESS(status))
goto done;
- }
status = RegistryQueryDwordValue(ServiceKey,
"Count",
if (!NT_SUCCESS(status))
Count = 0;
- if (Count == 0) {
- Info("%Z: NO SERVICE INSTANCES\n", ServiceName);
+ if (Count == 0)
goto done;
- }
AcquireHighLock(&Context->Lock, &Irql);
ASSERT(!Context->UnpluggedDisks);
WRITE_PORT_USHORT((PUSHORT)0x10, 0x0001);
+
+ LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: DISKS\n");
+
Context->UnpluggedDisks = TRUE;
ReleaseHighLock(&Context->Lock, Irql);
- Info("DONE\n");
-
done:
if (ServiceKey != NULL)
RegistryCloseKey(ServiceKey);
status = RegistryQuerySzValue(UnplugKey,
"NICS",
&ServiceName);
- if (!NT_SUCCESS(status)) {
- Info("NO PV SERVICE\n");
+ if (!NT_SUCCESS(status))
goto done;
- }
status = RtlStringCbPrintfA(ServiceKeyName,
sizeof (ServiceKeyName),
ServiceKeyName,
KEY_READ,
&ServiceKey);
- if (!NT_SUCCESS(status)) {
- Info("%Z: NO SERVICE KEY\n", ServiceName);
+ if (!NT_SUCCESS(status))
goto done;
- }
status = RegistryQueryDwordValue(ServiceKey,
"Count",
if (!NT_SUCCESS(status))
Count = 0;
- if (Count == 0) {
- Info("%Z: NO SERVICE INSTANCES\n", ServiceName);
+ if (Count == 0)
goto done;
- }
AcquireHighLock(&Context->Lock, &Irql);
ASSERT(!Context->UnpluggedNics);
WRITE_PORT_USHORT((PUSHORT)0x10, 0x0002);
+
+ LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: NICS\n");
+
Context->UnpluggedNics = TRUE;
ReleaseHighLock(&Context->Lock, Irql);
- Info("DONE\n");
-
done:
if (ServiceKey != NULL)
RegistryCloseKey(ServiceKey);
)
{
KIRQL Irql;
+ NTSTATUS status;
AcquireHighLock(&Context->Lock, &Irql);
- if (Context->UnpluggedDisks)
+ status = __UnplugPreamble(Context, TRUE);
+ ASSERT(NT_SUCCESS(status));
+
+ if (Context->UnpluggedDisks) {
WRITE_PORT_USHORT((PUSHORT)0x10, 0x0001);
+ LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: DISKS\n");
+ }
- if (Context->UnpluggedNics)
+ if (Context->UnpluggedNics) {
WRITE_PORT_USHORT((PUSHORT)0x10, 0x0002);
+ LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: NICS\n");
+ }
ReleaseHighLock(&Context->Lock, Irql);
}
InitializeHighLock(&Context->Lock);
- status = __UnplugPreamble(Context);
+ status = __UnplugPreamble(Context, FALSE);
if (!NT_SUCCESS(status))
goto fail1;
ASSERT(IsZeroMemory(Context, sizeof (XENFILT_UNPLUG_CONTEXT)));
- Info("DONE\n");
-
done:
RtlZeroMemory(Interface, sizeof (XENFILT_UNPLUG_INTERFACE));