From: Owen Smith Date: Thu, 1 Mar 2018 17:21:34 +0000 (+0000) Subject: Hide console access behind an interface X-Git-Tag: 9.0.0-rc1~22 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=277fa6e471b10610a9ee30d4099d0dd2bcb38eb2;p=pvdrivers%2Fwin%2Fxencons.git Hide console access behind an interface * Allows a different implementation of the console protocol for non-default consoles. Signed-off-by: Owen Smith * Re-worked create/destroy and renamed some items. * Left IsDefault as a flag on the Pdo. * Fail to create the PDO in the non-default case. * ASSERT the Pdo is default before attempting to use the ABI, since it is only valid in this case. Signed-off-by: Paul Durrant --- diff --git a/src/xencons/console.c b/src/xencons/console.c index ed1fe53..2e044ae 100644 --- a/src/xencons/console.c +++ b/src/xencons/console.c @@ -53,11 +53,12 @@ typedef struct _CONSOLE_HANDLE { PXENCONS_STREAM Stream; } CONSOLE_HANDLE, *PCONSOLE_HANDLE; -struct _XENCONS_CONSOLE { +typedef struct _XENCONS_CONSOLE { + LONG References; PXENCONS_FDO Fdo; LIST_ENTRY List; KSPIN_LOCK Lock; -}; +} XENCONS_CONSOLE, *PXENCONS_CONSOLE; static FORCEINLINE PVOID __ConsoleAllocate( @@ -169,7 +170,7 @@ fail1: return NULL; } -NTSTATUS +static NTSTATUS ConsoleOpen( IN PXENCONS_CONSOLE Console, IN PFILE_OBJECT FileObject @@ -197,7 +198,7 @@ fail1: return status; } -NTSTATUS +static NTSTATUS ConsoleClose( IN PXENCONS_CONSOLE Console, IN PFILE_OBJECT FileObject @@ -338,7 +339,7 @@ fail1: return status; } -NTSTATUS +static NTSTATUS ConsolePutQueue( IN PXENCONS_CONSOLE Console, IN PIRP Irp @@ -368,7 +369,7 @@ ConsolePutQueue( return status; } -NTSTATUS +static NTSTATUS ConsoleD3ToD0( IN PXENCONS_CONSOLE Console ) @@ -382,7 +383,7 @@ ConsoleD3ToD0( return STATUS_SUCCESS; } -VOID +static VOID ConsoleD0ToD3( IN PXENCONS_CONSOLE Console ) @@ -421,25 +422,134 @@ ConsoleD0ToD3( Trace("<====\n"); } +static NTSTATUS +ConsoleAbiAcquire( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context + ) +{ + PXENCONS_CONSOLE Console = (PXENCONS_CONSOLE)Context; + KIRQL Irql; + + Trace("====>\n"); + + KeAcquireSpinLock(&Console->Lock, &Irql); + + Console->References++; + + KeReleaseSpinLock(&Console->Lock, Irql); + + Trace("<====\n"); + + return STATUS_SUCCESS; +} + +static VOID +ConsoleAbiRelease( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context + ) +{ + PXENCONS_CONSOLE Console = (PXENCONS_CONSOLE)Context; + KIRQL Irql; + + Trace("====>\n"); + + KeAcquireSpinLock(&Console->Lock, &Irql); + + ASSERT(Console->References != 0); + --Console->References; + + KeReleaseSpinLock(&Console->Lock, Irql); + + Trace("<====\n"); +} + +static NTSTATUS +ConsoleAbiD3ToD0( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context + ) +{ + PXENCONS_CONSOLE Console = (PXENCONS_CONSOLE)Context; + + return ConsoleD3ToD0(Console); +} + +static VOID +ConsoleAbiD0ToD3( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context + ) +{ + PXENCONS_CONSOLE Console = (PXENCONS_CONSOLE)Context; + + ConsoleD0ToD3(Console); +} + +static NTSTATUS +ConsoleAbiOpen( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context, + IN PFILE_OBJECT FileObject + ) +{ + PXENCONS_CONSOLE Console = (PXENCONS_CONSOLE)Context; + + return ConsoleOpen(Console, FileObject); +} + +static NTSTATUS +ConsoleAbiClose( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context, + IN PFILE_OBJECT FileObject + ) +{ + PXENCONS_CONSOLE Console = (PXENCONS_CONSOLE)Context; + + return ConsoleClose(Console, FileObject); +} + +static NTSTATUS +ConsoleAbiPutQueue( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context, + IN PIRP Irp + ) +{ + PXENCONS_CONSOLE Console = (PXENCONS_CONSOLE)Context; + + return ConsolePutQueue(Console, Irp); +} + +static XENCONS_CONSOLE_ABI ConsoleAbi = { + NULL, + ConsoleAbiAcquire, + ConsoleAbiRelease, + ConsoleAbiD3ToD0, + ConsoleAbiD0ToD3, + ConsoleAbiOpen, + ConsoleAbiClose, + ConsoleAbiPutQueue +}; + NTSTATUS ConsoleCreate( - IN PXENCONS_FDO Fdo, - OUT PXENCONS_CONSOLE *Console + IN PXENCONS_FDO Fdo, + OUT PXENCONS_CONSOLE_ABI_CONTEXT *Context ) { - NTSTATUS status; + PXENCONS_CONSOLE Console; + NTSTATUS status; Trace("====>\n"); - *Console = __ConsoleAllocate(sizeof(XENCONS_CONSOLE)); + Console = __ConsoleAllocate(sizeof(XENCONS_CONSOLE)); status = STATUS_NO_MEMORY; - if (*Console == NULL) + if (Console == NULL) goto fail1; - (*Console)->Fdo = Fdo; - InitializeListHead(&(*Console)->List); - KeInitializeSpinLock(&(*Console)->Lock); + InitializeListHead(&Console->List); + KeInitializeSpinLock(&Console->Lock); + + Console->Fdo = Fdo; + + *Context = (PVOID)Console; Trace("<====\n"); @@ -451,11 +561,24 @@ fail1: return status; } +VOID +ConsoleGetAbi( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context, + OUT PXENCONS_CONSOLE_ABI Abi + ) +{ + *Abi = ConsoleAbi; + + Abi->Context = Context; +} + VOID ConsoleDestroy( - IN PXENCONS_CONSOLE Console + IN PXENCONS_CONSOLE_ABI_CONTEXT Context ) { + PXENCONS_CONSOLE Console = (PXENCONS_CONSOLE)Context; + Trace("====>\n"); ASSERT(IsListEmpty(&Console->List)); diff --git a/src/xencons/console.h b/src/xencons/console.h index 1094f82..cd00303 100644 --- a/src/xencons/console.h +++ b/src/xencons/console.h @@ -35,46 +35,23 @@ #include #include "driver.h" - -typedef struct _XENCONS_CONSOLE XENCONS_CONSOLE, *PXENCONS_CONSOLE; +#include "console_abi.h" extern NTSTATUS ConsoleCreate( - IN PXENCONS_FDO Fdo, - OUT PXENCONS_CONSOLE *Console - ); - -extern VOID -ConsoleDestroy( - IN PXENCONS_CONSOLE Console - ); - -extern NTSTATUS -ConsoleD3ToD0( - IN PXENCONS_CONSOLE Console - ); - -extern VOID -ConsoleD0ToD3( - IN PXENCONS_CONSOLE Console + IN PXENCONS_FDO Fdo, + OUT PXENCONS_CONSOLE_ABI_CONTEXT *Context ); -extern NTSTATUS -ConsoleOpen( - IN PXENCONS_CONSOLE Console, - IN PFILE_OBJECT FileObject +VOID +ConsoleGetAbi( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context, + OUT PXENCONS_CONSOLE_ABI Abi ); -extern NTSTATUS -ConsoleClose( - IN PXENCONS_CONSOLE Console, - IN PFILE_OBJECT FileObject - ); - -extern NTSTATUS -ConsolePutQueue( - IN PXENCONS_CONSOLE Console, - IN PIRP Irp +VOID +ConsoleDestroy( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context ); #endif // _XENCONS_CONSOLE_H diff --git a/src/xencons/console_abi.h b/src/xencons/console_abi.h new file mode 100644 index 0000000..0b2057d --- /dev/null +++ b/src/xencons/console_abi.h @@ -0,0 +1,93 @@ +/* Copyright (c) Citrix Systems Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, +* with or without modification, are permitted provided +* that the following conditions are met: +* +* * Redistributions of source code must retain the above +* copyright notice, this list of conditions and the +* following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the +* following disclaimer in the documentation and/or other +* materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ + +#ifndef _XENCONS_CONSOLE_ABI_H +#define _XENCONS_CONSOLE_ABI_H + +#include + +#include "driver.h" + +typedef PVOID *PXENCONS_CONSOLE_ABI_CONTEXT; + +typedef NTSTATUS +(*XENCONS_CONSOLE_ABI_ACQUIRE)( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context + ); + +typedef VOID +(*XENCONS_CONSOLE_ABI_RELEASE)( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context + ); + +typedef NTSTATUS +(*XENCONS_CONSOLE_ABI_D3TOD0)( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context + ); + +typedef VOID +(*XENCONS_CONSOLE_ABI_D0TOD3)( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context + ); + +typedef NTSTATUS +(*XENCONS_CONSOLE_ABI_OPEN)( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context, + IN PFILE_OBJECT FileObject + ); + +typedef NTSTATUS +(*XENCONS_CONSOLE_ABI_CLOSE)( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context, + IN PFILE_OBJECT FileObject + ); + +typedef NTSTATUS +(*XENCONS_CONSOLE_ABI_PUT_QUEUE)( + IN PXENCONS_CONSOLE_ABI_CONTEXT Context, + IN PIRP Irp + ); + +typedef struct _XENCONS_CONSOLE_ABI { + PXENCONS_CONSOLE_ABI_CONTEXT Context; + XENCONS_CONSOLE_ABI_ACQUIRE ConsoleAbiAcquire; + XENCONS_CONSOLE_ABI_RELEASE ConsoleAbiRelease; + XENCONS_CONSOLE_ABI_D3TOD0 ConsoleAbiD3ToD0; + XENCONS_CONSOLE_ABI_D0TOD3 ConsoleAbiD0ToD3; + XENCONS_CONSOLE_ABI_OPEN ConsoleAbiOpen; + XENCONS_CONSOLE_ABI_CLOSE ConsoleAbiClose; + XENCONS_CONSOLE_ABI_PUT_QUEUE ConsoleAbiPutQueue; +} XENCONS_CONSOLE_ABI, *PXENCONS_CONSOLE_ABI; + +#define XENCONS_CONSOLE_ABI(_Method, _Abi, ...) \ + (_Abi)->ConsoleAbi ## _Method((_Abi)->Context, __VA_ARGS__) + +#endif // _XENCONS_CONSOLE_ABI_H diff --git a/src/xencons/pdo.c b/src/xencons/pdo.c index 1783c89..6c24376 100644 --- a/src/xencons/pdo.c +++ b/src/xencons/pdo.c @@ -1,33 +1,33 @@ /* Copyright (c) Citrix Systems Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, -* with or without modification, are permitted provided -* that the following conditions are met: -* -* * Redistributions of source code must retain the above -* copyright notice, this list of conditions and the -* following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the -* following disclaimer in the documentation and/or other -* materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -*/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ #define INITGUID 1 @@ -44,6 +44,7 @@ #include "names.h" #include "fdo.h" #include "pdo.h" +#include "console_abi.h" #include "console.h" #include "thread.h" #include "dbg_print.h" @@ -56,23 +57,24 @@ #define MAXTEXTLEN 1024 struct _XENCONS_PDO { - PXENCONS_DX Dx; + PXENCONS_DX Dx; - PXENCONS_THREAD SystemPowerThread; - PIRP SystemPowerIrp; - PXENCONS_THREAD DevicePowerThread; - PIRP DevicePowerIrp; + PXENCONS_THREAD SystemPowerThread; + PIRP SystemPowerIrp; + PXENCONS_THREAD DevicePowerThread; + PIRP DevicePowerIrp; - PXENCONS_FDO Fdo; - BOOLEAN Missing; - const CHAR *Reason; - LONG Eject; + PXENCONS_FDO Fdo; + BOOLEAN Missing; + const CHAR *Reason; + LONG Eject; - XENBUS_SUSPEND_INTERFACE SuspendInterface; - PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate; + XENBUS_SUSPEND_INTERFACE SuspendInterface; + PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate; - BOOLEAN IsDefault; - PXENCONS_CONSOLE Console; + BOOLEAN IsDefault; + PXENCONS_CONSOLE_ABI_CONTEXT Context; + XENCONS_CONSOLE_ABI Abi; }; static FORCEINLINE PVOID @@ -328,7 +330,6 @@ __PdoSetDefault( Pdo->IsDefault = (Device == NULL) ? TRUE : FALSE; } - static FORCEINLINE BOOLEAN __PdoSetEjectRequested( IN PXENCONS_PDO Pdo @@ -476,11 +477,8 @@ PdoD3ToD0( KeLowerIrql(Irql); - if (__PdoIsDefault(Pdo)) - status = ConsoleD3ToD0(Pdo->Console); - else - status = STATUS_SUCCESS; - + ASSERT(__PdoIsDefault(Pdo)); + status = XENCONS_CONSOLE_ABI(D3ToD0, &Pdo->Abi); if (!NT_SUCCESS(status)) goto fail4; @@ -534,8 +532,8 @@ PdoD0ToD3( #pragma prefast(suppress:28123) (VOID) IoSetDeviceInterfaceState(&Pdo->Dx->Link, FALSE); - if (__PdoIsDefault(Pdo)) - ConsoleD0ToD3(Pdo->Console); + ASSERT(__PdoIsDefault(Pdo)); + XENCONS_CONSOLE_ABI(D0ToD3, &Pdo->Abi); KeRaiseIrql(DISPATCH_LEVEL, &Irql); @@ -1729,10 +1727,10 @@ PdoDispatchCreate( StackLocation = IoGetCurrentIrpStackLocation(Irp); - if (__PdoIsDefault(Pdo)) - status = ConsoleOpen(Pdo->Console, StackLocation->FileObject); - else - status = STATUS_SUCCESS; + ASSERT(__PdoIsDefault(Pdo)); + status = XENCONS_CONSOLE_ABI(Open, + &Pdo->Abi, + StackLocation->FileObject); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -1751,10 +1749,10 @@ PdoDispatchCleanup( StackLocation = IoGetCurrentIrpStackLocation(Irp); - if (__PdoIsDefault(Pdo)) - status = ConsoleClose(Pdo->Console, StackLocation->FileObject); - else - status = STATUS_SUCCESS; + ASSERT(__PdoIsDefault(Pdo)); + status = XENCONS_CONSOLE_ABI(Close, + &Pdo->Abi, + StackLocation->FileObject); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -1788,11 +1786,10 @@ PdoDispatchReadWriteControl( { NTSTATUS status; - if (__PdoIsDefault(Pdo)) - status = ConsolePutQueue(Pdo->Console, Irp); - else - status = STATUS_DEVICE_NOT_READY; - + ASSERT(__PdoIsDefault(Pdo)); + status = XENCONS_CONSOLE_ABI(PutQueue, + &Pdo->Abi, + Irp); if (status == STATUS_PENDING) { IoMarkIrpPending(Irp); goto done; @@ -1872,9 +1869,22 @@ PdoResume( IN PXENCONS_PDO Pdo ) { + NTSTATUS status; + Trace("(%s) ====>\n", __PdoGetName(Pdo)); + + ASSERT(__PdoIsDefault(Pdo)); + status = XENCONS_CONSOLE_ABI(Acquire, &Pdo->Abi); + if (!NT_SUCCESS(status)) + goto fail1; + Trace("(%s) <====\n", __PdoGetName(Pdo)); return STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + + return status; } VOID @@ -1883,6 +1893,10 @@ PdoSuspend( ) { Trace("(%s) ====>\n", __PdoGetName(Pdo)); + + ASSERT(__PdoIsDefault(Pdo)); + XENCONS_CONSOLE_ABI(Release, &Pdo->Abi); + Trace("(%s) <====\n", __PdoGetName(Pdo)); } @@ -1942,14 +1956,15 @@ PdoCreate( __PdoSetDefault(Pdo, Device); - if (__PdoIsDefault(Pdo)) - status = ConsoleCreate(Fdo, &Pdo->Console); - else - status = STATUS_SUCCESS; - + status = __PdoIsDefault(Pdo) ? + ConsoleCreate(Fdo, &Pdo->Context) : + STATUS_NOT_SUPPORTED; if (!NT_SUCCESS(status)) goto fail5; + if (__PdoIsDefault(Pdo)) + ConsoleGetAbi(Pdo->Context, &Pdo->Abi); + status = FdoAddPhysicalDeviceObject(Fdo, Pdo); if (!NT_SUCCESS(status)) goto fail6; @@ -1976,10 +1991,10 @@ fail6: (VOID)__PdoClearEjectRequested(Pdo); - if (__PdoIsDefault(Pdo)) - ConsoleDestroy(Pdo->Console); - - Pdo->Console = NULL; + if (__PdoIsDefault(Pdo)) { + RtlZeroMemory(&Pdo->Abi, sizeof(XENCONS_CONSOLE_ABI)); + ConsoleDestroy(Pdo->Context); + } Pdo->IsDefault = FALSE; @@ -2049,10 +2064,10 @@ PdoDestroy( Dx->Pdo = NULL; - if (__PdoIsDefault(Pdo)) - ConsoleDestroy(Pdo->Console); - - Pdo->Console = NULL; + if (__PdoIsDefault(Pdo)) { + RtlZeroMemory(&Pdo->Abi, sizeof(XENCONS_CONSOLE_ABI)); + ConsoleDestroy(Pdo->Context); + } Pdo->IsDefault = FALSE;