static int VBoxUSBMonSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal) { LogFunc((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: Dev=%d Cmd=%d pArg=%p Mode=%d\n", Dev, Cmd, pArg)); /* * Get the session from the soft state item. */ vboxusbmon_state_t *pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, getminor(Dev)); if (!pState) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: No state data for minor instance %d\n", getminor(Dev))); return EINVAL; } /* * Read the request wrapper. Though We don't really need wrapper struct. now * it's room for the future as Solaris isn't generous regarding the size. */ VBOXUSBREQ ReqWrap; if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap))); return ENOTTY; } int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode); if (RT_UNLIKELY(rc)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d\n", pArg, Cmd, rc)); return EINVAL; } if (ReqWrap.u32Magic != VBOXUSBMON_MAGIC) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: Bad magic %#x; pArg=%p Cmd=%d\n", ReqWrap.u32Magic, pArg, Cmd)); return EINVAL; } if (RT_UNLIKELY( ReqWrap.cbData == 0 || ReqWrap.cbData > _1M*16)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: Bad size %#x; pArg=%p Cmd=%d\n", ReqWrap.cbData, pArg, Cmd)); return EINVAL; } /* * Read the request. */ void *pvBuf = RTMemTmpAlloc(ReqWrap.cbData); if (RT_UNLIKELY(!pvBuf)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: RTMemTmpAlloc failed to alloc %d bytes\n", ReqWrap.cbData)); return ENOMEM; } rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode); if (RT_UNLIKELY(rc)) { RTMemTmpFree(pvBuf); LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc)); return EFAULT; } if (RT_UNLIKELY( ReqWrap.cbData != 0 && !VALID_PTR(pvBuf))) { RTMemTmpFree(pvBuf); LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: pvBuf Invalid pointer %p\n", pvBuf)); return EINVAL; } Log((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: pid=%d\n", (int)RTProcSelf())); /* * Process the IOCtl. */ size_t cbDataReturned = 0; rc = vboxUSBMonSolarisProcessIOCtl(Cmd, pState, pvBuf, ReqWrap.cbData, &cbDataReturned); ReqWrap.rc = rc; rc = 0; if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: Too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData)); cbDataReturned = ReqWrap.cbData; } ReqWrap.cbData = cbDataReturned; /* * Copy the request back to user space. */ rc = ddi_copyout(&ReqWrap, (void *)pArg, sizeof(ReqWrap), Mode); if (RT_LIKELY(!rc)) { /* * Copy the payload (if any) back to user space. */ if (cbDataReturned > 0) { rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode); if (RT_UNLIKELY(rc)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyout failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc)); rc = EFAULT; } } } else { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyout(1) failed pArg=%p Cmd=%d\n", pArg, Cmd)); rc = EFAULT; } *pVal = rc; RTMemTmpFree(pvBuf); return rc; }
int sf_dir_read_all(struct sf_glob_info *sf_g, struct sf_inode_info *sf_i, struct sf_dir_info *sf_d, SHFLHANDLE handle) { int err; SHFLSTRING *mask; struct sf_dir_buf *b; TRACE(); err = sf_make_path(__func__, sf_i, "*", 1, &mask); if (err) goto fail0; for (;;) { int rc; void *buf; uint32_t cbSize; uint32_t cEntries; b = sf_get_empty_dir_buf(sf_d); if (!b) { b = sf_dir_buf_alloc(); if (!b) { err = -ENOMEM; LogRelFunc(("could not alloc directory buffer\n")); goto fail1; } list_add(&b->head, &sf_d->info_list); } buf = b->buf; cbSize = b->cbFree; rc = vboxCallDirInfo(&client_handle, &sf_g->map, handle, mask, 0, 0, &cbSize, buf, &cEntries); switch (rc) { case VINF_SUCCESS: /* fallthrough */ case VERR_NO_MORE_FILES: break; case VERR_NO_TRANSLATION: LogFunc(("host could not translate entry\n")); /* XXX */ break; default: err = -RTErrConvertToErrno(rc); LogFunc(("vboxCallDirInfo failed rc=%Rrc\n", rc)); goto fail1; } b->cEntries += cEntries; b->cbFree -= cbSize; b->cbUsed += cbSize; if (RT_FAILURE(rc)) break; } err = 0; fail1: kfree(mask); fail0: return err; }
static void vbox_encoder_destroy(struct drm_encoder *encoder) { LogFunc(("vboxvideo: %d: encoder=%p\n", __LINE__, encoder)); drm_encoder_cleanup(encoder); kfree(encoder); }
int vbsfPathGuestToHost(SHFLCLIENTDATA *pClient, SHFLROOT hRoot, PSHFLSTRING pGuestString, uint32_t cbGuestString, char **ppszHostPath, uint32_t *pcbHostPathRoot, bool fWildCard, bool fPreserveLastComponent, uint32_t *pfu32PathFlags) { #ifdef VBOX_STRICT /* * Check that the pGuestPath has correct size and encoding. */ if (ShflStringIsValidIn(pGuestString, cbGuestString, RT_BOOL(pClient->fu32Flags & SHFL_CF_UTF8)) == false) { LogFunc(("Invalid input string\n")); return VERR_INTERNAL_ERROR; } #else NOREF(cbGuestString); #endif /* * Resolve the root handle into a string. */ uint32_t cbRootLen = 0; const char *pszRoot = NULL; int rc = vbsfMappingsQueryHostRootEx(hRoot, &pszRoot, &cbRootLen); if (RT_FAILURE(rc)) { LogFunc(("invalid root\n")); return rc; } AssertReturn(cbRootLen > 0, VERR_INTERNAL_ERROR_2); /* vbsfMappingsQueryHostRootEx ensures this. */ /* * Get the UTF8 string with the relative path provided by the guest. * If guest uses UTF-16 then convert it to UTF-8. */ uint32_t cbGuestPath; const char *pchGuestPath; char *pchGuestPathAllocated = NULL; /* Converted from UTF-16. */ if (BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8)) { /* UTF-8 */ cbGuestPath = pGuestString->u16Length; pchGuestPath = (char *)&pGuestString->String.utf8[0]; } else { /* UTF-16 */ uint32_t cwcSrc; PRTUTF16 pwszSrc; #ifdef RT_OS_DARWIN /* Misplaced hack! See todo! */ cwcSrc = 0; pwszSrc = NULL; rc = vbsfNormalizeStringDarwin(&pGuestString->String.ucs2[0], pGuestString->u16Length / sizeof(RTUTF16), &pwszSrc, &cwcSrc); #else cwcSrc = pGuestString->u16Length / sizeof(RTUTF16); pwszSrc = &pGuestString->String.ucs2[0]; #endif if (RT_SUCCESS(rc)) { size_t cbPathAsUtf8 = RTUtf16CalcUtf8Len(pwszSrc); if (cbPathAsUtf8 >= cwcSrc) { /* Allocate buffer that will be able to contain the converted UTF-8 string. */ pchGuestPathAllocated = (char *)RTMemAlloc(cbPathAsUtf8 + 1); if (RT_LIKELY(pchGuestPathAllocated != NULL)) { if (RT_LIKELY(cbPathAsUtf8)) { size_t cchActual; char *pszDst = pchGuestPathAllocated; rc = RTUtf16ToUtf8Ex(pwszSrc, cwcSrc, &pszDst, cbPathAsUtf8 + 1, &cchActual); AssertRC(rc); AssertStmt(RT_FAILURE(rc) || cchActual == cbPathAsUtf8, rc = VERR_INTERNAL_ERROR_4); Assert(strlen(pszDst) == cbPathAsUtf8); } if (RT_SUCCESS(rc)) { /* Terminate the string. */ pchGuestPathAllocated[cbPathAsUtf8] = '\0'; cbGuestPath = cbPathAsUtf8; pchGuestPath = pchGuestPathAllocated; } } else { rc = VERR_NO_MEMORY; } } else { AssertFailed(); rc = VERR_INTERNAL_ERROR_3; } #ifdef RT_OS_DARWIN RTMemFree(pwszSrc); #endif } } char *pszFullPath = NULL; if (RT_SUCCESS(rc)) { LogFlowFunc(("Root %s path %.*s\n", pszRoot, cbGuestPath, pchGuestPath)); /* * Allocate enough memory to build the host full path from the root and the relative path. */ uint32_t cbFullPathAlloc = cbRootLen + 1 + cbGuestPath + 1; /* root + possible_slash + relative + 0 */ pszFullPath = (char *)RTMemAlloc(cbFullPathAlloc); if (RT_LIKELY(pszFullPath != NULL)) { /* Copy the root. */ memcpy(pszFullPath, pszRoot, cbRootLen); if (!RTPATH_IS_SLASH(pszFullPath[cbRootLen - 1])) { pszFullPath[cbRootLen++] = RTPATH_SLASH; } /* Init the pointer for the relative path. */ char *pchDst = &pszFullPath[cbRootLen]; uint32_t cbSrc = cbGuestPath; const char *pchSrc = pchGuestPath; /* Strip leading delimiters from the path the guest specified. */ while ( cbSrc > 0 && *pchSrc == pClient->PathDelimiter) { ++pchSrc; --cbSrc; } /* * Iterate the guest path components, verify each of them * and append to the host full path replacing delimiters with host slash. */ bool fLastComponentHasWildcard = false; for (; cbSrc > 0; --cbSrc, ++pchSrc) { if (RT_LIKELY(*pchSrc != pClient->PathDelimiter)) { if (RT_LIKELY(vbsfPathIsValidNameChar(*pchSrc))) { if (pfu32PathFlags && vbsfPathIsWildcardChar(*pchSrc)) { fLastComponentHasWildcard = true; } *pchDst++ = *pchSrc; } else { rc = VERR_INVALID_NAME; break; } } else { /* Replace with the host slash. */ *pchDst++ = RTPATH_SLASH; if (pfu32PathFlags && fLastComponentHasWildcard && cbSrc > 1) { /* Processed component has a wildcard and there are more characters in the path. */ *pfu32PathFlags |= VBSF_F_PATH_HAS_WILDCARD_IN_PREFIX; } fLastComponentHasWildcard = false; } } if (RT_SUCCESS(rc)) { const size_t cbFullPathLength = pchDst - &pszFullPath[0]; /* As strlen(pszFullPath). */ *pchDst++ = 0; if (pfu32PathFlags && fLastComponentHasWildcard) { *pfu32PathFlags |= VBSF_F_PATH_HAS_WILDCARD_IN_LAST; } /* Check the appended path for root escapes. */ rc = vbsfPathCheckRootEscape(&pszFullPath[cbRootLen]); if (RT_SUCCESS(rc)) { /* * When the host file system is case sensitive and the guest expects * a case insensitive fs, then problems can occur. */ if ( vbsfIsHostMappingCaseSensitive(hRoot) && !vbsfIsGuestMappingCaseSensitive(hRoot)) { rc = vbsfCorrectPathCasing(pClient, pszFullPath, cbFullPathLength, fWildCard, fPreserveLastComponent); } if (RT_SUCCESS(rc)) { LogFunc(("%s\n", pszFullPath)); /* Return the full host path. */ *ppszHostPath = pszFullPath; if (pcbHostPathRoot) { *pcbHostPathRoot = cbRootLen - 1; /* Must index the path delimiter. */ } } } } } else { rc = VERR_NO_MEMORY; } } /* * Cleanup. */ RTMemFree(pchGuestPathAllocated); if (RT_SUCCESS(rc)) { return rc; } /* * Cleanup on failure. */ RTMemFree(pszFullPath); return rc; }
/** * [dentry] contains string encoded in coding system that corresponds * to [sf_g]->nls, we must convert it to UTF8 here and pass down to * [sf_make_path] which will allocate SHFLSTRING and fill it in */ int sf_path_from_dentry(const char *caller, struct sf_glob_info *sf_g, struct sf_inode_info *sf_i, struct dentry *dentry, SHFLSTRING **result) { int err; const char *d_name; size_t d_len; const char *name; size_t len = 0; TRACE(); d_name = dentry->d_name.name; d_len = dentry->d_name.len; if (sf_g->nls) { size_t in_len, i, out_bound_len; const char *in; char *out; in = d_name; in_len = d_len; out_bound_len = PATH_MAX; out = kmalloc(out_bound_len, GFP_KERNEL); name = out; for (i = 0; i < d_len; ++i) { /* We renamed the linux kernel wchar_t type to linux_wchar_t in the-linux-kernel.h, as it conflicts with the C++ type of that name. */ linux_wchar_t uni; int nb; nb = sf_g->nls->char2uni(in, in_len, &uni); if (nb < 0) { LogFunc(("nls->char2uni failed %x %d\n", *in, in_len)); err = -EINVAL; goto fail1; } in_len -= nb; in += nb; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) nb = utf32_to_utf8(uni, out, out_bound_len); #else nb = utf8_wctomb(out, uni, out_bound_len); #endif if (nb < 0) { LogFunc(("nls->uni2char failed %x %d\n", uni, out_bound_len)); err = -EINVAL; goto fail1; } out_bound_len -= nb; out += nb; len += nb; } if (len >= PATH_MAX - 1) { err = -ENAMETOOLONG; goto fail1; } LogFunc(("result(%d) = %.*s\n", len, len, name)); *out = 0; } else { name = d_name; len = d_len; } err = sf_make_path(caller, sf_i, name, len, result); if (name != d_name) kfree(name); return err; fail1: kfree(name); return err; }
static int paCreateStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples) { AssertPtrReturn(pInterface, VERR_INVALID_POINTER); AssertPtrReturn(pStream, VERR_INVALID_POINTER); AssertPtrReturn(pCfg, VERR_INVALID_POINTER); /* pcSamples is optional. */ PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); PPULSEAUDIOSTREAM pStrm = (PPULSEAUDIOSTREAM)pStream; LogFlowFuncEnter(); pStrm->pDrainOp = NULL; pStrm->SampleSpec.format = paFmtToPulse(pCfg->enmFormat); pStrm->SampleSpec.rate = pCfg->uHz; pStrm->SampleSpec.channels = pCfg->cChannels; /* Note that setting maxlength to -1 does not work on PulseAudio servers * older than 0.9.10. So use the suggested value of 3/2 of tlength */ pStrm->BufAttr.tlength = (pa_bytes_per_second(&pStrm->SampleSpec) * s_pulseCfg.buffer_msecs_out) / 1000; pStrm->BufAttr.maxlength = (pStrm->BufAttr.tlength * 3) / 2; pStrm->BufAttr.prebuf = -1; /* Same as tlength */ pStrm->BufAttr.minreq = -1; /* Note that the struct BufAttr is updated to the obtained values after this call! */ int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)", &pStrm->SampleSpec, &pStrm->BufAttr, &pStrm->pPAStream); if (RT_FAILURE(rc)) return rc; PDMAUDIOSTREAMCFG streamCfg; rc = paPulseToFmt(pStrm->SampleSpec.format, &streamCfg.enmFormat, &streamCfg.enmEndianness); if (RT_FAILURE(rc)) { LogRel(("PulseAudio: Cannot find audio output format %ld\n", pStrm->SampleSpec.format)); return rc; } streamCfg.uHz = pStrm->SampleSpec.rate; streamCfg.cChannels = pStrm->SampleSpec.channels; rc = DrvAudioHlpStreamCfgToProps(&streamCfg, &pStream->Props); if (RT_SUCCESS(rc)) { uint32_t cbBuf = RT_MIN(pStrm->BufAttr.tlength * 2, pStrm->BufAttr.maxlength); /** @todo Make this configurable! */ if (cbBuf) { pStrm->pvPCMBuf = RTMemAllocZ(cbBuf); if (pStrm->pvPCMBuf) { pStrm->cbPCMBuf = cbBuf; uint32_t cSamples = cbBuf >> pStream->Props.cShift; if (pcSamples) *pcSamples = cSamples; /* Save pointer to driver instance. */ pStrm->pDrv = pThis; LogFunc(("cbBuf=%RU32, cSamples=%RU32\n", cbBuf, cSamples)); } else rc = VERR_NO_MEMORY; }
/* This function will free m0! */ int ip_output0(PNATState pData, struct socket *so, struct mbuf *m0, int urg) { register struct ip *ip; register struct mbuf *m = m0; register int hlen = sizeof(struct ip); int len, off, error = 0; extern uint8_t zerro_ethaddr[ETH_ALEN]; struct ethhdr *eh = NULL; uint8_t eth_dst[ETH_ALEN]; int rc = 1; STAM_PROFILE_START(&pData->StatIP_output, a); LogFlowFunc(("ip_output: so = %R[natsock], m0 = %lx\n", so, (long)m0)); M_ASSERTPKTHDR(m); Assert(m->m_pkthdr.header); #if 0 /* We do no options */ if (opt) { m = ip_insertoptions(m, opt, &len); hlen = len; } #endif ip = mtod(m, struct ip *); LogFunc(("ip(src:%RTnaipv4, dst:%RTnaipv4)\n", ip->ip_src, ip->ip_dst)); /* * Fill in IP header. */ ip->ip_v = IPVERSION; ip->ip_off &= IP_DF; ip->ip_id = RT_H2N_U16(ip_currid++); ip->ip_hl = hlen >> 2; ipstat.ips_localout++; /* Current TCP/IP stack hasn't routing information at * all so we need to calculate destination ethernet address */ rc = rt_lookup_in_cache(pData, ip->ip_dst.s_addr, eth_dst); if (RT_FAILURE(rc)) goto exit_drop_package; eh = (struct ethhdr *)(m->m_data - ETH_HLEN); /* * If small enough for interface, can just send directly. */ if ((u_int16_t)ip->ip_len <= if_mtu) { ip->ip_len = RT_H2N_U16((u_int16_t)ip->ip_len); ip->ip_off = RT_H2N_U16((u_int16_t)ip->ip_off); ip->ip_sum = 0; ip->ip_sum = cksum(m, hlen); { struct m_tag *t; STAM_PROFILE_START(&pData->StatALIAS_output, b); if ((t = m_tag_find(m, PACKET_TAG_ALIAS, NULL)) != 0) rc = LibAliasOut((struct libalias *)&t[1], mtod(m, char *), m_length(m, NULL)); else rc = LibAliasOut(pData->proxy_alias, mtod(m, char *), m_length(m, NULL)); if (rc == PKT_ALIAS_IGNORED) { Log(("NAT: packet was droppped\n")); goto exit_drop_package; } STAM_PROFILE_STOP(&pData->StatALIAS_output, b); }
/** * Read from a regular file. * * @param file the file * @param buf the buffer * @param size length of the buffer * @param off offset within the file * @returns the number of read bytes on success, Linux error code otherwise */ static ssize_t sf_reg_read(struct file *file, char *buf, size_t size, loff_t *off) { int err; void *tmp; RTCCPHYS tmp_phys; size_t tmp_size; size_t left = size; ssize_t total_bytes_read = 0; struct inode *inode = GET_F_DENTRY(file)->d_inode; struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); struct sf_reg_info *sf_r = file->private_data; loff_t pos = *off; TRACE(); if (!S_ISREG(inode->i_mode)) { LogFunc(("read from non regular file %d\n", inode->i_mode)); return -EINVAL; } /** XXX Check read permission according to inode->i_mode! */ if (!size) return 0; tmp = alloc_bounce_buffer(&tmp_size, &tmp_phys, size, __PRETTY_FUNCTION__); if (!tmp) return -ENOMEM; while (left) { uint32_t to_read, nread; to_read = tmp_size; if (to_read > left) to_read = (uint32_t) left; nread = to_read; err = sf_reg_read_aux(__func__, sf_g, sf_r, tmp, &nread, pos); if (err) goto fail; if (copy_to_user(buf, tmp, nread)) { err = -EFAULT; goto fail; } pos += nread; left -= nread; buf += nread; total_bytes_read += nread; if (nread != to_read) break; } *off += total_bytes_read; free_bounce_buffer(tmp); return total_bytes_read; fail: free_bounce_buffer(tmp); return err; }
/** * Write to a regular file. * * @param file the file * @param buf the buffer * @param size length of the buffer * @param off offset within the file * @returns the number of written bytes on success, Linux error code otherwise */ static ssize_t sf_reg_write(struct file *file, const char *buf, size_t size, loff_t *off) { int err; void *tmp; RTCCPHYS tmp_phys; size_t tmp_size; size_t left = size; ssize_t total_bytes_written = 0; struct inode *inode = GET_F_DENTRY(file)->d_inode; struct sf_inode_info *sf_i = GET_INODE_INFO(inode); struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); struct sf_reg_info *sf_r = file->private_data; loff_t pos; TRACE(); BUG_ON(!sf_i); BUG_ON(!sf_g); BUG_ON(!sf_r); if (!S_ISREG(inode->i_mode)) { LogFunc(("write to non regular file %d\n", inode->i_mode)); return -EINVAL; } pos = *off; if (file->f_flags & O_APPEND) { pos = inode->i_size; *off = pos; } /** XXX Check write permission according to inode->i_mode! */ if (!size) return 0; tmp = alloc_bounce_buffer(&tmp_size, &tmp_phys, size, __PRETTY_FUNCTION__); if (!tmp) return -ENOMEM; while (left) { uint32_t to_write, nwritten; to_write = tmp_size; if (to_write > left) to_write = (uint32_t) left; nwritten = to_write; if (copy_from_user(tmp, buf, to_write)) { err = -EFAULT; goto fail; } #if 1 if (VbglR0CanUsePhysPageList()) { err = VbglR0SfWritePhysCont(&client_handle, &sf_g->map, sf_r->handle, pos, &nwritten, tmp_phys); err = RT_FAILURE(err) ? -EPROTO : 0; } else #endif err = sf_reg_write_aux(__func__, sf_g, sf_r, tmp, &nwritten, pos); if (err) goto fail; pos += nwritten; left -= nwritten; buf += nwritten; total_bytes_written += nwritten; if (nwritten != to_write) break; } *off += total_bytes_written; if (*off > inode->i_size) inode->i_size = *off; sf_i->force_restat = 1; free_bounce_buffer(tmp); return total_bytes_written; fail: free_bounce_buffer(tmp); return err; }
static DECLCALLBACK(int) drvHostPulseAudioInitOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples) { NOREF(pInterface); AssertPtrReturn(pHstStrmOut, VERR_INVALID_POINTER); AssertPtrReturn(pCfg, VERR_INVALID_POINTER); /* pcSamples is optional. */ PPULSEAUDIOSTREAM pThisStrmOut = (PPULSEAUDIOSTREAM)pHstStrmOut; LogFlowFuncEnter(); pThisStrmOut->pDrainOp = NULL; pThisStrmOut->SampleSpec.format = drvHostPulseAudioFmtToPulse(pCfg->enmFormat); pThisStrmOut->SampleSpec.rate = pCfg->uHz; pThisStrmOut->SampleSpec.channels = pCfg->cChannels; /* Note that setting maxlength to -1 does not work on PulseAudio servers * older than 0.9.10. So use the suggested value of 3/2 of tlength */ pThisStrmOut->BufAttr.tlength = (pa_bytes_per_second(&pThisStrmOut->SampleSpec) * s_pulseCfg.buffer_msecs_out) / 1000; pThisStrmOut->BufAttr.maxlength = (pThisStrmOut->BufAttr.tlength * 3) / 2; pThisStrmOut->BufAttr.prebuf = -1; /* Same as tlength */ pThisStrmOut->BufAttr.minreq = -1; /* Pulse should set something sensible for minreq on it's own */ /* Note that the struct BufAttr is updated to the obtained values after this call! */ int rc = drvHostPulseAudioOpen(false /* fIn */, "pa.out", &pThisStrmOut->SampleSpec, &pThisStrmOut->BufAttr, &pThisStrmOut->pStream); if (RT_FAILURE(rc)) return rc; PDMAUDIOSTREAMCFG streamCfg; rc = drvHostPulseAudioPulseToFmt(pThisStrmOut->SampleSpec.format, &streamCfg.enmFormat, &streamCfg.enmEndianness); if (RT_FAILURE(rc)) { LogRel(("PulseAudio: Cannot find audio output format %ld\n", pThisStrmOut->SampleSpec.format)); return rc; } streamCfg.uHz = pThisStrmOut->SampleSpec.rate; streamCfg.cChannels = pThisStrmOut->SampleSpec.channels; rc = drvAudioStreamCfgToProps(&streamCfg, &pHstStrmOut->Props); if (RT_SUCCESS(rc)) { uint32_t cbBuf = RT_MIN(pThisStrmOut->BufAttr.tlength * 2, pThisStrmOut->BufAttr.maxlength); /** @todo Make this configurable! */ if (cbBuf) { pThisStrmOut->pvPCMBuf = RTMemAllocZ(cbBuf); if (pThisStrmOut->pvPCMBuf) { pThisStrmOut->cbPCMBuf = cbBuf; uint32_t cSamples = cbBuf >> pHstStrmOut->Props.cShift; if (pcSamples) *pcSamples = cSamples; LogFunc(("cbBuf=%RU32, cSamples=%RU32\n", cbBuf, cSamples)); } else rc = VERR_NO_MEMORY; }
/** * Attach entry point, to attach a device to the system or resume it. * * @param pDip The module structure instance. * @param enmCmd Operation type (attach/resume). * * @returns corresponding solaris error code. */ static int VBoxNetAdpSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd) { LogFunc((DEVICE_NAME ":VBoxNetAdpSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd)); int rc = -1; switch (enmCmd) { case DDI_ATTACH: { gld_mac_info_t *pMacInfo = gld_mac_alloc(pDip); if (pMacInfo) { vboxnetadp_state_t *pState = RTMemAllocZ(sizeof(vboxnetadp_state_t)); if (pState) { pState->pDip = pDip; /* * Setup GLD MAC layer registration info. */ pMacInfo->gldm_reset = vboxNetAdpSolarisStub; pMacInfo->gldm_start = vboxNetAdpSolarisStub; pMacInfo->gldm_stop = vboxNetAdpSolarisStub; pMacInfo->gldm_set_mac_addr = vboxNetAdpSolarisSetMacAddress; pMacInfo->gldm_set_multicast = vboxNetAdpSolarisSetMulticast; pMacInfo->gldm_set_promiscuous = vboxNetAdpSolarisSetPromisc; pMacInfo->gldm_send = vboxNetAdpSolarisSend; pMacInfo->gldm_intr = NULL; pMacInfo->gldm_get_stats = vboxNetAdpSolarisGetStats; pMacInfo->gldm_ioctl = NULL; pMacInfo->gldm_ident = DEVICE_NAME; pMacInfo->gldm_type = DL_ETHER; pMacInfo->gldm_minpkt = 0; pMacInfo->gldm_maxpkt = VBOXNETADP_MTU; pMacInfo->gldm_capabilities = GLD_CAP_LINKSTATE; AssertCompile(sizeof(RTMAC) == ETHERADDRL); pMacInfo->gldm_addrlen = ETHERADDRL; pMacInfo->gldm_saplen = -2; pMacInfo->gldm_broadcast_addr = achBroadcastAddr; pMacInfo->gldm_ppa = ddi_get_instance(pState->pDip); pMacInfo->gldm_devinfo = pState->pDip; pMacInfo->gldm_private = (caddr_t)pState; /* * We use a semi-random MAC addresses similar to a guest NIC's MAC address * as the default factory address of the interface. */ rc = vboxNetAdpSolarisGenerateMac(&pState->FactoryMac); if (RT_SUCCESS(rc)) { bcopy(&pState->FactoryMac, &pState->CurrentMac, sizeof(RTMAC)); pMacInfo->gldm_vendor_addr = (unsigned char *)&pState->FactoryMac; /* * Now try registering our GLD with the MAC layer. * Registration can fail on some S10 versions when the MTU size is more than 1500. * When we implement jumbo frames we should probably retry with MTU 1500 for S10. */ rc = gld_register(pDip, (char *)ddi_driver_name(pDip), pMacInfo); if (rc == DDI_SUCCESS) { ddi_report_dev(pDip); gld_linkstate(pMacInfo, GLD_LINKSTATE_UP); return DDI_SUCCESS; } else LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to register GLD. rc=%d\n", rc)); } else LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to generate mac address.rc=%d\n")); RTMemFree(pState); } else LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to alloc state.\n")); gld_mac_free(pMacInfo); } else LogRel((DEVICE_NAME ":VBoxNetAdpSolarisAttach failed to alloc mac structure.\n")); return DDI_FAILURE; } case DDI_RESUME: { /* Nothing to do here... */ return DDI_SUCCESS; } /* case DDI_PM_RESUME: */ default: return DDI_FAILURE; } }
/** * MSR write handler for KVM. * * @returns Strict VBox status code like CPUMSetGuestMsr(). * @retval VINF_CPUM_R3_MSR_WRITE * @retval VERR_CPUM_RAISE_GP_0 * * @param pVCpu Pointer to the VMCPU. * @param idMsr The MSR being written. * @param pRange The range this MSR belongs to. * @param uRawValue The raw value with the ignored bits not masked. */ VMM_INT_DECL(VBOXSTRICTRC) gimKvmWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uRawValue) { NOREF(pRange); PVM pVM = pVCpu->CTX_SUFF(pVM); PGIMKVM pKvm = &pVM->gim.s.u.Kvm; PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu; switch (idMsr) { case MSR_GIM_KVM_SYSTEM_TIME: case MSR_GIM_KVM_SYSTEM_TIME_OLD: { bool fEnable = RT_BOOL(uRawValue & MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT); #ifdef IN_RING0 gimR0KvmUpdateSystemTime(pVM, pVCpu); return VINF_CPUM_R3_MSR_WRITE; #elif defined(IN_RC) Assert(pVM->cCpus == 1); if (fEnable) { RTCCUINTREG fEFlags = ASMIntDisableFlags(); pKvmCpu->uTsc = TMCpuTickGetNoCheck(pVCpu) | UINT64_C(1); pKvmCpu->uVirtNanoTS = TMVirtualGetNoCheck(pVM) | UINT64_C(1); ASMSetFlags(fEFlags); } return VINF_CPUM_R3_MSR_WRITE; #else /* IN_RING3 */ if (!fEnable) { gimR3KvmDisableSystemTime(pVM); pKvmCpu->u64SystemTimeMsr = uRawValue; return VINF_SUCCESS; } /* Is the system-time struct. already enabled? If so, get flags that need preserving. */ uint8_t fFlags = 0; GIMKVMSYSTEMTIME SystemTime; RT_ZERO(SystemTime); if ( MSR_GIM_KVM_SYSTEM_TIME_IS_ENABLED(pKvmCpu->u64SystemTimeMsr) && MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue) == pKvmCpu->GCPhysSystemTime) { int rc2 = PGMPhysSimpleReadGCPhys(pVM, &SystemTime, pKvmCpu->GCPhysSystemTime, sizeof(GIMKVMSYSTEMTIME)); if (RT_SUCCESS(rc2)) pKvmCpu->fSystemTimeFlags = (SystemTime.fFlags & GIM_KVM_SYSTEM_TIME_FLAGS_GUEST_PAUSED); } /* Enable and populate the system-time struct. */ pKvmCpu->u64SystemTimeMsr = uRawValue; pKvmCpu->GCPhysSystemTime = MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue); pKvmCpu->u32SystemTimeVersion += 2; int rc = gimR3KvmEnableSystemTime(pVM, pVCpu); if (RT_FAILURE(rc)) { pKvmCpu->u64SystemTimeMsr = 0; return VERR_CPUM_RAISE_GP_0; } return VINF_SUCCESS; #endif } case MSR_GIM_KVM_WALL_CLOCK: case MSR_GIM_KVM_WALL_CLOCK_OLD: { #ifndef IN_RING3 return VINF_CPUM_R3_MSR_WRITE; #else /* Enable the wall-clock struct. */ RTGCPHYS GCPhysWallClock = MSR_GIM_KVM_WALL_CLOCK_GUEST_GPA(uRawValue); if (RT_LIKELY(RT_ALIGN_64(GCPhysWallClock, 4) == GCPhysWallClock)) { int rc = gimR3KvmEnableWallClock(pVM, GCPhysWallClock); if (RT_SUCCESS(rc)) { pKvm->u64WallClockMsr = uRawValue; return VINF_SUCCESS; } } return VERR_CPUM_RAISE_GP_0; #endif /* IN_RING3 */ } default: { #ifdef IN_RING3 static uint32_t s_cTimes = 0; if (s_cTimes++ < 20) LogRel(("GIM: KVM: Unknown/invalid WrMsr (%#x,%#x`%08x) -> #GP(0)\n", idMsr, uRawValue & UINT64_C(0xffffffff00000000), uRawValue & UINT64_C(0xffffffff))); #endif LogFunc(("Unknown/invalid WrMsr (%#RX32,%#RX64) -> #GP(0)\n", idMsr, uRawValue)); break; } } return VERR_CPUM_RAISE_GP_0; }
/** * USBA driver election callback. * * @returns USB_SUCCESS if we want to capture the device, USB_FAILURE otherwise. * @param pDevDesc The parsed device descriptor (does not include subconfigs). * @param pDevStrings Device strings: Manufacturer, Product, Serial Number. * @param pszDevicePath The physical path of the device being attached. * @param Bus The Bus number on which the device is on. * @param Port The Port number on the bus. * @param ppszDrv The name of the driver we wish to capture the device with. * @param pvReserved Reserved for future use. */ int VBoxUSBMonSolarisElectDriver(usb_dev_descr_t *pDevDesc, usb_dev_str_t *pDevStrings, char *pszDevicePath, int Bus, int Port, char **ppszDrv, void *pvReserved) { LogFunc((DEVICE_NAME ": VBoxUSBMonSolarisElectDriver: pDevDesc=%p pDevStrings=%p pszDevicePath=%s Bus=%d Port=%d\n", pDevDesc, pDevStrings, pszDevicePath, Bus, Port)); AssertPtrReturn(pDevDesc, USB_FAILURE); AssertPtrReturn(pDevStrings, USB_FAILURE); /* * Create a filter from the device being attached. */ USBFILTER Filter; USBFilterInit(&Filter, USBFILTERTYPE_CAPTURE); USBFilterSetNumExact(&Filter, USBFILTERIDX_VENDOR_ID, pDevDesc->idVendor, true); USBFilterSetNumExact(&Filter, USBFILTERIDX_PRODUCT_ID, pDevDesc->idProduct, true); USBFilterSetNumExact(&Filter, USBFILTERIDX_DEVICE_REV, pDevDesc->bcdDevice, true); USBFilterSetNumExact(&Filter, USBFILTERIDX_DEVICE_CLASS, pDevDesc->bDeviceClass, true); USBFilterSetNumExact(&Filter, USBFILTERIDX_DEVICE_SUB_CLASS, pDevDesc->bDeviceSubClass, true); USBFilterSetNumExact(&Filter, USBFILTERIDX_DEVICE_PROTOCOL, pDevDesc->bDeviceProtocol, true); USBFilterSetNumExact(&Filter, USBFILTERIDX_BUS, 0x0 /* Bus */, true); /* Use 0x0 as userland initFilterFromDevice function in Main: see comment on "SetMustBePresent" below */ USBFilterSetNumExact(&Filter, USBFILTERIDX_PORT, Port, true); USBFilterSetStringExact(&Filter, USBFILTERIDX_MANUFACTURER_STR, pDevStrings->usb_mfg ? pDevStrings->usb_mfg : "", true); USBFilterSetStringExact(&Filter, USBFILTERIDX_PRODUCT_STR, pDevStrings->usb_product ? pDevStrings->usb_product : "", true); USBFilterSetStringExact(&Filter, USBFILTERIDX_SERIAL_NUMBER_STR, pDevStrings->usb_serialno ? pDevStrings->usb_serialno : "", true); /* This doesn't work like it should (USBFilterMatch fails on matching field (6) i.e. Bus despite this. Investigate later. */ USBFilterSetMustBePresent(&Filter, USBFILTERIDX_BUS, false /* fMustBePresent */); Log((DEVICE_NAME ": VBoxUSBMonSolarisElectDriver: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x " "bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_VENDOR_ID), USBFilterGetNum(&Filter, USBFILTERIDX_PRODUCT_ID), USBFilterGetNum(&Filter, USBFILTERIDX_DEVICE_REV), USBFilterGetNum(&Filter, USBFILTERIDX_DEVICE_CLASS), USBFilterGetNum(&Filter, USBFILTERIDX_DEVICE_SUB_CLASS), USBFilterGetNum(&Filter, USBFILTERIDX_DEVICE_PROTOCOL), USBFilterGetNum(&Filter, USBFILTERIDX_BUS), USBFilterGetNum(&Filter, USBFILTERIDX_PORT))); Log((DEVICE_NAME ": VBoxUSBMonSolarisElectDriver: Manufacturer=%s Product=%s Serial=%s\n", USBFilterGetString(&Filter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(&Filter, USBFILTERIDX_MANUFACTURER_STR) : "<null>", USBFilterGetString(&Filter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(&Filter, USBFILTERIDX_PRODUCT_STR) : "<null>", USBFilterGetString(&Filter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(&Filter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>")); /* * Run through user filters and try to see if it has a match. */ uintptr_t uId = 0; RTPROCESS Owner = VBoxUSBFilterMatch(&Filter, &uId); USBFilterDelete(&Filter); if (Owner == NIL_RTPROCESS) { Log((DEVICE_NAME ": VBoxUSBMonSolarisElectDriver: No matching filters, device %#x:%#x uninteresting\n", pDevDesc->idVendor, pDevDesc->idProduct)); return USB_FAILURE; } *ppszDrv = ddi_strdup(VBOXUSB_DRIVER_NAME, KM_SLEEP); #if 0 LogRel((DEVICE_NAME ": Capturing %s %s %#x:%#x:%s Bus=%d Port=%d\n", pDevStrings->usb_mfg ? pDevStrings->usb_mfg : "<Unknown Manufacturer>", pDevStrings->usb_product ? pDevStrings->usb_product : "<Unnamed USB device>", pDevDesc->idVendor, pDevDesc->idProduct, pszDevicePath, Bus, Port)); #else /* Until IPRT R0 logging is fixed. See @bugref{6657#c7} */ cmn_err(CE_CONT, "Capturing %s %s 0x%x:0x%x:%s Bus=%d Port=%d\n", pDevStrings->usb_mfg ? pDevStrings->usb_mfg : "<Unknown Manufacturer>", pDevStrings->usb_product ? pDevStrings->usb_product : "<Unnamed USB device>", pDevDesc->idVendor, pDevDesc->idProduct, pszDevicePath, Bus, Port); #endif return USB_SUCCESS; }
/** * IOCtl processor for user to kernel and kernel to kernel communication. * * @returns VBox status code. * * @param iFunction The requested function. * @param pvState Opaque pointer to driver state used for getting * ring-3 process (Id). * @param pvData The input/output data buffer. Can be NULL * depending on the function. * @param cbData The max size of the data buffer. * @param pcbReturnedData Where to store the amount of returned data. Can * be NULL. */ static int vboxUSBMonSolarisProcessIOCtl(int iFunction, void *pvState, void *pvData, size_t cbData, size_t *pcbReturnedData) { LogFunc((DEVICE_NAME ": vboxUSBMonSolarisProcessIOCtl: iFunction=%d pvBuf=%p cbBuf=%zu\n", iFunction, pvData, cbData)); AssertPtrReturn(pvState, VERR_INVALID_POINTER); vboxusbmon_state_t *pState = (vboxusbmon_state_t *)pvState; int rc; #define CHECKRET_MIN_SIZE(mnemonic, cbMin) \ do { \ if (cbData < (cbMin)) \ { \ LogRel(("vboxUSBSolarisProcessIOCtl: " mnemonic ": cbData=%#zx (%zu) min is %#zx (%zu)\n", \ cbData, cbData, (size_t)(cbMin), (size_t)(cbMin))); \ return VERR_BUFFER_OVERFLOW; \ } \ if ((cbMin) != 0 && !VALID_PTR(pvData)) \ { \ LogRel(("vboxUSBSolarisProcessIOCtl: " mnemonic ": Invalid pointer %p\n", pvData)); \ return VERR_INVALID_POINTER; \ } \ } while (0) switch (iFunction) { case VBOXUSBMON_IOCTL_ADD_FILTER: { CHECKRET_MIN_SIZE("ADD_FILTER", sizeof(VBOXUSBREQ_ADD_FILTER)); VBOXUSBREQ_ADD_FILTER *pReq = (VBOXUSBREQ_ADD_FILTER *)pvData; PUSBFILTER pFilter = (PUSBFILTER)&pReq->Filter; Log(("vboxUSBMonSolarisProcessIOCtl: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x " "bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x\n", USBFilterGetNum(pFilter, USBFILTERIDX_VENDOR_ID), USBFilterGetNum(pFilter, USBFILTERIDX_PRODUCT_ID), USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_REV), USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_CLASS), USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_SUB_CLASS), USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_PROTOCOL), USBFilterGetNum(pFilter, USBFILTERIDX_BUS), USBFilterGetNum(pFilter, USBFILTERIDX_PORT))); Log(("vboxUSBMonSolarisProcessIOCtl: Manufacturer=%s Product=%s Serial=%s\n", USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) : "<null>", USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) : "<null>", USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>")); rc = USBFilterSetMustBePresent(pFilter, USBFILTERIDX_BUS, false /* fMustBePresent */); AssertRC(rc); rc = VBoxUSBFilterAdd(pFilter, pState->Process, &pReq->uId); *pcbReturnedData = cbData; Log((DEVICE_NAME ": vboxUSBMonSolarisProcessIOCtl: ADD_FILTER (Process:%d) returned %d\n", pState->Process, rc)); break; } case VBOXUSBMON_IOCTL_REMOVE_FILTER: { CHECKRET_MIN_SIZE("REMOVE_FILTER", sizeof(VBOXUSBREQ_REMOVE_FILTER)); VBOXUSBREQ_REMOVE_FILTER *pReq = (VBOXUSBREQ_REMOVE_FILTER *)pvData; rc = VBoxUSBFilterRemove(pState->Process, (uintptr_t)pReq->uId); *pcbReturnedData = 0; Log((DEVICE_NAME ": vboxUSBMonSolarisProcessIOCtl: REMOVE_FILTER (Process:%d) returned %d\n", pState->Process, rc)); break; } case VBOXUSBMON_IOCTL_RESET_DEVICE: { CHECKRET_MIN_SIZE("RESET_DEVICE", sizeof(VBOXUSBREQ_RESET_DEVICE)); VBOXUSBREQ_RESET_DEVICE *pReq = (VBOXUSBREQ_RESET_DEVICE *)pvData; rc = vboxUSBMonSolarisResetDevice(pReq->szDevicePath, pReq->fReattach); *pcbReturnedData = 0; Log((DEVICE_NAME ": vboxUSBMonSolarisProcessIOCtl: RESET_DEVICE (Process:%d) returned %d\n", pState->Process, rc)); break; } case VBOXUSBMON_IOCTL_CLIENT_INFO: { CHECKRET_MIN_SIZE("CLIENT_INFO", sizeof(VBOXUSBREQ_CLIENT_INFO)); VBOXUSBREQ_CLIENT_INFO *pReq = (VBOXUSBREQ_CLIENT_INFO *)pvData; rc = vboxUSBMonSolarisClientInfo(pState, pReq); *pcbReturnedData = cbData; Log((DEVICE_NAME ": vboxUSBMonSolarisProcessIOCtl: CLIENT_INFO (Process:%d) returned %d\n", pState->Process, rc)); break; } case VBOXUSBMON_IOCTL_GET_VERSION: { CHECKRET_MIN_SIZE("GET_VERSION", sizeof(VBOXUSBREQ_GET_VERSION)); PVBOXUSBREQ_GET_VERSION pGetVersionReq = (PVBOXUSBREQ_GET_VERSION)pvData; pGetVersionReq->u32Major = VBOXUSBMON_VERSION_MAJOR; pGetVersionReq->u32Minor = VBOXUSBMON_VERSION_MINOR; *pcbReturnedData = sizeof(VBOXUSBREQ_GET_VERSION); rc = VINF_SUCCESS; Log((DEVICE_NAME ": vboxUSBMonSolarisProcessIOCtl: GET_VERSION returned %d\n", rc)); break; } default: { LogRel((DEVICE_NAME ": vboxUSBMonSolarisProcessIOCtl: Unknown request (Process:%d) %#x\n", pState->Process, iFunction)); *pcbReturnedData = 0; rc = VERR_NOT_SUPPORTED; break; } } return rc; }
/** 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; }
/** * Open a regular file. * * @param inode the inode * @param file the file * @returns 0 on success, Linux error code otherwise */ static int sf_reg_open(struct inode *inode, struct file *file) { int rc, rc_linux = 0; struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); struct sf_inode_info *sf_i = GET_INODE_INFO(inode); struct sf_reg_info *sf_r; SHFLCREATEPARMS params; TRACE(); BUG_ON(!sf_g); BUG_ON(!sf_i); LogFunc(("open %s\n", sf_i->path->String.utf8)); sf_r = kmalloc(sizeof(*sf_r), GFP_KERNEL); if (!sf_r) { LogRelFunc(("could not allocate reg info\n")); return -ENOMEM; } /* Already open? */ if (sf_i->handle != SHFL_HANDLE_NIL) { /* * This inode was created with sf_create_aux(). Check the CreateFlags: * O_CREAT, O_TRUNC: inherent true (file was just created). Not sure * about the access flags (SHFL_CF_ACCESS_*). */ sf_i->force_restat = 1; sf_r->handle = sf_i->handle; sf_i->handle = SHFL_HANDLE_NIL; sf_i->file = file; file->private_data = sf_r; return 0; } RT_ZERO(params); params.Handle = SHFL_HANDLE_NIL; /* We check the value of params.Handle afterwards to find out if * the call succeeded or failed, as the API does not seem to cleanly * distinguish error and informational messages. * * Furthermore, we must set params.Handle to SHFL_HANDLE_NIL to * make the shared folders host service use our fMode parameter */ if (file->f_flags & O_CREAT) { LogFunc(("O_CREAT set\n")); params.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW; /* We ignore O_EXCL, as the Linux kernel seems to call create beforehand itself, so O_EXCL should always fail. */ if (file->f_flags & O_TRUNC) { LogFunc(("O_TRUNC set\n")); params.CreateFlags |= ( SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACCESS_WRITE); } else params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS; } else { params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW; if (file->f_flags & O_TRUNC) { LogFunc(("O_TRUNC set\n")); params.CreateFlags |= ( SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACCESS_WRITE); } } if (!(params.CreateFlags & SHFL_CF_ACCESS_READWRITE)) { switch (file->f_flags & O_ACCMODE) { case O_RDONLY: params.CreateFlags |= SHFL_CF_ACCESS_READ; break; case O_WRONLY: params.CreateFlags |= SHFL_CF_ACCESS_WRITE; break; case O_RDWR: params.CreateFlags |= SHFL_CF_ACCESS_READWRITE; break; default: BUG (); } } if (file->f_flags & O_APPEND) { LogFunc(("O_APPEND set\n")); params.CreateFlags |= SHFL_CF_ACCESS_APPEND; } params.Info.Attr.fMode = inode->i_mode; LogFunc(("sf_reg_open: calling VbglR0SfCreate, file %s, flags=%#x, %#x\n", sf_i->path->String.utf8 , file->f_flags, params.CreateFlags)); rc = VbglR0SfCreate(&client_handle, &sf_g->map, sf_i->path, ¶ms); if (RT_FAILURE(rc)) { LogFunc(("VbglR0SfCreate failed flags=%d,%#x rc=%Rrc\n", file->f_flags, params.CreateFlags, rc)); kfree(sf_r); return -RTErrConvertToErrno(rc); } if (SHFL_HANDLE_NIL == params.Handle) { switch (params.Result) { case SHFL_PATH_NOT_FOUND: case SHFL_FILE_NOT_FOUND: rc_linux = -ENOENT; break; case SHFL_FILE_EXISTS: rc_linux = -EEXIST; break; default: break; } } sf_i->force_restat = 1; sf_r->handle = params.Handle; sf_i->file = file; file->private_data = sf_r; return rc_linux; }
static int paStreamOpen(PDRVHOSTPULSEAUDIO pThis, bool fIn, const char *pszName, pa_sample_spec *pSampleSpec, pa_buffer_attr *pBufAttr, pa_stream **ppStream) { AssertPtrReturn(pThis, VERR_INVALID_POINTER); AssertPtrReturn(pszName, VERR_INVALID_POINTER); AssertPtrReturn(pSampleSpec, VERR_INVALID_POINTER); AssertPtrReturn(pBufAttr, VERR_INVALID_POINTER); AssertPtrReturn(ppStream, VERR_INVALID_POINTER); if (!pa_sample_spec_valid(pSampleSpec)) { LogRel(("PulseAudio: Unsupported sample specification for stream \"%s\"\n", pszName)); return VERR_NOT_SUPPORTED; } int rc = VINF_SUCCESS; pa_stream *pStream = NULL; uint32_t flags = PA_STREAM_NOFLAGS; LogFunc(("Opening \"%s\", rate=%dHz, channels=%d, format=%s\n", pszName, pSampleSpec->rate, pSampleSpec->channels, pa_sample_format_to_string(pSampleSpec->format))); pa_threaded_mainloop_lock(pThis->pMainLoop); do { /** @todo r=andy Use pa_stream_new_with_proplist instead. */ if (!(pStream = pa_stream_new(pThis->pContext, pszName, pSampleSpec, NULL /* pa_channel_map */))) { LogRel(("PulseAudio: Could not create stream \"%s\"\n", pszName)); rc = VERR_NO_MEMORY; break; } pa_stream_set_state_callback(pStream, paStreamCbStateChanged, pThis); #if PA_API_VERSION >= 12 /* XXX */ flags |= PA_STREAM_ADJUST_LATENCY; #endif #if 0 /* Not applicable as we don't use pa_stream_get_latency() and pa_stream_get_time(). */ flags |= PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE; #endif /* No input/output right away after the stream was started. */ flags |= PA_STREAM_START_CORKED; if (fIn) { LogFunc(("Input stream attributes: maxlength=%d fragsize=%d\n", pBufAttr->maxlength, pBufAttr->fragsize)); if (pa_stream_connect_record(pStream, /*dev=*/NULL, pBufAttr, (pa_stream_flags_t)flags) < 0) { LogRel(("PulseAudio: Could not connect input stream \"%s\": %s\n", pszName, pa_strerror(pa_context_errno(pThis->pContext)))); rc = VERR_AUDIO_BACKEND_INIT_FAILED; break; } } else { LogFunc(("Output buffer attributes: maxlength=%d tlength=%d prebuf=%d minreq=%d\n", pBufAttr->maxlength, pBufAttr->tlength, pBufAttr->prebuf, pBufAttr->minreq)); if (pa_stream_connect_playback(pStream, /*dev=*/NULL, pBufAttr, (pa_stream_flags_t)flags, /*cvolume=*/NULL, /*sync_stream=*/NULL) < 0) { LogRel(("PulseAudio: Could not connect playback stream \"%s\": %s\n", pszName, pa_strerror(pa_context_errno(pThis->pContext)))); rc = VERR_AUDIO_BACKEND_INIT_FAILED; break; } } /* Wait until the stream is ready. */ for (;;) { if (!pThis->fLoopWait) pa_threaded_mainloop_wait(pThis->pMainLoop); pThis->fLoopWait = false; pa_stream_state_t streamSt = pa_stream_get_state(pStream); if (streamSt == PA_STREAM_READY) break; else if ( streamSt == PA_STREAM_FAILED || streamSt == PA_STREAM_TERMINATED) { LogRel(("PulseAudio: Failed to initialize stream \"%s\" (state %ld)\n", pszName, streamSt)); rc = VERR_AUDIO_BACKEND_INIT_FAILED; break; } } if (RT_FAILURE(rc)) break; const pa_buffer_attr *pBufAttrObtained = pa_stream_get_buffer_attr(pStream); AssertPtr(pBufAttrObtained); memcpy(pBufAttr, pBufAttrObtained, sizeof(pa_buffer_attr)); if (fIn) LogFunc(("Obtained record buffer attributes: maxlength=%RU32, fragsize=%RU32\n", pBufAttr->maxlength, pBufAttr->fragsize)); else LogFunc(("Obtained playback buffer attributes: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d\n", pBufAttr->maxlength, pBufAttr->tlength, pBufAttr->prebuf, pBufAttr->minreq)); } while (0); if ( RT_FAILURE(rc) && pStream) pa_stream_disconnect(pStream); pa_threaded_mainloop_unlock(pThis->pMainLoop); if (RT_FAILURE(rc)) { if (pStream) pa_stream_unref(pStream); } else *ppStream = pStream; LogFlowFuncLeaveRC(rc); return rc; }
HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks) { HRESULT hr = S_OK; memset(pCallbacks, 0, sizeof (*pCallbacks)); pCallbacks->hGdi32 = loadSystemDll("gdi32.dll"); if (pCallbacks->hGdi32 != NULL) { bool bSupported = true; bool bSupportedWin8 = true; pCallbacks->pfnD3DKMTOpenAdapterFromHdc = (PFND3DKMT_OPENADAPTERFROMHDC)GetProcAddress(pCallbacks->hGdi32, "D3DKMTOpenAdapterFromHdc"); LogFunc(("pfnD3DKMTOpenAdapterFromHdc = %p\n", pCallbacks->pfnD3DKMTOpenAdapterFromHdc)); bSupported &= !!(pCallbacks->pfnD3DKMTOpenAdapterFromHdc); pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName = (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)GetProcAddress(pCallbacks->hGdi32, "D3DKMTOpenAdapterFromGdiDisplayName"); LogFunc(("pfnD3DKMTOpenAdapterFromGdiDisplayName = %p\n", pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName)); bSupported &= !!(pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName); pCallbacks->pfnD3DKMTCloseAdapter = (PFND3DKMT_CLOSEADAPTER)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCloseAdapter"); LogFunc(("pfnD3DKMTCloseAdapter = %p\n", pCallbacks->pfnD3DKMTCloseAdapter)); bSupported &= !!(pCallbacks->pfnD3DKMTCloseAdapter); pCallbacks->pfnD3DKMTEscape = (PFND3DKMT_ESCAPE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEscape"); LogFunc(("pfnD3DKMTEscape = %p\n", pCallbacks->pfnD3DKMTEscape)); bSupported &= !!(pCallbacks->pfnD3DKMTEscape); pCallbacks->pfnD3DKMTQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO)GetProcAddress(pCallbacks->hGdi32, "D3DKMTQueryAdapterInfo"); LogFunc(("pfnD3DKMTQueryAdapterInfo = %p\n", pCallbacks->pfnD3DKMTQueryAdapterInfo)); bSupported &= !!(pCallbacks->pfnD3DKMTQueryAdapterInfo); pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice"); LogFunc(("pfnD3DKMTCreateDevice = %p\n", pCallbacks->pfnD3DKMTCreateDevice)); bSupported &= !!(pCallbacks->pfnD3DKMTCreateDevice); pCallbacks->pfnD3DKMTDestroyDevice = (PFND3DKMT_DESTROYDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyDevice"); LogFunc(("pfnD3DKMTDestroyDevice = %p\n", pCallbacks->pfnD3DKMTDestroyDevice)); bSupported &= !!(pCallbacks->pfnD3DKMTDestroyDevice); pCallbacks->pfnD3DKMTCreateContext = (PFND3DKMT_CREATECONTEXT)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateContext"); LogFunc(("pfnD3DKMTCreateContext = %p\n", pCallbacks->pfnD3DKMTCreateContext)); bSupported &= !!(pCallbacks->pfnD3DKMTCreateContext); pCallbacks->pfnD3DKMTDestroyContext = (PFND3DKMT_DESTROYCONTEXT)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyContext"); LogFunc(("pfnD3DKMTDestroyContext = %p\n", pCallbacks->pfnD3DKMTDestroyContext)); bSupported &= !!(pCallbacks->pfnD3DKMTDestroyContext); pCallbacks->pfnD3DKMTRender = (PFND3DKMT_RENDER)GetProcAddress(pCallbacks->hGdi32, "D3DKMTRender"); LogFunc(("pfnD3DKMTRender = %p\n", pCallbacks->pfnD3DKMTRender)); bSupported &= !!(pCallbacks->pfnD3DKMTRender); pCallbacks->pfnD3DKMTCreateAllocation = (PFND3DKMT_CREATEALLOCATION)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateAllocation"); LogFunc(("pfnD3DKMTCreateAllocation = %p\n", pCallbacks->pfnD3DKMTCreateAllocation)); bSupported &= !!(pCallbacks->pfnD3DKMTCreateAllocation); pCallbacks->pfnD3DKMTDestroyAllocation = (PFND3DKMT_DESTROYALLOCATION)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyAllocation"); LogFunc(("pfnD3DKMTDestroyAllocation = %p\n", pCallbacks->pfnD3DKMTDestroyAllocation)); bSupported &= !!(pCallbacks->pfnD3DKMTDestroyAllocation); pCallbacks->pfnD3DKMTLock = (PFND3DKMT_LOCK)GetProcAddress(pCallbacks->hGdi32, "D3DKMTLock"); LogFunc(("pfnD3DKMTLock = %p\n", pCallbacks->pfnD3DKMTLock)); bSupported &= !!(pCallbacks->pfnD3DKMTLock); pCallbacks->pfnD3DKMTUnlock = (PFND3DKMT_UNLOCK)GetProcAddress(pCallbacks->hGdi32, "D3DKMTUnlock"); LogFunc(("pfnD3DKMTUnlock = %p\n", pCallbacks->pfnD3DKMTUnlock)); bSupported &= !!(pCallbacks->pfnD3DKMTUnlock); pCallbacks->pfnD3DKMTInvalidateActiveVidPn = (PFND3DKMT_INVALIDATEACTIVEVIDPN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTInvalidateActiveVidPn"); LogFunc(("pfnD3DKMTInvalidateActiveVidPn = %p\n", pCallbacks->pfnD3DKMTInvalidateActiveVidPn)); bSupported &= !!(pCallbacks->pfnD3DKMTInvalidateActiveVidPn); pCallbacks->pfnD3DKMTPollDisplayChildren = (PFND3DKMT_POLLDISPLAYCHILDREN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTPollDisplayChildren"); LogFunc(("pfnD3DKMTPollDisplayChildren = %p\n", pCallbacks->pfnD3DKMTPollDisplayChildren)); bSupported &= !!(pCallbacks->pfnD3DKMTPollDisplayChildren); pCallbacks->pfnD3DKMTEnumAdapters = (PFND3DKMT_ENUMADAPTERS)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEnumAdapters"); LogFunc(("pfnD3DKMTEnumAdapters = %p\n", pCallbacks->pfnD3DKMTEnumAdapters)); /* this present starting win8 release preview only, so keep going if it is not available, * i.e. do not clear the bSupported on its absence */ bSupportedWin8 &= !!(pCallbacks->pfnD3DKMTEnumAdapters); pCallbacks->pfnD3DKMTOpenAdapterFromLuid = (PFND3DKMT_OPENADAPTERFROMLUID)GetProcAddress(pCallbacks->hGdi32, "D3DKMTOpenAdapterFromLuid"); LogFunc(("pfnD3DKMTOpenAdapterFromLuid = %p\n", pCallbacks->pfnD3DKMTOpenAdapterFromLuid)); /* this present starting win8 release preview only, so keep going if it is not available, * i.e. do not clear the bSupported on its absence */ bSupportedWin8 &= !!(pCallbacks->pfnD3DKMTOpenAdapterFromLuid); /*Assert(bSupported);*/ if (bSupported) { if (bSupportedWin8) pCallbacks->enmVersion = VBOXDISPKMT_CALLBACKS_VERSION_WIN8; else pCallbacks->enmVersion = VBOXDISPKMT_CALLBACKS_VERSION_VISTA_WIN7; return S_OK; } else { LogFunc(("one of pfnD3DKMT function pointers failed to initialize\n")); hr = E_NOINTERFACE; } FreeLibrary(pCallbacks->hGdi32); } else { DWORD winEr = GetLastError(); hr = HRESULT_FROM_WIN32(winEr); Assert(0); Assert(hr != S_OK); Assert(hr != S_FALSE); if (hr == S_OK || hr == S_FALSE) hr = E_FAIL; } return hr; }
void HostPowerService::notify(Reason_T aReason) { SessionMachinesList machines; VirtualBox::InternalControlList controls; HRESULT rc = S_OK; switch (aReason) { case Reason_HostSuspend: { LogFunc(("HOST SUSPEND\n")); #ifdef VBOX_WITH_RESOURCE_USAGE_API /* Suspend performance sampling to avoid unnecessary callbacks due to jumps in time. */ PerformanceCollector *perfcollector = mVirtualBox->i_performanceCollector(); if (perfcollector) perfcollector->suspendSampling(); #endif mVirtualBox->i_getOpenedMachines(machines, &controls); /* pause running VMs */ for (VirtualBox::InternalControlList::const_iterator it = controls.begin(); it != controls.end(); ++it) { ComPtr<IInternalSessionControl> pControl = *it; /* PauseWithReason() will simply return a failure if * the VM is in an inappropriate state */ rc = pControl->PauseWithReason(Reason_HostSuspend); if (FAILED(rc)) continue; /* save the control to un-pause the VM later */ mSessionControls.push_back(pControl); } LogRel(("Host suspending: Paused %d VMs\n", mSessionControls.size())); break; } case Reason_HostResume: { LogFunc(("HOST RESUME\n")); size_t resumed = 0; /* go through VMs we paused on Suspend */ for (size_t i = 0; i < mSessionControls.size(); ++i) { /* note that Resume() will simply return a failure if the VM is * in an inappropriate state (it will also fail if the VM has * been somehow closed by this time already so that the * console reference we have is dead) */ rc = mSessionControls[i]->ResumeWithReason(Reason_HostResume); if (FAILED(rc)) continue; ++resumed; } LogRel(("Host resumed: Resumed %d VMs\n", resumed)); #ifdef VBOX_WITH_RESOURCE_USAGE_API /* Resume the performance sampling. */ PerformanceCollector *perfcollector = mVirtualBox->i_performanceCollector(); if (perfcollector) perfcollector->resumeSampling(); #endif mSessionControls.clear(); break; } case Reason_HostBatteryLow: { LogFunc(("BATTERY LOW\n")); Bstr value; rc = mVirtualBox->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(), value.asOutParam()); int fGlobal = 0; if (SUCCEEDED(rc) && !value.isEmpty()) { if (value != "0") fGlobal = 1; else if (value == "0") fGlobal = -1; } mVirtualBox->i_getOpenedMachines(machines, &controls); size_t saved = 0; /* save running VMs */ for (SessionMachinesList::const_iterator it = machines.begin(); it != machines.end(); ++it) { ComPtr<SessionMachine> pMachine = *it; rc = pMachine->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(), value.asOutParam()); int fPerVM = 0; if (SUCCEEDED(rc) && !value.isEmpty()) { /* per-VM overrides global */ if (value != "0") fPerVM = 2; else if (value == "0") fPerVM = -2; } /* default is true */ if (fGlobal + fPerVM >= 0) { ComPtr<IProgress> progress; /* SessionMachine::i_saveStateWithReason() will return * a failure if the VM is in an inappropriate state */ rc = pMachine->i_saveStateWithReason(Reason_HostBatteryLow, progress); if (FAILED(rc)) { LogRel(("SaveState '%s' failed with %Rhrc\n", pMachine->i_getName().c_str(), rc)); continue; } /* Wait until the operation has been completed. */ rc = progress->WaitForCompletion(-1); if (SUCCEEDED(rc)) { LONG iRc; progress->COMGETTER(ResultCode)(&iRc); rc = iRc; } AssertMsg(SUCCEEDED(rc), ("SaveState WaitForCompletion failed with %Rhrc (%#08X)\n", rc, rc)); if (SUCCEEDED(rc)) { LogRel(("SaveState '%s' succeeded\n", pMachine->i_getName().c_str())); ++saved; } } } LogRel(("Battery Low: saved %d VMs\n", saved)); break; } default: /* nothing */; } }
/* m->m_data points at ip packet header * m->m_len length ip packet * ip->ip_len length data (IPDU) */ void udp_input(PNATState pData, register struct mbuf *m, int iphlen) { register struct ip *ip; register struct udphdr *uh; int len; struct ip save_ip; struct socket *so; int ret; int ttl, tos; LogFlowFunc(("ENTER: m = %p, iphlen = %d\n", m, iphlen)); ip = mtod(m, struct ip *); Log2(("%RTnaipv4 iphlen = %d\n", ip->ip_dst, iphlen)); udpstat.udps_ipackets++; /* * Strip IP options, if any; should skip this, * make available to user, and use on returned packets, * but we don't yet have a way to check the checksum * with options still present. */ if (iphlen > sizeof(struct ip)) { ip_stripoptions(m, (struct mbuf *)0); iphlen = sizeof(struct ip); } /* * Get IP and UDP header together in first mbuf. */ ip = mtod(m, struct ip *); uh = (struct udphdr *)((caddr_t)ip + iphlen); /* * Make mbuf data length reflect UDP length. * If not enough data to reflect UDP length, drop. */ len = RT_N2H_U16((u_int16_t)uh->uh_ulen); Assert(ip->ip_len + iphlen == (ssize_t)m_length(m, NULL)); if (ip->ip_len != len) { if (len > ip->ip_len) { udpstat.udps_badlen++; Log3(("NAT: IP(id: %hd) has bad size\n", ip->ip_id)); goto bad_free_mbuf; } m_adj(m, len - ip->ip_len); ip->ip_len = len; } /* * Save a copy of the IP header in case we want restore it * for sending an ICMP error message in response. */ save_ip = *ip; save_ip.ip_len+= iphlen; /* tcp_input subtracts this */ /* * Checksum extended UDP header and data. */ if (udpcksum && uh->uh_sum) { memset(((struct ipovly *)ip)->ih_x1, 0, 9); ((struct ipovly *)ip)->ih_len = uh->uh_ulen; #if 0 /* keep uh_sum for ICMP reply */ uh->uh_sum = cksum(m, len + sizeof (struct ip)); if (uh->uh_sum) { #endif if (cksum(m, len + iphlen)) { udpstat.udps_badsum++; Log3(("NAT: IP(id: %hd) has bad (udp) cksum\n", ip->ip_id)); goto bad_free_mbuf; } } #if 0 } #endif /* * handle DHCP/BOOTP */ if (uh->uh_dport == RT_H2N_U16_C(BOOTP_SERVER)) { bootp_input(pData, m); goto done_free_mbuf; } LogFunc(("uh src: %RTnaipv4:%d, dst: %RTnaipv4:%d\n", ip->ip_src.s_addr, RT_N2H_U16(uh->uh_sport), ip->ip_dst.s_addr, RT_N2H_U16(uh->uh_dport))); /* * handle DNS host resolver without creating a socket */ if ( pData->fUseHostResolver && uh->uh_dport == RT_H2N_U16_C(53) && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS)) { struct sockaddr_in dst, src; src.sin_addr.s_addr = ip->ip_dst.s_addr; src.sin_port = uh->uh_dport; dst.sin_addr.s_addr = ip->ip_src.s_addr; dst.sin_port = uh->uh_sport; m_adj(m, sizeof(struct udpiphdr)); m = hostresolver(pData, m, ip->ip_src.s_addr, uh->uh_sport); if (m == NULL) goto done_free_mbuf; slirpMbufTagService(pData, m, CTL_DNS); udp_output2(pData, NULL, m, &src, &dst, IPTOS_LOWDELAY); LogFlowFuncLeave(); return; } /* * handle TFTP */ if ( uh->uh_dport == RT_H2N_U16_C(TFTP_SERVER) && CTL_CHECK(ip->ip_dst.s_addr, CTL_TFTP)) { if (pData->pvTftpSessions) slirpTftpInput(pData, m); goto done_free_mbuf; } /* * XXX: DNS proxy currently relies on the fact that each socket * only serves one request. */ if ( pData->fUseDnsProxy && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS) && (uh->uh_dport == RT_H2N_U16_C(53))) { so = NULL; goto new_socket; } /* * Locate pcb for datagram. */ so = udp_last_so; if ( so->so_lport != uh->uh_sport || so->so_laddr.s_addr != ip->ip_src.s_addr) { struct socket *tmp; for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { if ( tmp->so_lport == uh->uh_sport && tmp->so_laddr.s_addr == ip->ip_src.s_addr) { so = tmp; break; } } if (tmp == &udb) so = NULL; else { udpstat.udpps_pcbcachemiss++; udp_last_so = so; } } new_socket: if (so == NULL) { /* * If there's no socket for this packet, * create one */ if ((so = socreate()) == NULL) { Log2(("NAT: IP(id: %hd) failed to create socket\n", ip->ip_id)); goto bad_free_mbuf; } if (udp_attach(pData, so) <= 0) { Log2(("NAT: IP(id: %hd) udp_attach errno = %d (%s)\n", ip->ip_id, errno, strerror(errno))); sofree(pData, so); goto bad_free_mbuf; } /* * Setup fields */ /* udp_last_so = so; */ so->so_laddr = ip->ip_src; so->so_lport = uh->uh_sport; so->so_iptos = ip->ip_tos; /* * XXXXX Here, check if it's in udpexec_list, * and if it is, do the fork_exec() etc. */ } so->so_faddr = ip->ip_dst; /* XXX */ so->so_fport = uh->uh_dport; /* XXX */ Assert(so->so_type == IPPROTO_UDP); /* * DNS proxy */ if ( pData->fUseDnsProxy && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS) && (uh->uh_dport == RT_H2N_U16_C(53))) { dnsproxy_query(pData, so, m, iphlen); goto done_free_mbuf; } iphlen += sizeof(struct udphdr); m->m_len -= iphlen; m->m_data += iphlen; ttl = ip->ip_ttl = save_ip.ip_ttl; if (ttl != so->so_sottl) { ret = setsockopt(so->s, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)); if (RT_LIKELY(ret == 0)) so->so_sottl = ttl; } tos = save_ip.ip_tos; if (tos != so->so_sotos) { ret = setsockopt(so->s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(tos)); if (RT_LIKELY(ret == 0)) so->so_sotos = tos; } { /* * Different OSes have different socket options for DF. We * can't use IP_HDRINCL here as it's only valid for SOCK_RAW. */ # define USE_DF_OPTION(_Optname) \ const int dfopt = _Optname #if defined(IP_MTU_DISCOVER) USE_DF_OPTION(IP_MTU_DISCOVER); #elif defined(IP_DONTFRAG) /* Solaris 11+, FreeBSD */ USE_DF_OPTION(IP_DONTFRAG); #elif defined(IP_DONTFRAGMENT) /* Windows */ USE_DF_OPTION(IP_DONTFRAGMENT); #else USE_DF_OPTION(0); #endif if (dfopt) { int df = (save_ip.ip_off & IP_DF) != 0; #if defined(IP_MTU_DISCOVER) df = df ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; #endif if (df != so->so_sodf) { ret = setsockopt(so->s, IPPROTO_IP, dfopt, (char *)&df, sizeof(df)); if (RT_LIKELY(ret == 0)) so->so_sodf = df; } } } if ( sosendto(pData, so, m) == -1 && ( !soIgnorableErrorCode(errno) && errno != ENOTCONN)) { m->m_len += iphlen; m->m_data -= iphlen; *ip = save_ip; Log2(("NAT: UDP tx errno = %d (%s) on sent to %RTnaipv4\n", errno, strerror(errno), ip->ip_dst)); icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno)); so->so_m = NULL; LogFlowFuncLeave(); return; } if (so->so_m) m_freem(pData, so->so_m); /* used for ICMP if error on sorecvfrom */ /* restore the orig mbuf packet */ m->m_len += iphlen; m->m_data -= iphlen; *ip = save_ip; so->so_m = m; /* ICMP backup */ LogFlowFuncLeave(); return; bad_free_mbuf: Log2(("NAT: UDP(id: %hd) datagram to %RTnaipv4 with size(%d) claimed as bad\n", ip->ip_id, &ip->ip_dst, ip->ip_len)); done_free_mbuf: /* some services like bootp(built-in), dns(buildt-in) and dhcp don't need sockets * and create new m'buffers to send them to guest, so we'll free their incomming * buffers here. */ if (m != NULL) m_freem(pData, m); LogFlowFuncLeave(); return; }
static bool vboxHwBufferWrite(PVBVAEXBUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, const void *p, uint32_t cb) { VBVARECORD *pRecord; uint32_t cbHwBufferAvail; uint32_t cbWritten = 0; VBVABUFFER *pVBVA = pCtx->pVBVA; Assert(pVBVA); if (!pVBVA || pCtx->fHwBufferOverflow) { return false; } Assert(pVBVA->indexRecordFirst != pVBVA->indexRecordFree); Assert(pCtx->indexRecordFirstUncompleted != pVBVA->indexRecordFree); pRecord = pCtx->pRecord; Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL)); // LogFunc(("%d\n", cb)); cbHwBufferAvail = vboxHwBufferAvail(pCtx, pVBVA); while (cb > 0) { uint32_t cbChunk = cb; // LogFunc(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n", // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten)); if (cbChunk >= cbHwBufferAvail) { LogFunc(("1) avail %d, chunk %d\n", cbHwBufferAvail, cbChunk)); vboxVBVAExFlush(pCtx, pHGSMICtx); cbHwBufferAvail = vboxHwBufferAvail(pCtx, pVBVA); if (cbChunk >= cbHwBufferAvail) { WARN(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.\n", cb, cbHwBufferAvail)); if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold) { WARN(("Buffer overflow!!!\n")); pCtx->fHwBufferOverflow = true; Assert(false); return false; } cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold; } } Assert(cbChunk <= cb); Assert(cbChunk <= vboxHwBufferAvail(pCtx, pVBVA)); vboxHwBufferPlaceDataAt (pCtx, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free); pVBVA->off32Free = (pVBVA->off32Free + cbChunk) % pVBVA->cbData; pRecord->cbRecord += cbChunk; cbHwBufferAvail -= cbChunk; cb -= cbChunk; cbWritten += cbChunk; } return true; }
/* m->m_data points at ip packet header * m->m_len length ip packet * ip->ip_len length data (IPDU) */ void udp_input(PNATState pData, register struct mbuf *m, int iphlen) { register struct ip *ip; register struct udphdr *uh; int len; struct ip save_ip; struct socket *so; int ret; int ttl; LogFlowFunc(("ENTER: m = %p, iphlen = %d\n", m, iphlen)); ip = mtod(m, struct ip *); Log2(("%RTnaipv4 iphlen = %d\n", ip->ip_dst, iphlen)); udpstat.udps_ipackets++; /* * Strip IP options, if any; should skip this, * make available to user, and use on returned packets, * but we don't yet have a way to check the checksum * with options still present. */ if (iphlen > sizeof(struct ip)) { ip_stripoptions(m, (struct mbuf *)0); iphlen = sizeof(struct ip); } /* * Get IP and UDP header together in first mbuf. */ ip = mtod(m, struct ip *); uh = (struct udphdr *)((caddr_t)ip + iphlen); /* * Make mbuf data length reflect UDP length. * If not enough data to reflect UDP length, drop. */ len = RT_N2H_U16((u_int16_t)uh->uh_ulen); Assert((ip->ip_len == len)); Assert((ip->ip_len + iphlen == m_length(m, NULL))); if (ip->ip_len != len) { if (len > ip->ip_len) { udpstat.udps_badlen++; Log3(("NAT: IP(id: %hd) has bad size\n", ip->ip_id)); } m_adj(m, len - ip->ip_len); ip->ip_len = len; } /* * Save a copy of the IP header in case we want restore it * for sending an ICMP error message in response. */ save_ip = *ip; save_ip.ip_len+= iphlen; /* tcp_input subtracts this */ /* * Checksum extended UDP header and data. */ if (udpcksum && uh->uh_sum) { memset(((struct ipovly *)ip)->ih_x1, 0, 9); ((struct ipovly *)ip)->ih_len = uh->uh_ulen; #if 0 /* keep uh_sum for ICMP reply */ uh->uh_sum = cksum(m, len + sizeof (struct ip)); if (uh->uh_sum) { #endif if (cksum(m, len + iphlen)) { udpstat.udps_badsum++; Log3(("NAT: IP(id: %hd) has bad (udp) cksum\n", ip->ip_id)); goto bad_free_mbuf; } } #if 0 } #endif /* * handle DHCP/BOOTP */ if (uh->uh_dport == RT_H2N_U16_C(BOOTP_SERVER)) { bootp_input(pData, m); goto done_free_mbuf; } LogFunc(("uh src: %RTnaipv4:%d, dst: %RTnaipv4:%d\n", ip->ip_src, RT_H2N_U16_C(uh->uh_sport), ip->ip_dst, RT_H2N_U16_C(uh->uh_dport))); if ( pData->fUseHostResolver && uh->uh_dport == RT_H2N_U16_C(53) && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS)) { struct sockaddr_in dst, src; src.sin_addr.s_addr = ip->ip_dst.s_addr; src.sin_port = uh->uh_dport; dst.sin_addr.s_addr = ip->ip_src.s_addr; dst.sin_port = uh->uh_sport; slirpMbufTagService(pData, m, CTL_DNS); /* udp_output2() expects a pointer to the body of UDP packet. */ m->m_data += sizeof(struct udpiphdr); m->m_len -= sizeof(struct udpiphdr); udp_output2(pData, NULL, m, &src, &dst, IPTOS_LOWDELAY); LogFlowFuncLeave(); return; } /* * handle TFTP */ if ( uh->uh_dport == RT_H2N_U16_C(TFTP_SERVER) && CTL_CHECK(ip->ip_dst.s_addr, CTL_TFTP)) { if (pData->pvTftpSessions) slirpTftpInput(pData, m); goto done_free_mbuf; } /* * Locate pcb for datagram. */ so = udp_last_so; if ( so->so_lport != uh->uh_sport || so->so_laddr.s_addr != ip->ip_src.s_addr) { struct socket *tmp; for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { if ( tmp->so_lport == uh->uh_sport && tmp->so_laddr.s_addr == ip->ip_src.s_addr) { so = tmp; break; } } if (tmp == &udb) so = NULL; else { udpstat.udpps_pcbcachemiss++; udp_last_so = so; } } if (so == NULL) { /* * If there's no socket for this packet, * create one */ if ((so = socreate()) == NULL) { Log2(("NAT: IP(id: %hd) failed to create socket\n", ip->ip_id)); goto bad_free_mbuf; } if (udp_attach(pData, so) <= 0) { Log2(("NAT: IP(id: %hd) udp_attach errno = %d (%s)\n", ip->ip_id, errno, strerror(errno))); sofree(pData, so); goto bad_free_mbuf; } /* * Setup fields */ /* udp_last_so = so; */ so->so_laddr = ip->ip_src; so->so_lport = uh->uh_sport; so->so_iptos = ip->ip_tos; /* * XXXXX Here, check if it's in udpexec_list, * and if it is, do the fork_exec() etc. */ } so->so_faddr = ip->ip_dst; /* XXX */ so->so_fport = uh->uh_dport; /* XXX */ Assert(so->so_type == IPPROTO_UDP); /* * DNS proxy */ if ( pData->fUseDnsProxy && CTL_CHECK(ip->ip_dst.s_addr, CTL_DNS) && (uh->uh_dport == RT_H2N_U16_C(53))) { dnsproxy_query(pData, so, m, iphlen); goto done_free_mbuf; } iphlen += sizeof(struct udphdr); m->m_len -= iphlen; m->m_data += iphlen; ttl = ip->ip_ttl = save_ip.ip_ttl; ret = setsockopt(so->s, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof(ttl)); if (ret < 0) LogRel(("NAT: Error (%s) occurred while setting TTL(%d) attribute " "of IP packet to socket %R[natsock]\n", strerror(errno), ip->ip_ttl, so)); if ( sosendto(pData, so, m) == -1 && ( !soIgnorableErrorCode(errno) && errno != ENOTCONN)) { m->m_len += iphlen; m->m_data -= iphlen; *ip = save_ip; Log2(("NAT: UDP tx errno = %d (%s) on sent to %RTnaipv4\n", errno, strerror(errno), ip->ip_dst)); #if 0 /* ICMP_SOURCEQUENCH haven't got any effect, the idea here * inform guest about the exosting NAT resources with assumption that * that guest reduce traffic. But it doesn't work */ if( errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS || errno == ENOTCONN) icmp_error(pData, m, ICMP_SOURCEQUENCH, 0, 1, strerror(errno)); else #endif icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno)); so->so_m = NULL; LogFlowFuncLeave(); return; } if (so->so_m) m_freem(pData, so->so_m); /* used for ICMP if error on sorecvfrom */ /* restore the orig mbuf packet */ m->m_len += iphlen; m->m_data -= iphlen; *ip = save_ip; so->so_m = m; /* ICMP backup */ LogFlowFuncLeave(); return; bad_free_mbuf: Log2(("NAT: UDP(id: %hd) datagram to %RTnaipv4 with size(%d) claimed as bad\n", ip->ip_id, &ip->ip_dst, ip->ip_len)); done_free_mbuf: /* some services like bootp(built-in), dns(buildt-in) and dhcp don't need sockets * and create new m'buffers to send them to guest, so we'll free their incomming * buffers here. */ m_freem(pData, m); LogFlowFuncLeave(); return; }
int sf_setattr(struct dentry *dentry, struct iattr *iattr) { struct sf_glob_info *sf_g; struct sf_inode_info *sf_i; SHFLCREATEPARMS params; SHFLFSOBJINFO info; uint32_t cbBuffer; int rc, err; TRACE(); sf_g = GET_GLOB_INFO(dentry->d_inode->i_sb); sf_i = GET_INODE_INFO(dentry->d_inode); err = 0; RT_ZERO(params); params.Handle = SHFL_HANDLE_NIL; params.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_ATTR_WRITE; /* this is at least required for Posix hosts */ if (iattr->ia_valid & ATTR_SIZE) params.CreateFlags |= SHFL_CF_ACCESS_WRITE; rc = vboxCallCreate(&client_handle, &sf_g->map, sf_i->path, ¶ms); if (RT_FAILURE(rc)) { LogFunc(("vboxCallCreate(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); err = -RTErrConvertToErrno(rc); goto fail2; } if (params.Result != SHFL_FILE_EXISTS) { LogFunc(("file %s does not exist\n", sf_i->path->String.utf8)); err = -ENOENT; goto fail1; } /* Setting the file size and setting the other attributes has to be * handled separately, see implementation of vbsfSetFSInfo() in * vbsf.cpp */ if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME)) { #define mode_set(r) ((iattr->ia_mode & (S_##r)) ? RTFS_UNIX_##r : 0) RT_ZERO(info); if (iattr->ia_valid & ATTR_MODE) { info.Attr.fMode = mode_set(ISUID); info.Attr.fMode |= mode_set(ISGID); info.Attr.fMode |= mode_set(IRUSR); info.Attr.fMode |= mode_set(IWUSR); info.Attr.fMode |= mode_set(IXUSR); info.Attr.fMode |= mode_set(IRGRP); info.Attr.fMode |= mode_set(IWGRP); info.Attr.fMode |= mode_set(IXGRP); info.Attr.fMode |= mode_set(IROTH); info.Attr.fMode |= mode_set(IWOTH); info.Attr.fMode |= mode_set(IXOTH); if (iattr->ia_mode & S_IFDIR) info.Attr.fMode |= RTFS_TYPE_DIRECTORY; else info.Attr.fMode |= RTFS_TYPE_FILE; } if (iattr->ia_valid & ATTR_ATIME) sf_timespec_from_ftime(&info.AccessTime, &iattr->ia_atime); if (iattr->ia_valid & ATTR_MTIME) sf_timespec_from_ftime(&info.ModificationTime, &iattr->ia_mtime); /* ignore ctime (inode change time) as it can't be set from userland anyway */ cbBuffer = sizeof(info); rc = vboxCallFSInfo(&client_handle, &sf_g->map, params.Handle, SHFL_INFO_SET | SHFL_INFO_FILE, &cbBuffer, (PSHFLDIRINFO)&info); if (RT_FAILURE(rc)) { LogFunc(("vboxCallFSInfo(%s, FILE) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); err = -RTErrConvertToErrno(rc); goto fail1; } } if (iattr->ia_valid & ATTR_SIZE) { RT_ZERO(info); info.cbObject = iattr->ia_size; cbBuffer = sizeof(info); rc = vboxCallFSInfo(&client_handle, &sf_g->map, params.Handle, SHFL_INFO_SET | SHFL_INFO_SIZE, &cbBuffer, (PSHFLDIRINFO)&info); if (RT_FAILURE(rc)) { LogFunc(("vboxCallFSInfo(%s, SIZE) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); err = -RTErrConvertToErrno(rc); goto fail1; } } rc = vboxCallClose(&client_handle, &sf_g->map, params.Handle); if (RT_FAILURE(rc)) LogFunc(("vboxCallClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); return sf_inode_revalidate(dentry); fail1: rc = vboxCallClose(&client_handle, &sf_g->map, params.Handle); if (RT_FAILURE(rc)) LogFunc(("vboxCallClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); fail2: return err; }
/** * This is called (by sf_read_super_[24|26] when vfs mounts the fs and * wants to read super_block. * * calls [sf_glob_alloc] to map the folder and allocate global * information structure. * * initializes [sb], initializes root inode and dentry. * * should respect [flags] */ static int sf_read_super_aux(struct super_block *sb, void *data, int flags) { int err; struct dentry *droot; struct inode *iroot; struct sf_inode_info *sf_i; struct sf_glob_info *sf_g; SHFLFSOBJINFO fsinfo; struct vbsf_mount_info_new *info; TRACE(); if (!data) { LogFunc(("no mount info specified\n")); return -EINVAL; } info = data; if (flags & MS_REMOUNT) { LogFunc(("remounting is not supported\n")); return -ENOSYS; } err = sf_glob_alloc(info, &sf_g); if (err) goto fail0; sf_i = kmalloc(sizeof (*sf_i), GFP_KERNEL); if (!sf_i) { err = -ENOMEM; LogRelFunc(("could not allocate memory for root inode info\n")); goto fail1; } sf_i->handle = SHFL_HANDLE_NIL; sf_i->path = kmalloc(sizeof(SHFLSTRING) + 1, GFP_KERNEL); if (!sf_i->path) { err = -ENOMEM; LogRelFunc(("could not allocate memory for root inode path\n")); goto fail2; } sf_i->path->u16Length = 1; sf_i->path->u16Size = 2; sf_i->path->String.utf8[0] = '/'; sf_i->path->String.utf8[1] = 0; err = sf_stat(__func__, sf_g, sf_i->path, &fsinfo, 0); if (err) { LogFunc(("could not stat root of share\n")); goto fail3; } sb->s_magic = 0xface; sb->s_blocksize = 1024; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 3) /* Required for seek/sendfile. * * Must by less than or equal to INT64_MAX despite the fact that the * declaration of this variable is unsigned long long. See determination * of 'loff_t max' in fs/read_write.c / do_sendfile(). I don't know the * correct limit but MAX_LFS_FILESIZE (8TB-1 on 32-bit boxes) takes the * page cache into account and is the suggested limit. */ # if defined MAX_LFS_FILESIZE sb->s_maxbytes = MAX_LFS_FILESIZE; # else sb->s_maxbytes = 0x7fffffffffffffffULL; # endif #endif sb->s_op = &sf_super_ops; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) iroot = iget_locked(sb, 0); #else iroot = iget(sb, 0); #endif if (!iroot) { err = -ENOMEM; /* XXX */ LogFunc(("could not get root inode\n")); goto fail3; } if (sf_init_backing_dev(sf_g, info->name)) { err = -EINVAL; LogFunc(("could not init bdi\n")); goto fail4; } sf_init_inode(sf_g, iroot, &fsinfo); SET_INODE_INFO(iroot, sf_i); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) unlock_new_inode(iroot); #endif droot = d_alloc_root(iroot); if (!droot) { err = -ENOMEM; /* XXX */ LogFunc(("d_alloc_root failed\n")); goto fail5; } sb->s_root = droot; SET_GLOB_INFO(sb, sf_g); return 0; fail5: sf_done_backing_dev(sf_g); fail4: iput(iroot); fail3: kfree(sf_i->path); fail2: kfree(sf_i); fail1: sf_glob_free(sf_g); fail0: return err; }
int sf_nlscpy(struct sf_glob_info *sf_g, char *name, size_t name_bound_len, const unsigned char *utf8_name, size_t utf8_len) { if (sf_g->nls) { const char *in; char *out; size_t out_len; size_t out_bound_len; size_t in_bound_len; in = utf8_name; in_bound_len = utf8_len; out = name; out_len = 0; out_bound_len = name_bound_len; while (in_bound_len) { int nb; wchar_t uni; /** @todo this should be unicode_t in more recent kernel versions. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) nb = utf8_to_utf32(in, in_bound_len, &uni); #else nb = utf8_mbtowc(&uni, in, in_bound_len); #endif if (nb < 0) { LogFunc(("utf8_mbtowc failed(%s) %x:%d\n", (const char *) utf8_name, *in, in_bound_len)); return -EINVAL; } in += nb; in_bound_len -= nb; nb = sf_g->nls->uni2char(uni, out, out_bound_len); if (nb < 0) { LogFunc(("nls->uni2char failed(%s) %x:%d\n", utf8_name, uni, out_bound_len)); return nb; } out += nb; out_bound_len -= nb; out_len += nb; } *out = 0; } else { if (utf8_len + 1 > name_bound_len) return -ENAMETOOLONG; memcpy(name, utf8_name, utf8_len + 1); } return 0; }
/* allocate global info, try to map host share */ static int sf_glob_alloc(struct vbsf_mount_info_new *info, struct sf_glob_info **sf_gp) { int err, rc; SHFLSTRING *str_name; size_t name_len, str_len; struct sf_glob_info *sf_g; TRACE(); sf_g = kmalloc(sizeof(*sf_g), GFP_KERNEL); if (!sf_g) { err = -ENOMEM; LogRelFunc(("could not allocate memory for global info\n")); goto fail0; } RT_ZERO(*sf_g); if ( info->nullchar != '\0' || info->signature[0] != VBSF_MOUNT_SIGNATURE_BYTE_0 || info->signature[1] != VBSF_MOUNT_SIGNATURE_BYTE_1 || info->signature[2] != VBSF_MOUNT_SIGNATURE_BYTE_2) { /* An old version of mount.vboxsf made the syscall. Translate the * old parameters to the new structure. */ struct vbsf_mount_info_old *info_old = (struct vbsf_mount_info_old *)info; static struct vbsf_mount_info_new info_compat; info = &info_compat; memset(info, 0, sizeof(*info)); memcpy(&info->name, &info_old->name, MAX_HOST_NAME); memcpy(&info->nls_name, &info_old->nls_name, MAX_NLS_NAME); info->length = offsetof(struct vbsf_mount_info_new, dmode); info->uid = info_old->uid; info->gid = info_old->gid; info->ttl = info_old->ttl; } info->name[sizeof(info->name) - 1] = 0; info->nls_name[sizeof(info->nls_name) - 1] = 0; name_len = strlen(info->name); if (name_len > 0xfffe) { err = -ENAMETOOLONG; LogFunc(("map name too big\n")); goto fail1; } str_len = offsetof(SHFLSTRING, String.utf8) + name_len + 1; str_name = kmalloc(str_len, GFP_KERNEL); if (!str_name) { err = -ENOMEM; LogRelFunc(("could not allocate memory for host name\n")); goto fail1; } str_name->u16Length = name_len; str_name->u16Size = name_len + 1; memcpy(str_name->String.utf8, info->name, name_len + 1); if (info->nls_name[0] && strcmp(info->nls_name, "utf8")) { sf_g->nls = load_nls(info->nls_name); if (!sf_g->nls) { err = -EINVAL; LogFunc(("failed to load nls %s\n", info->nls_name)); goto fail1; } } else sf_g->nls = NULL; rc = vboxCallMapFolder(&client_handle, str_name, &sf_g->map); kfree(str_name); if (RT_FAILURE(rc)) { err = -EPROTO; LogFunc(("vboxCallMapFolder failed rc=%d\n", rc)); goto fail2; } sf_g->ttl = info->ttl; sf_g->uid = info->uid; sf_g->gid = info->gid; if ((unsigned)info->length >= sizeof(struct vbsf_mount_info_new)) { /* new fields */ sf_g->dmode = info->dmode; sf_g->fmode = info->fmode; sf_g->dmask = info->dmask; sf_g->fmask = info->fmask; } else { sf_g->dmode = ~0; sf_g->fmode = ~0; } *sf_gp = sf_g; return 0; fail2: if (sf_g->nls) unload_nls(sf_g->nls); fail1: kfree(sf_g); fail0: return err; }
static int vbox_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { LogFunc(("vboxvideo: %d\n", __LINE__)); return vbox_crtc_do_set_base(crtc, old_fb, x, y, 0); }
/* Module initialization/finalization handlers */ static int __init init(void) { int rcVBox; int rcRet = 0; int err; TRACE(); if (sizeof(struct vbsf_mount_info_new) > PAGE_SIZE) { printk(KERN_ERR "Mount information structure is too large %lu\n" "Must be less than or equal to %lu\n", (unsigned long)sizeof (struct vbsf_mount_info_new), (unsigned long)PAGE_SIZE); return -EINVAL; } err = register_filesystem(&vboxsf_fs_type); if (err) { LogFunc(("register_filesystem err=%d\n", err)); return err; } rcVBox = vboxInit(); if (RT_FAILURE(rcVBox)) { LogRelFunc(("vboxInit failed, rc=%d\n", rcVBox)); rcRet = -EPROTO; goto fail0; } rcVBox = vboxConnect(&client_handle); if (RT_FAILURE(rcVBox)) { LogRelFunc(("vboxConnect failed, rc=%d\n", rcVBox)); rcRet = -EPROTO; goto fail1; } rcVBox = vboxCallSetUtf8(&client_handle); if (RT_FAILURE(rcVBox)) { LogRelFunc(("vboxCallSetUtf8 failed, rc=%d\n", rcVBox)); rcRet = -EPROTO; goto fail2; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) if (!follow_symlinks) { rcVBox = vboxCallSetSymlinks(&client_handle); if (RT_FAILURE(rcVBox)) { printk(KERN_WARNING "vboxsf: Host unable to show symlinks, rc=%d\n", rcVBox); } } #endif printk(KERN_DEBUG "vboxsf: Successfully loaded version " VBOX_VERSION_STRING " (interface " RT_XSTR(VMMDEV_VERSION) ")\n"); return 0; fail2: vboxDisconnect(&client_handle); fail1: vboxUninit(); fail0: unregister_filesystem(&vboxsf_fs_type); return rcRet; }
/** * Pass the host a new mouse pointer shape via an HGSMI command. * * @returns success or failure * @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags * @param cHotX horizontal position of the hot spot * @param cHotY vertical position of the hot spot * @param cWidth width in pixels of the cursor * @param cHeight height in pixels of the cursor * @param pPixels pixel data, @see VMMDevReqMousePointer for the format * @param cbLength size in bytes of the pixel data */ RTDECL(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t fFlags, uint32_t cHotX, uint32_t cHotY, uint32_t cWidth, uint32_t cHeight, uint8_t *pPixels, uint32_t cbLength) { VBVAMOUSEPOINTERSHAPE *p; uint32_t cbData = 0; int rc = VINF_SUCCESS; if (fFlags & VBOX_MOUSE_POINTER_SHAPE) { /* Size of the pointer data: sizeof (AND mask) + sizeof (XOR_MASK) */ cbData = ((((cWidth + 7) / 8) * cHeight + 3) & ~3) + cWidth * 4 * cHeight; /* If shape is supplied, then always create the pointer visible. * See comments in 'vboxUpdatePointerShape' */ fFlags |= VBOX_MOUSE_POINTER_VISIBLE; } LogFlowFunc(("cbData %d, %dx%d\n", cbData, cWidth, cHeight)); if (cbData > cbLength) { LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n", cbData, cbLength)); return VERR_INVALID_PARAMETER; } /* Allocate the IO buffer. */ p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAMOUSEPOINTERSHAPE) + cbData, HGSMI_CH_VBVA, VBVA_MOUSE_POINTER_SHAPE); if (p) { /* Prepare data to be sent to the host. */ /* Will be updated by the host. */ p->i32Result = VINF_SUCCESS; /* We have our custom flags in the field */ p->fu32Flags = fFlags; p->u32HotX = cHotX; p->u32HotY = cHotY; p->u32Width = cWidth; p->u32Height = cHeight; if (p->fu32Flags & VBOX_MOUSE_POINTER_SHAPE) /* Copy the actual pointer data. */ memcpy (p->au8Data, pPixels, cbData); rc = VBoxHGSMIBufferSubmit(pCtx, p); if (RT_SUCCESS(rc)) rc = p->i32Result; /* Free the IO buffer. */ VBoxHGSMIBufferFree(pCtx, p); } else rc = VERR_NO_MEMORY; LogFlowFunc(("rc %d\n", rc)); return rc; }
static int VBoxUSBMonSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred) { LogFunc((DEVICE_NAME ": VBoxUSBMonSolarisWrite\n")); return 0; }