/* Verify that the given offBuffer points to a valid buffer, which is within the area. */ static const HGSMIBUFFERHEADER *hgsmiVerifyBuffer (const HGSMIAREA *pArea, HGSMIOFFSET offBuffer) { AssertPtr(pArea); LogFlowFunc(("buffer 0x%x, area %p %x [0x%x;0x%x]\n", offBuffer, pArea->pu8Base, pArea->cbArea, pArea->offBase, pArea->offLast)); if ( offBuffer < pArea->offBase || offBuffer > pArea->offLast) { LogFunc(("offset 0x%x is outside the area [0x%x;0x%x]!!!\n", offBuffer, pArea->offBase, pArea->offLast)); HGSMI_STRICT_ASSERT_FAILED(); return NULL; } const HGSMIBUFFERHEADER *pHeader = HGSMIOffsetToPointer (pArea, offBuffer); /* 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)); if (pHeader->u32DataSize <= pArea->offLast - offBuffer) { HGSMIBUFFERTAIL *pTail = HGSMIBufferTail (pHeader); /* At least both pHeader and pTail structures are in the area. Check the checksum. */ uint32_t u32Checksum = HGSMIChecksum (offBuffer, pHeader, pTail); LogFlowFunc(("checksum check: u32Checksum = 0x%x pTail->u32Checksum = 0x%x\n", u32Checksum, pTail->u32Checksum)); if (u32Checksum == pTail->u32Checksum) { LogFlowFunc(("returning %p\n", pHeader)); return pHeader; } else { LogFunc(("invalid checksum 0x%x, expected 0x%x!!!\n", u32Checksum, pTail->u32Checksum)); HGSMI_STRICT_ASSERT_FAILED(); } } else { LogFunc(("invalid data size 0x%x, maximum is 0x%x!!!\n", pHeader->u32DataSize, pArea->offLast - offBuffer)); HGSMI_STRICT_ASSERT_FAILED(); } LogFlowFunc(("returning NULL\n")); return NULL; }
/* Initialize the memory buffer including its checksum. * No changes alloed to the header and the tail after that. */ HGSMIOFFSET HGSMIBufferInitializeSingle(const HGSMIAREA *pArea, HGSMIBUFFERHEADER *pHeader, HGSMISIZE cbBuffer, uint8_t u8Channel, uint16_t u16ChannelInfo) { if ( !pArea || !pHeader || cbBuffer < HGSMIBufferMinimumSize()) { 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. */ HGSMISIZE cbMaximumDataSize = pArea->offLast - pArea->offBase; uint32_t u32DataSize = cbBuffer - HGSMIBufferMinimumSize(); if ( u32DataSize > cbMaximumDataSize || (uint8_t *)pHeader < pArea->pu8Base || (uint8_t *)pHeader > pArea->pu8Base + cbMaximumDataSize - u32DataSize) { return HGSMIOFFSET_VOID; } HGSMIOFFSET offBuffer = HGSMIPointerToOffset(pArea, pHeader); pHeader->u8Flags = HGSMI_BUFFER_HEADER_F_SEQ_SINGLE; pHeader->u32DataSize = u32DataSize; pHeader->u8Channel = u8Channel; pHeader->u16ChannelInfo = u16ChannelInfo; RT_ZERO(pHeader->u.au8Union); HGSMIBUFFERTAIL *pTail = HGSMIBufferTailFromPtr(pHeader, u32DataSize); pTail->u32Reserved = 0; pTail->u32Checksum = HGSMIChecksum(offBuffer, pHeader, pTail); return offBuffer; }
/** Verify that the given offBuffer points to a valid buffer, which is within the area. * * @returns VBox status and the buffer information in pBufferContext. * @param pArea Area which supposed to contain the buffer. * @param offBuffer The buffer location in the area. * @param pBufferContext Where to write information about the buffer. */ static int hgsmiVerifyBuffer(const HGSMIAREA *pArea, HGSMIOFFSET offBuffer, HGSMIBUFFERCONTEXT *pBufferContext) { LogFlowFunc(("buffer 0x%x, area %p %x [0x%x;0x%x]\n", offBuffer, pArea->pu8Base, pArea->cbArea, pArea->offBase, pArea->offLast)); int rc = VINF_SUCCESS; if ( offBuffer < pArea->offBase || offBuffer > pArea->offLast) { LogFunc(("offset 0x%x is outside the area [0x%x;0x%x]!!!\n", offBuffer, pArea->offBase, pArea->offLast)); rc = VERR_INVALID_PARAMETER; HGSMI_STRICT_ASSERT_FAILED(); } else { void *pvBuffer = HGSMIOffsetToPointer(pArea, offBuffer); HGSMIBUFFERHEADER header = *HGSMIBufferHeaderFromPtr(pvBuffer); /* Quick check of the data size, it should be less than the maximum * data size for the buffer at this offset. */ LogFlowFunc(("datasize check: header.u32DataSize = 0x%x pArea->offLast - offBuffer = 0x%x\n", header.u32DataSize, pArea->offLast - offBuffer)); if (header.u32DataSize <= pArea->offLast - offBuffer) { HGSMIBUFFERTAIL tail = *HGSMIBufferTailFromPtr(pvBuffer, header.u32DataSize); /* At least both header and tail structures are in the area. Check the checksum. */ uint32_t u32Checksum = HGSMIChecksum(offBuffer, &header, &tail); LogFlowFunc(("checksum check: u32Checksum = 0x%x pTail->u32Checksum = 0x%x\n", u32Checksum, tail.u32Checksum)); if (u32Checksum == tail.u32Checksum) { /* Success. */ pBufferContext->pHeader = HGSMIBufferHeaderFromPtr(pvBuffer); pBufferContext->pvData = HGSMIBufferDataFromPtr(pvBuffer); pBufferContext->cbData = header.u32DataSize; } else { LogFunc(("invalid checksum 0x%x, expected 0x%x!!!\n", u32Checksum, tail.u32Checksum)); rc = VERR_INVALID_STATE; HGSMI_STRICT_ASSERT_FAILED(); } } else { LogFunc(("invalid data size 0x%x, maximum is 0x%x!!!\n", header.u32DataSize, pArea->offLast - offBuffer)); rc = VERR_TOO_MUCH_DATA; HGSMI_STRICT_ASSERT_FAILED(); } } return rc; }