HGSMICommon.cpp revision c58f1213e628a545081c70e26c6b67a841cff880
/* $Id$ */
/** @file
* VBox Host Guest Shared Memory Interface (HGSMI) - Functions common to both host and guest.
*/
/*
* Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#define LOG_DISABLED /* Maybe we can enabled it all the time now? */
#define LOG_GROUP LOG_GROUP_HGSMI
/* Channel flags. */
#define HGSMI_CH_F_REGISTERED 0x01
/* Assertions for situations which could happen and normally must be processed properly
* but must be investigated during development: guest misbehaving, etc.
*/
#ifdef HGSMI_STRICT
#define HGSMI_STRICT_ASSERT_FAILED() AssertFailed()
#else
#define HGSMI_STRICT_ASSERT_FAILED() do {} while (0)
#define HGSMI_STRICT_ASSERT(expr) do {} while (0)
#endif /* !HGSMI_STRICT */
/* One-at-a-Time Hash from
*
* ub4 one_at_a_time(char *key, ub4 len)
* {
* ub4 hash, i;
* for (hash=0, i=0; i<len; ++i)
* {
* hash += key[i];
* hash += (hash << 10);
* hash ^= (hash >> 6);
* }
* hash += (hash << 3);
* hash ^= (hash >> 11);
* hash += (hash << 15);
* return hash;
* }
*/
static uint32_t hgsmiHashBegin (void)
{
return 0;
}
const void *pvData,
{
while (cbData--)
{
}
return hash;
}
{
return hash;
}
const HGSMIBUFFERHEADER *pHeader,
const HGSMIBUFFERTAIL *pTail)
{
return hgsmiHashEnd (u32Checksum);
}
{
if ( !pArea
|| !pHeader)
{
return HGSMIOFFSET_VOID;
}
/* Buffer must be within the area:
* * header data size do not exceed the maximum data size;
* * buffer address is greater than the area base address;
* * buffer address is lower than the maximum allowed for the given data size.
*/
if ( u32DataSize > cbMaximumDataSize
{
return HGSMIOFFSET_VOID;
}
pTail->u32Reserved = 0;
return offBuffer;
}
{
if ( !pArea /* Check that the area: */
|| offBase > UINT32_C(0xFFFFFFFF) - cbArea /* Area within the 32 bit space: offBase + cbMem <= 0xFFFFFFFF */
)
{
return VERR_INVALID_PARAMETER;
}
return VINF_SUCCESS;
}
{
if (pArea)
{
}
}
/* Initialize the memory buffer including its checksum.
* No changes alloed to the header and the tail after that.
*/
{
if (cbBuffer < HGSMIBufferMinimumSize ())
{
return HGSMIOFFSET_VOID;
}
return hgsmiBufferInitializeSingle (pArea, pHeader, cbBuffer - HGSMIBufferMinimumSize (), u8Channel, u16ChannelInfo);
}
{
pHeap->fOffsetBased = false;
}
{
}
void *pvBase,
bool fOffsetBased
)
{
if ( !pHeap
|| !pvBase)
{
return VERR_INVALID_PARAMETER;
}
if (RT_SUCCESS (rc))
{
if (fOffsetBased)
else
{
}
if (RT_SUCCESS (rc))
{
}
else
{
}
}
return rc;
}
void *pvBase,
bool fOffsetBased)
{
if ( !pHeap
|| !pvBase)
{
return VERR_INVALID_PARAMETER;
}
if (RT_SUCCESS (rc))
{
if (!fOffsetBased)
else
if (RT_SUCCESS (rc))
{
}
else
{
}
}
return rc;
}
{
if (pHeap)
{
}
}
{
{
return NULL;
}
if (!pHeader)
return NULL;
return HGSMIBufferData (pHeader);
}
void *pvData)
{
return offBuffer;
}
void *pvData)
{
if ( pvData
{
}
}
{
void* pvBuf;
if (!pHeap->fOffsetBased)
else
if (!pvBuf)
return NULL;
return pvBuf;
}
void *pvBuf)
{
if (!pHeap->fOffsetBased)
else
}
/* Verify that the given offBuffer points to a valid buffer, which is within the area.
*/
{
LogFlowFunc(("buffer 0x%x, area %p %x [0x%x;0x%x]\n", offBuffer, pArea->pu8Base, pArea->cbArea, pArea->offBase, pArea->offLast));
{
LogFunc(("offset 0x%x is outside the area [0x%x;0x%x]!!!\n", offBuffer, pArea->offBase, pArea->offLast));
return NULL;
}
/* Quick check of the data size, it should be less than the maximum
* data size for the buffer at this offset.
*/
LogFlowFunc(("datasize check: pHeader->u32DataSize = 0x%x pArea->offLast - offBuffer = 0x%x\n", pHeader->u32DataSize, pArea->offLast - offBuffer));
{
/* At least both pHeader and pTail structures are in the area. Check the checksum. */
LogFlowFunc(("checksum check: u32Checksum = 0x%x pTail->u32Checksum = 0x%x\n", u32Checksum, pTail->u32Checksum));
{
return pHeader;
}
else
{
}
}
else
{
LogFunc(("invalid data size 0x%x, maximum is 0x%x!!!\n", pHeader->u32DataSize, pArea->offLast - offBuffer));
}
LogFlowFunc(("returning NULL\n"));
return NULL;
}
/* A wrapper to safely call the handler.
*/
const HGSMIBUFFERHEADER *pHeader)
{
int rc;
if ( pHandler
&& pHandler->pfnHandler)
{
}
else
{
/* It is a NOOP case here. */
rc = VINF_SUCCESS;
}
return rc;
}
/*
* Process a guest buffer.
* @thread EMT
*/
const HGSMIBUFFERHEADER *pHeader)
{
pHeader);
return rc;
}
{
{
return pChannel;
}
return NULL;
}
{
int rc = VERR_GENERAL_FAILURE;
// VM_ASSERT_EMT(pIns->pVM);
/* Guest has prepared a command description at 'offBuffer'. */
if (pHeader)
{
/* Pass the command to the appropriate handler registered with this instance.
* Start with the handler list head, which is the preallocated HGSMI setup channel.
*/
if (pChannel)
{
rc = VINF_SUCCESS;
}
else
{
}
}
else
{
// LogRel(("HGSMI[%s]: ignored invalid guest buffer 0x%08X!!!\n", pIns->pszName, offBuffer));
}
return rc;
}
/* Register a new VBVA channel by index.
*
*/
const char *pszName,
void *pvChannelHandler,
{
/* Check whether the channel is already registered. */
if (!pChannel)
{
/* Channel is not yet registered. */
}
return VINF_SUCCESS;
}