[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 2/3] Store (IRP_MN_QUERY_DEVICE_TEXT) DeviceTextLocationInformation...
...for active XENBUS instance. When we 'trick' Windows into thinking that the active XENBUS device hasn't moved (should it actually move in the PCI bus topology) we ought to make sure that the location information remains constant as well is the InstanceID. Thus it needs to be sampled and stored in the registry at installation time. Subsequent patches will add the necessary code into XENFILT to pull off the trick. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- src/xenbus/driver.c | 51 ++++++++++-------- src/xenbus/driver.h | 7 +-- src/xenbus/fdo.c | 150 ++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 163 insertions(+), 45 deletions(-) diff --git a/src/xenbus/driver.c b/src/xenbus/driver.c index 0ede4ef..c49a7de 100644 --- a/src/xenbus/driver.c +++ b/src/xenbus/driver.c @@ -306,12 +306,14 @@ DriverRemoveFunctionDeviceObject( NTSTATUS DriverGetActive( - OUT PCHAR DeviceID, - OUT PCHAR InstanceID + IN const CHAR *Key, + OUT PCHAR *Value ) { HANDLE ActiveKey; + CHAR Name[MAXNAMELEN]; PANSI_STRING Ansi; + ULONG Length; NTSTATUS status; Trace("====>\n"); @@ -325,30 +327,25 @@ DriverGetActive( if (!NT_SUCCESS(status)) goto fail1; + status = RtlStringCbPrintfA(Name, MAXNAMELEN, "Active%s", Key); + ASSERT(NT_SUCCESS(status)); + status = RegistryQuerySzValue(ActiveKey, - "ActiveDeviceID", + Name, NULL, &Ansi); if (!NT_SUCCESS(status)) goto fail2; - status = RtlStringCbPrintfA(DeviceID, - MAX_DEVICE_ID_LEN, - "%Z", - &Ansi[0]); - ASSERT(NT_SUCCESS(status)); - - RegistryFreeSzValue(Ansi); + Length = Ansi[0].Length + sizeof (CHAR); + *Value = __AllocatePoolWithTag(PagedPool, Length, 'SUB'); - status = RegistryQuerySzValue(ActiveKey, - "ActiveInstanceID", - NULL, - &Ansi); - if (!NT_SUCCESS(status)) + status = STATUS_NO_MEMORY; + if (*Value == NULL) goto fail3; - status = RtlStringCbPrintfA(InstanceID, - MAX_DEVICE_ID_LEN, + status = RtlStringCbPrintfA(*Value, + Length, "%Z", &Ansi[0]); ASSERT(NT_SUCCESS(status)); @@ -362,8 +359,7 @@ DriverGetActive( return STATUS_SUCCESS; fail3: - if (status != STATUS_OBJECT_NAME_NOT_FOUND) - Error("fail3\n"); + Error("fail3\n"); fail2: if (status != STATUS_OBJECT_NAME_NOT_FOUND) @@ -455,7 +451,8 @@ fail1: NTSTATUS DriverSetActive( IN PCHAR DeviceID, - IN PCHAR InstanceID + IN PCHAR InstanceID, + IN PCHAR LocationInformation ) { HANDLE ActiveKey; @@ -498,7 +495,16 @@ DriverSetActive( if (!NT_SUCCESS(status)) goto fail4; - Info("%s\\%s\n", DeviceID, InstanceID); + RtlInitAnsiString(&Ansi[0], LocationInformation); + + status = RegistryUpdateSzValue(ActiveKey, + "ActiveLocationInformation", + REG_SZ, + Ansi); + if (!NT_SUCCESS(status)) + goto fail5; + + Info("%s\\%s: %s\n", DeviceID, InstanceID, LocationInformation); RegistryCloseKey(ActiveKey); @@ -506,6 +512,9 @@ DriverSetActive( return STATUS_SUCCESS; +fail5: + Error("fail5\n"); + fail4: Error("fail4\n"); diff --git a/src/xenbus/driver.h b/src/xenbus/driver.h index 30f6091..3875b42 100644 --- a/src/xenbus/driver.h +++ b/src/xenbus/driver.h @@ -66,14 +66,15 @@ DriverReleaseMutex( extern NTSTATUS DriverGetActive( - OUT PCHAR DeviceID, - OUT PCHAR InstanceID + IN const CHAR *Key, + OUT PCHAR *Value ); NTSTATUS DriverSetActive( IN PCHAR DeviceID, - IN PCHAR InstanceID + IN PCHAR InstanceID, + IN PCHAR LocationInformation ); NTSTATUS diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index 8ca8f52..2b9c690 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -552,13 +552,15 @@ static NTSTATUS FdoQueryId( IN PXENBUS_FDO Fdo, IN BUS_QUERY_ID_TYPE Type, - OUT PCHAR Id + OUT PCHAR *Id ) { KEVENT Event; IO_STATUS_BLOCK StatusBlock; PIRP Irp; PIO_STACK_LOCATION StackLocation; + PWCHAR Buffer; + ULONG Length; NTSTATUS status; ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); @@ -598,16 +600,110 @@ FdoQueryId( if (!NT_SUCCESS(status)) goto fail2; - status = RtlStringCbPrintfA(Id, - MAXNAMELEN, - "%ws", - (PWCHAR)StatusBlock.Information); + Buffer = (PWCHAR)StatusBlock.Information; + Length = (ULONG)(wcslen(Buffer) + 1) * sizeof (CHAR); + + *Id = __AllocatePoolWithTag(PagedPool, Length, 'SUB'); + + status = STATUS_NO_MEMORY; + if (*Id == NULL) + goto fail3; + + status = RtlStringCbPrintfA(*Id, Length, "%ws", Buffer); ASSERT(NT_SUCCESS(status)); + ExFreePool(Buffer); + + return STATUS_SUCCESS; + +fail3: + Error("fail3\n"); + ExFreePool((PVOID)StatusBlock.Information); +fail2: + Error("fail2\n"); + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + +__drv_requiresIRQL(PASSIVE_LEVEL) +static NTSTATUS +FdoQueryDeviceText( + IN PXENBUS_FDO Fdo, + IN DEVICE_TEXT_TYPE Type, + OUT PCHAR *Text + ) +{ + KEVENT Event; + IO_STATUS_BLOCK StatusBlock; + PIRP Irp; + PIO_STACK_LOCATION StackLocation; + PWCHAR Buffer; + ULONG Length; + NTSTATUS status; + + ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); + + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, + Fdo->LowerDeviceObject, + NULL, + 0, + NULL, + &Event, + &StatusBlock); + + status = STATUS_UNSUCCESSFUL; + if (Irp == NULL) + goto fail1; + + StackLocation = IoGetNextIrpStackLocation(Irp); + StackLocation->MinorFunction = IRP_MN_QUERY_DEVICE_TEXT; + + StackLocation->Parameters.QueryDeviceText.DeviceTextType = Type; + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + if (status == STATUS_PENDING) { + (VOID) KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + status = StatusBlock.Status; + } + + if (!NT_SUCCESS(status)) + goto fail2; + + Buffer = (PWCHAR)StatusBlock.Information; + Length = (ULONG)(wcslen(Buffer) + 1) * sizeof (CHAR); + + *Text = __AllocatePoolWithTag(PagedPool, Length, 'SUB'); + + status = STATUS_NO_MEMORY; + if (*Text == NULL) + goto fail3; + + status = RtlStringCbPrintfA(*Text, Length, "%ws", Buffer); + ASSERT(NT_SUCCESS(status)); + + ExFreePool(Buffer); + return STATUS_SUCCESS; +fail3: + Error("fail3\n"); + + ExFreePool((PVOID)StatusBlock.Information); + fail2: Error("fail2\n"); @@ -622,44 +718,56 @@ FdoSetActive( IN PXENBUS_FDO Fdo ) { - CHAR DeviceID[MAX_DEVICE_ID_LEN]; - CHAR InstanceID[MAX_DEVICE_ID_LEN]; - CHAR ActiveDeviceID[MAX_DEVICE_ID_LEN]; - CHAR ActiveInstanceID[MAX_DEVICE_ID_LEN]; + PCHAR DeviceID; + PCHAR InstanceID; + PCHAR ActiveDeviceID; + PCHAR LocationInformation; NTSTATUS status; status = FdoQueryId(Fdo, BusQueryDeviceID, - DeviceID); + &DeviceID); if (!NT_SUCCESS(status)) goto fail1; status = FdoQueryId(Fdo, BusQueryInstanceID, - InstanceID); + &InstanceID); if (!NT_SUCCESS(status)) goto fail2; - status = DriverGetActive(ActiveDeviceID, - ActiveInstanceID); + status = FdoQueryDeviceText(Fdo, + DeviceTextLocationInformation, + &LocationInformation); + if (!NT_SUCCESS(status)) + goto fail3; + + status = DriverGetActive("DeviceID", &ActiveDeviceID); if (NT_SUCCESS(status)) { - if (_stricmp(DeviceID, ActiveDeviceID) != 0) - goto done; + Fdo->Active = (_stricmp(DeviceID, ActiveDeviceID) == 0) ? TRUE : FALSE; + ExFreePool(ActiveDeviceID); } else { - status = DriverSetActive(DeviceID, - InstanceID); - if (!NT_SUCCESS(status)) - goto done; + status = DriverSetActive(DeviceID, InstanceID, LocationInformation); + if (NT_SUCCESS(status)) + Fdo->Active = TRUE; } - Fdo->Active = TRUE; + ExFreePool(LocationInformation); + ExFreePool(InstanceID); + ExFreePool(DeviceID); -done: return STATUS_SUCCESS; +fail3: + Error("fail3\n"); + + ExFreePool(InstanceID); + fail2: Error("fail2\n"); + ExFreePool(DeviceID); + fail1: Error("fail1 (%08x)\n", status); -- 2.5.3 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |