Files
yttrium-virtio-gpu/vioinput/sys/Array.c
T
Ladi Prosek e36be0711e vioinput: Don't fail driver init if no input device was found
Before this commit the driver failed to load if it didn't create
a HID report descriptor for at least one device. The host evdev
device connected to the VM may be arbitrarily obscure and not being
able to drive it should not be an error condition.

In general, virtio-input is a best-effort driver. It ignores what
it doesn't understand, which includes ignoring everything if the
evdev device description doesn't make sense.

Signed-off-by: Ladi Prosek <[email protected]>
2017-05-09 11:38:30 +02:00

116 lines
2.7 KiB
C

/**********************************************************************
* Copyright (c) 2016-2017 Red Hat, Inc.
*
* File: Array.c
*
* Author(s):
* Ladi Prosek <[email protected]>
*
* Simple dynamic array implementation
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
**********************************************************************/
#include "precomp.h"
#include "vioinput.h"
#if defined(EVENT_TRACING)
#include "Array.tmh"
#endif
BOOLEAN DynamicArrayReserve(PDYNAMIC_ARRAY pArray, SIZE_T cbSize)
{
if (pArray->Ptr == (PVOID)-1)
{
// an allocation has failed before, this array is no good
return FALSE;
}
if (pArray->Ptr == NULL)
{
// initial allocation
pArray->Size = 0;
pArray->MaxSize = cbSize;
pArray->Ptr = ExAllocatePoolWithTag(
NonPagedPool,
pArray->MaxSize,
VIOINPUT_DRIVER_MEMORY_TAG);
if (pArray->Ptr == NULL)
{
// mark as failed
pArray->Ptr = (PVOID)-1;
return FALSE;
}
}
if (cbSize > pArray->MaxSize)
{
// resize needed
PVOID OldPtr = pArray->Ptr;
while (cbSize > pArray->MaxSize)
{
pArray->MaxSize *= 2;
}
pArray->Ptr = ExAllocatePoolWithTag(
NonPagedPool,
pArray->MaxSize,
VIOINPUT_DRIVER_MEMORY_TAG);
if (pArray->Ptr == NULL)
{
// mark as failed
pArray->Ptr = (PVOID)-1;
return FALSE;
}
RtlCopyMemory(pArray->Ptr, OldPtr, pArray->Size);
ExFreePoolWithTag(OldPtr, VIOINPUT_DRIVER_MEMORY_TAG);
}
return TRUE;
}
BOOLEAN DynamicArrayAppend(PDYNAMIC_ARRAY pArray, PVOID pData, SIZE_T cbLength)
{
if (DynamicArrayReserve(pArray, pArray->Size + cbLength))
{
RtlCopyBytes((PUCHAR)pArray->Ptr + pArray->Size, pData, cbLength);
pArray->Size += cbLength;
return TRUE;
}
return FALSE;
}
VOID DynamicArrayDestroy(PDYNAMIC_ARRAY pArray)
{
if (pArray->Ptr != NULL && pArray->Ptr != (PVOID)-1)
{
ExFreePoolWithTag(pArray->Ptr, VIOINPUT_DRIVER_MEMORY_TAG);
pArray->Ptr = NULL;
}
}
BOOLEAN DynamicArrayIsEmpty(PDYNAMIC_ARRAY pArray)
{
return (pArray->Ptr == NULL || pArray->Size == 0);
}
PVOID DynamicArrayGet(PDYNAMIC_ARRAY pArray, SIZE_T *pcbSize)
{
PVOID Ptr = pArray->Ptr;
if (Ptr == NULL || Ptr == (PVOID)-1)
{
if (pcbSize)
{
*pcbSize = 0;
}
return NULL;
}
if (pcbSize)
{
*pcbSize = pArray->Size;
}
// transferring ownership of the array to the caller
pArray->Ptr = NULL;
return Ptr;
}