STDMETHODIMP GuestFileEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent) { switch (aType) { case VBoxEventType_OnGuestFileStateChanged: { HRESULT rc; do { ComPtr<IGuestFileStateChangedEvent> pEvent = aEvent; Assert(!pEvent.isNull()); ComPtr<IGuestFile> pProcess; CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pProcess.asOutParam())); AssertBreak(!pProcess.isNull()); FileStatus_T fileSts; CHECK_ERROR_BREAK(pEvent, COMGETTER(Status)(&fileSts)); Bstr strPath; CHECK_ERROR_BREAK(pProcess, COMGETTER(FileName)(strPath.asOutParam())); ULONG uID; CHECK_ERROR_BREAK(pProcess, COMGETTER(Id)(&uID)); RTPrintf("File ID=%RU32 \"%s\" changed status to [%s]\n", uID, Utf8Str(strPath).c_str(), gctlFileStatusToText(fileSts)); } while (0); break; } default: AssertFailed(); } return S_OK; }
/** * Run once function that initializes the kstats we need here. * * @returns IPRT status code. * @param pvUser1 Unused. * @param pvUser2 Unused. */ static DECLCALLBACK(int) rtMpSolarisOnce(void *pvUser1, void *pvUser2) { int rc = VINF_SUCCESS; NOREF(pvUser1); NOREF(pvUser2); /* * Open kstat and find the cpu_info entries for each of the CPUs. */ g_pKsCtl = kstat_open(); if (g_pKsCtl) { g_capCpuInfo = RTMpGetCount(); g_papCpuInfo = (kstat_t **)RTMemAllocZ(g_capCpuInfo * sizeof(kstat_t *)); if (g_papCpuInfo) { rc = RTCritSectInit(&g_MpSolarisCritSect); if (RT_SUCCESS(rc)) { RTCPUID i = 0; for (kstat_t *pKsp = g_pKsCtl->kc_chain; pKsp != NULL; pKsp = pKsp->ks_next) { if (!strcmp(pKsp->ks_module, "cpu_info")) { AssertBreak(i < g_capCpuInfo); g_papCpuInfo[i++] = pKsp; /** @todo ks_instance == cpu_id (/usr/src/uts/common/os/cpu.c)? Check this and fix it ASAP. */ } } return VINF_SUCCESS; } /* bail out, we failed. */ RTMemFree(g_papCpuInfo); } else rc = VERR_NO_MEMORY; kstat_close(g_pKsCtl); g_pKsCtl = NULL; } else { rc = RTErrConvertFromErrno(errno); if (RT_SUCCESS(rc)) rc = VERR_INTERNAL_ERROR; Log(("kstat_open() -> %d (%Rrc)\n", errno, rc)); } return rc; }
/** * Internal worker for RTTimeNormalize and RTTimeLocalNormalize. * It doesn't adjust the UCT offset but leaves that for RTTimeLocalNormalize. */ static PRTTIME rtTimeNormalizeInternal(PRTTIME pTime) { unsigned uSecond; unsigned uMinute; unsigned uHour; bool fLeapYear; /* * Fix the YearDay and Month/MonthDay. */ fLeapYear = rtTimeIsLeapYear(pTime->i32Year); if (!pTime->u16YearDay) { /* * The Month+MonthDay must present, overflow adjust them and calc the year day. */ AssertMsgReturn( pTime->u8Month && pTime->u8MonthDay, ("date=%d-%d-%d\n", pTime->i32Year, pTime->u8Month, pTime->u8MonthDay), NULL); while (pTime->u8Month > 12) { pTime->u8Month -= 12; pTime->i32Year++; fLeapYear = rtTimeIsLeapYear(pTime->i32Year); pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR); } for (;;) { unsigned cDaysInMonth = fLeapYear ? g_acDaysInMonthsLeap[pTime->u8Month - 1] : g_acDaysInMonths[pTime->u8Month - 1]; if (pTime->u8MonthDay <= cDaysInMonth) break; pTime->u8MonthDay -= cDaysInMonth; if (pTime->u8Month != 12) pTime->u8Month++; else { pTime->u8Month = 1; pTime->i32Year++; fLeapYear = rtTimeIsLeapYear(pTime->i32Year); pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR); } } pTime->u16YearDay = pTime->u8MonthDay - 1 + (fLeapYear ? g_aiDayOfYearLeap[pTime->u8Month - 1] : g_aiDayOfYear[pTime->u8Month - 1]); } else { /* * Are both YearDay and Month/MonthDay valid? * Check that they don't overflow and match, if not use YearDay (simpler). */ bool fRecalc = true; if ( pTime->u8Month && pTime->u8MonthDay) { do { uint16_t u16YearDay; /* If you change one, zero the other to make clear what you mean. */ AssertBreak(pTime->u8Month <= 12); AssertBreak(pTime->u8MonthDay <= (fLeapYear ? g_acDaysInMonthsLeap[pTime->u8Month - 1] : g_acDaysInMonths[pTime->u8Month - 1])); u16YearDay = pTime->u8MonthDay - 1 + (fLeapYear ? g_aiDayOfYearLeap[pTime->u8Month - 1] : g_aiDayOfYear[pTime->u8Month - 1]); AssertBreak(u16YearDay == pTime->u16YearDay); fRecalc = false; } while (0); } if (fRecalc) { const uint16_t *paiDayOfYear; /* overflow adjust YearDay */ while (pTime->u16YearDay > (fLeapYear ? 366 : 365)) { pTime->u16YearDay -= fLeapYear ? 366 : 365; pTime->i32Year++; fLeapYear = rtTimeIsLeapYear(pTime->i32Year); pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR); } /* calc Month and MonthDay */ paiDayOfYear = fLeapYear ? &g_aiDayOfYearLeap[0] : &g_aiDayOfYear[0]; pTime->u8Month = 1; while (pTime->u16YearDay > paiDayOfYear[pTime->u8Month]) pTime->u8Month++; Assert(pTime->u8Month >= 1 && pTime->u8Month <= 12); pTime->u8MonthDay = pTime->u16YearDay - paiDayOfYear[pTime->u8Month - 1] + 1; } } /* * Fixup time overflows. * Use unsigned int values internally to avoid overflows. */ uSecond = pTime->u8Second; uMinute = pTime->u8Minute; uHour = pTime->u8Hour; while (pTime->u32Nanosecond >= 1000000000) { pTime->u32Nanosecond -= 1000000000; uSecond++; } while (uSecond >= 60) { uSecond -= 60; uMinute++; } while (uMinute >= 60) { uMinute -= 60; uHour++; } while (uHour >= 24) { uHour -= 24; /* This is really a RTTimeIncDay kind of thing... */ if (pTime->u16YearDay + 1 != (fLeapYear ? g_aiDayOfYearLeap[pTime->u8Month] : g_aiDayOfYear[pTime->u8Month])) { pTime->u16YearDay++; pTime->u8MonthDay++; } else if (pTime->u8Month != 12) { pTime->u16YearDay++; pTime->u8Month++; pTime->u8MonthDay = 1; } else { pTime->i32Year++; fLeapYear = rtTimeIsLeapYear(pTime->i32Year); pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR); pTime->u16YearDay = 1; pTime->u8Month = 1; pTime->u8MonthDay = 1; } } pTime->u8Second = uSecond; pTime->u8Minute = uMinute; pTime->u8Hour = uHour; /* * Correct the leap year flag. * Assert if it's wrong, but ignore if unset. */ if (fLeapYear) { Assert(!(pTime->fFlags & RTTIME_FLAGS_COMMON_YEAR)); pTime->fFlags &= ~RTTIME_FLAGS_COMMON_YEAR; pTime->fFlags |= RTTIME_FLAGS_LEAP_YEAR; } else { Assert(!(pTime->fFlags & RTTIME_FLAGS_LEAP_YEAR)); pTime->fFlags &= ~RTTIME_FLAGS_LEAP_YEAR; pTime->fFlags |= RTTIME_FLAGS_COMMON_YEAR; } /* * Calc week day. * * 1970-01-01 was a Thursday (3), so find the number of days relative to * that point. We use the table when possible and a slow+stupid+brute-force * algorithm for points outside it. Feel free to optimize the latter by * using some clever formula. */ if ( pTime->i32Year >= OFF_YEAR_IDX_0_YEAR && pTime->i32Year < OFF_YEAR_IDX_0_YEAR + (int32_t)RT_ELEMENTS(g_aoffYear)) { int32_t offDays = g_aoffYear[pTime->i32Year - OFF_YEAR_IDX_0_YEAR] + pTime->u16YearDay -1; pTime->u8WeekDay = ((offDays % 7) + 3 + 7) % 7; } else { int32_t i32Year = pTime->i32Year; if (i32Year >= 1970) { uint64_t offDays = pTime->u16YearDay - 1; while (--i32Year >= 1970) offDays += rtTimeIsLeapYear(i32Year) ? 366 : 365; pTime->u8WeekDay = (uint8_t)((offDays + 3) % 7); } else { int64_t offDays = (fLeapYear ? -366 - 1 : -365 - 1) + pTime->u16YearDay; while (++i32Year < 1970) offDays -= rtTimeIsLeapYear(i32Year) ? 366 : 365; pTime->u8WeekDay = ((int)(offDays % 7) + 3 + 7) % 7; } } return pTime; }
static DECLCALLBACK(int) drvHostALSAAudioPlayOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcSamplesPlayed) { NOREF(pInterface); AssertPtrReturn(pHstStrmOut, VERR_INVALID_POINTER); PALSAAUDIOSTREAMOUT pThisStrmOut = (PALSAAUDIOSTREAMOUT)pHstStrmOut; int rc = VINF_SUCCESS; uint32_t cbReadTotal = 0; do { snd_pcm_sframes_t cAvail; rc = drvHostALSAAudioGetAvail(pThisStrmOut->phPCM, &cAvail); if (RT_FAILURE(rc)) { LogFunc(("Error getting number of playback frames, rc=%Rrc\n", rc)); break; } size_t cbToRead = RT_MIN(AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cAvail), AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, drvAudioHstOutSamplesLive(pHstStrmOut, NULL /* pcStreamsLive */))); LogFlowFunc(("cbToRead=%zu, cbAvail=%zu\n", cbToRead, AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cAvail))); uint32_t cRead, cbRead; snd_pcm_sframes_t cWritten; while (cbToRead) { rc = AudioMixBufReadCirc(&pHstStrmOut->MixBuf, pThisStrmOut->pvBuf, cbToRead, &cRead); if (RT_FAILURE(rc)) break; cbRead = AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cRead); AssertBreak(cbRead); cWritten = snd_pcm_writei(pThisStrmOut->phPCM, pThisStrmOut->pvBuf, cRead); if (cWritten <= 0) { switch (cWritten) { case 0: { LogFunc(("Failed to write %RI32 frames\n", cRead)); rc = VERR_ACCESS_DENIED; break; } case -EPIPE: { rc = drvHostALSAAudioRecover(pThisStrmOut->phPCM); if (RT_FAILURE(rc)) break; LogFlowFunc(("Recovered from playback\n")); continue; } case -ESTRPIPE: { /* Stream was suspended and waiting for a recovery. */ rc = drvHostALSAAudioResume(pThisStrmOut->phPCM); if (RT_FAILURE(rc)) { LogRel(("ALSA: Failed to resume output stream\n")); break; } LogFlowFunc(("Resumed suspended output stream\n")); continue; } default: LogFlowFunc(("Failed to write %RI32 output frames, rc=%Rrc\n", cRead, rc)); rc = VERR_GENERAL_FAILURE; /** @todo */ break; } } if (RT_FAILURE(rc)) break; Assert(cbToRead >= cbRead); cbToRead -= cbRead; cbReadTotal += cbRead; } } while (0); if (RT_SUCCESS(rc)) { uint32_t cReadTotal = AUDIOMIXBUF_B2S(&pHstStrmOut->MixBuf, cbReadTotal); if (cReadTotal) AudioMixBufFinish(&pHstStrmOut->MixBuf, cReadTotal); if (pcSamplesPlayed) *pcSamplesPlayed = cReadTotal; LogFlowFunc(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n", cReadTotal, cbReadTotal, rc)); } LogFlowFuncLeaveRC(rc); return rc; }
/** * Recursive worker function to walk the /dev tree looking for DVD or floppy * devices. * @returns true if we have already found MAX_DEVICE_NODES devices, false * otherwise * @param pszPath the path to start recursing. The function can modify * this string at and after the terminating zero * @param cchPath the size of the buffer (not the string!) in @a pszPath * @param aDevices where to fill in information about devices that we have * found * @param wantDVD are we looking for DVD devices (or floppies)? */ static bool devFindDeviceRecursive(char *pszPath, size_t cchPath, deviceNodeArray aDevices, bool wantDVD) { /* * Check assumptions made by the code below. */ size_t const cchBasePath = strlen(pszPath); AssertReturn(cchBasePath < RTPATH_MAX - 10U, false); AssertReturn(pszPath[cchBasePath - 1] != '/', false); PRTDIR pDir; if (RT_FAILURE(RTDirOpen(&pDir, pszPath))) return false; for (;;) { RTDIRENTRY Entry; RTFSOBJINFO ObjInfo; int rc = RTDirRead(pDir, &Entry, NULL); if (RT_FAILURE(rc)) break; if (Entry.enmType == RTDIRENTRYTYPE_UNKNOWN) { if (RT_FAILURE(RTPathQueryInfo(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX))) continue; if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode)) continue; } if (Entry.enmType == RTDIRENTRYTYPE_SYMLINK) continue; pszPath[cchBasePath] = '\0'; if (RT_FAILURE(RTPathAppend(pszPath, cchPath, Entry.szName))) break; /* Do the matching. */ dev_t DevNode; char szDesc[256], szUdi[256]; if (!devValidateDevice(pszPath, wantDVD, &DevNode, szDesc, sizeof(szDesc), szUdi, sizeof(szUdi))) continue; unsigned i; for (i = 0; i < MAX_DEVICE_NODES; ++i) if (!aDevices[i].Device || (aDevices[i].Device == DevNode)) break; AssertBreak(i < MAX_DEVICE_NODES); if (aDevices[i].Device) continue; aDevices[i].Device = DevNode; RTStrPrintf(aDevices[i].szPath, sizeof(aDevices[i].szPath), "%s", pszPath); AssertCompile(sizeof(aDevices[i].szDesc) == sizeof(szDesc)); strcpy(aDevices[i].szDesc, szDesc); AssertCompile(sizeof(aDevices[i].szUdi) == sizeof(szUdi)); strcpy(aDevices[i].szUdi, szUdi); if (i == MAX_DEVICE_NODES - 1) break; continue; /* Recurse into subdirectories. */ if ( (Entry.enmType == RTDIRENTRYTYPE_UNKNOWN) && !RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) continue; if (Entry.enmType != RTDIRENTRYTYPE_DIRECTORY) continue; if (Entry.szName[0] == '.') continue; if (devFindDeviceRecursive(pszPath, cchPath, aDevices, wantDVD)) break; } RTDirClose(pDir); return aDevices[MAX_DEVICE_NODES - 1].Device ? true : false; }
static int solarisWalkDeviceNode(di_node_t Node, void *pvArg) { PUSBDEVICELIST pList = (PUSBDEVICELIST)pvArg; AssertPtrReturn(pList, DI_WALK_TERMINATE); /* * Check if it's a USB device in the first place. */ bool fUSBDevice = false; char *pszCompatNames = NULL; int cCompatNames = di_compatible_names(Node, &pszCompatNames); for (int i = 0; i < cCompatNames; i++, pszCompatNames += strlen(pszCompatNames) + 1) if (!strncmp(pszCompatNames, "usb", 3)) { fUSBDevice = true; break; } if (!fUSBDevice) return DI_WALK_CONTINUE; /* * Check if it's a device node or interface. */ int *pInt = NULL; char *pStr = NULL; int rc = DI_WALK_CONTINUE; if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "interface", &pInt) < 0) { /* It's a device node. */ char *pszDevicePath = di_devfs_path(Node); PUSBDEVICE pCur = (PUSBDEVICE)RTMemAllocZ(sizeof(*pCur)); if (!pCur) { LogRel(("USBService: failed to allocate %d bytes for PUSBDEVICE.\n", sizeof(*pCur))); return DI_WALK_TERMINATE; } bool fValidDevice = false; do { AssertBreak(pszDevicePath); char *pszDriverName = di_driver_name(Node); /* * Skip hubs */ if ( pszDriverName && !strcmp(pszDriverName, "hubd")) { break; } /* * Mandatory. * snv_85 and above have usb-dev-descriptor node properties, but older one's do not. * So if we cannot obtain the entire device descriptor, we try falling back to the * individual properties (those must not fail, if it does we drop the device). */ uchar_t *pDevData = NULL; int cbProp = di_prop_lookup_bytes(DDI_DEV_T_ANY, Node, "usb-dev-descriptor", &pDevData); if ( cbProp > 0 && pDevData) { usb_dev_descr_t *pDeviceDescriptor = (usb_dev_descr_t *)pDevData; pCur->bDeviceClass = pDeviceDescriptor->bDeviceClass; pCur->bDeviceSubClass = pDeviceDescriptor->bDeviceSubClass; pCur->bDeviceProtocol = pDeviceDescriptor->bDeviceProtocol; pCur->idVendor = pDeviceDescriptor->idVendor; pCur->idProduct = pDeviceDescriptor->idProduct; pCur->bcdDevice = pDeviceDescriptor->bcdDevice; pCur->bcdUSB = pDeviceDescriptor->bcdUSB; pCur->bNumConfigurations = pDeviceDescriptor->bNumConfigurations; pCur->fPartialDescriptor = false; } else { AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-vendor-id", &pInt) > 0); pCur->idVendor = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-product-id", &pInt) > 0); pCur->idProduct = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-revision-id", &pInt) > 0); pCur->bcdDevice = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-release", &pInt) > 0); pCur->bcdUSB = (uint16_t)*pInt; pCur->fPartialDescriptor = true; } char *pszPortAddr = di_bus_addr(Node); if (pszPortAddr) pCur->bPort = RTStrToUInt8(pszPortAddr); /* Bus & Port are mixed up (kernel driver/userland) */ else pCur->bPort = 0; char pathBuf[PATH_MAX]; RTStrPrintf(pathBuf, sizeof(pathBuf), "%s", pszDevicePath); RTPathStripFilename(pathBuf); char szBuf[PATH_MAX + 48]; RTStrPrintf(szBuf, sizeof(szBuf), "%#x:%#x:%d:%s", pCur->idVendor, pCur->idProduct, pCur->bcdDevice, pathBuf); pCur->pszAddress = RTStrDup(szBuf); pCur->pszDevicePath = RTStrDup(pszDevicePath); AssertBreak(pCur->pszDevicePath); /* * Optional (some devices don't have all these) */ if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-product-name", &pStr) > 0) pCur->pszProduct = RTStrDup(pStr); if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-vendor-name", &pStr) > 0) pCur->pszManufacturer = RTStrDup(pStr); if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-serialno", &pStr) > 0) pCur->pszSerialNumber = RTStrDup(pStr); if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "low-speed", &pInt) >= 0) pCur->enmSpeed = USBDEVICESPEED_LOW; else if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "high-speed", &pInt) >= 0) pCur->enmSpeed = USBDEVICESPEED_HIGH; else pCur->enmSpeed = USBDEVICESPEED_FULL; /* Determine state of the USB device. */ pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node); /* * Valid device, add it to the list. */ fValidDevice = true; pCur->pPrev = pList->pTail; if (pList->pTail) pList->pTail = pList->pTail->pNext = pCur; else pList->pTail = pList->pHead = pCur; rc = DI_WALK_CONTINUE; } while(0); di_devfs_path_free(pszDevicePath); if (!fValidDevice) solarisFreeUSBDevice(pCur); } return rc; }
/** * Initializes a SG list from an mbuf. * * @returns Number of segments. * @param pThis The instance. * @param pMBuf The mbuf. * @param pSG The SG. * @param pvFrame The frame pointer, optional. * @param cSegs The number of segments allocated for the SG. * This should match the number in the mbuf exactly! * @param fSrc The source of the frame. */ DECLINLINE(void) vboxNetFltDarwinMBufToSG(PVBOXNETFLTINS pThis, mbuf_t pMBuf, void *pvFrame, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc) { NOREF(pThis); /* * Walk the chain and convert the buffers to segments. Works INTNETSG::cbTotal. */ unsigned iSeg = 0; IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/); for (mbuf_t pCur = pMBuf; pCur; pCur = mbuf_next(pCur)) { size_t cbSeg = mbuf_len(pCur); if (cbSeg) { void *pvSeg = mbuf_data(pCur); /* deal with pvFrame */ if (!iSeg && pvFrame && pvFrame != pvSeg) { void *pvStart = mbuf_datastart(pMBuf); uintptr_t offSeg = (uintptr_t)pvSeg - (uintptr_t)pvStart; uintptr_t offSegEnd = offSeg + cbSeg; Assert(pvStart && pvSeg && offSeg < mbuf_maxlen(pMBuf) && offSegEnd <= mbuf_maxlen(pMBuf)); NOREF(offSegEnd); uintptr_t offFrame = (uintptr_t)pvFrame - (uintptr_t)pvStart; if (RT_LIKELY(offFrame < offSeg)) { pvSeg = pvFrame; cbSeg += offSeg - offFrame; } else AssertMsgFailed(("pvFrame=%p pvStart=%p pvSeg=%p offSeg=%p cbSeg=%#zx offSegEnd=%p offFrame=%p maxlen=%#zx\n", pvFrame, pvStart, pvSeg, offSeg, cbSeg, offSegEnd, offFrame, mbuf_maxlen(pMBuf))); pvFrame = NULL; } AssertBreak(iSeg < cSegs); pSG->cbTotal += cbSeg; pSG->aSegs[iSeg].cb = cbSeg; pSG->aSegs[iSeg].pv = pvSeg; pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS; iSeg++; } /* The pvFrame might be in a now empty buffer. */ else if ( !iSeg && pvFrame && (uintptr_t)pvFrame - (uintptr_t)mbuf_datastart(pMBuf) < mbuf_maxlen(pMBuf)) { cbSeg = (uintptr_t)mbuf_datastart(pMBuf) + mbuf_maxlen(pMBuf) - (uintptr_t)pvFrame; pSG->cbTotal += cbSeg; pSG->aSegs[iSeg].cb = cbSeg; pSG->aSegs[iSeg].pv = pvFrame; pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS; iSeg++; pvFrame = NULL; } } Assert(iSeg && iSeg <= cSegs); pSG->cSegsUsed = iSeg; #ifdef PADD_RUNT_FRAMES_FROM_HOST /* * Add a trailer if the frame is too small. * * Since we're getting to the packet before it is framed, it has not * yet been padded. The current solution is to add a segment pointing * to a buffer containing all zeros and pray that works for all frames... */ if (pSG->cbTotal < 60 && (fSrc & INTNETTRUNKDIR_HOST)) { AssertReturnVoid(iSeg < cSegs); static uint8_t const s_abZero[128] = {0}; pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS; pSG->aSegs[iSeg].pv = (void *)&s_abZero[0]; pSG->aSegs[iSeg].cb = 60 - pSG->cbTotal; pSG->cbTotal = 60; pSG->cSegsUsed++; } #endif #ifdef VBOXNETFLT_DARWIN_TEST_SEG_SIZE /* * Redistribute the segments. */ if (pSG->cSegsUsed < pSG->cSegsAlloc) { /* copy the segments to the end. */ int iSrc = pSG->cSegsUsed; int iDst = pSG->cSegsAlloc; while (iSrc > 0) { iDst--; iSrc--; pSG->aSegs[iDst] = pSG->aSegs[iSrc]; } /* create small segments from the start. */ pSG->cSegsUsed = pSG->cSegsAlloc; iSrc = iDst; iDst = 0; while ( iDst < iSrc && iDst < pSG->cSegsAlloc) { pSG->aSegs[iDst].Phys = NIL_RTHCPHYS; pSG->aSegs[iDst].pv = pSG->aSegs[iSrc].pv; pSG->aSegs[iDst].cb = RT_MIN(pSG->aSegs[iSrc].cb, VBOXNETFLT_DARWIN_TEST_SEG_SIZE); if (pSG->aSegs[iDst].cb != pSG->aSegs[iSrc].cb) { pSG->aSegs[iSrc].cb -= pSG->aSegs[iDst].cb; pSG->aSegs[iSrc].pv = (uint8_t *)pSG->aSegs[iSrc].pv + pSG->aSegs[iDst].cb; } else if (++iSrc >= pSG->cSegsAlloc) { pSG->cSegsUsed = iDst + 1; break; } iDst++; } } #endif AssertMsg(!pvFrame, ("pvFrame=%p pMBuf=%p iSeg=%d\n", pvFrame, pMBuf, iSeg)); }
STDMETHODIMP GuestEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent) { switch (aType) { case VBoxEventType_OnGuestSessionRegistered: { HRESULT rc; do { ComPtr<IGuestSessionRegisteredEvent> pEvent = aEvent; Assert(!pEvent.isNull()); ComPtr<IGuestSession> pSession; CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam())); AssertBreak(!pSession.isNull()); BOOL fRegistered; CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered)); Bstr strName; CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam())); ULONG uID; CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID)); RTPrintf("Session ID=%RU32 \"%s\" %s\n", uID, Utf8Str(strName).c_str(), fRegistered ? "registered" : "unregistered"); if (fRegistered) { if (mfVerbose) RTPrintf("Registering ...\n"); /* Register for IGuestSession events. */ ComObjPtr<GuestSessionEventListenerImpl> pListener; pListener.createObject(); CHECK_ERROR_BREAK(pListener, init(new GuestSessionEventListener())); ComPtr<IEventSource> es; CHECK_ERROR_BREAK(pSession, COMGETTER(EventSource)(es.asOutParam())); com::SafeArray<VBoxEventType_T> eventTypes; eventTypes.push_back(VBoxEventType_OnGuestFileRegistered); eventTypes.push_back(VBoxEventType_OnGuestProcessRegistered); CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */)); GuestSessionStats sessionStats(pListener); mSessions[pSession] = sessionStats; } else { GuestEventSessions::iterator itSession = mSessions.find(pSession); if (itSession != mSessions.end()) { if (mfVerbose) RTPrintf("Unregistering ...\n"); if (!itSession->first.isNull()) { /* Listener unregistration. */ ComPtr<IEventSource> pES; CHECK_ERROR_BREAK(itSession->first, COMGETTER(EventSource)(pES.asOutParam())); if (!pES.isNull()) CHECK_ERROR_BREAK(pES, UnregisterListener(itSession->second.mListener)); itSession->first->Release(); } mSessions.erase(itSession); } } } while (0); break; } default: AssertFailed(); } return S_OK; }
STDMETHODIMP GuestSessionEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent) { switch (aType) { case VBoxEventType_OnGuestFileRegistered: { HRESULT rc; do { ComPtr<IGuestFileRegisteredEvent> pEvent = aEvent; Assert(!pEvent.isNull()); ComPtr<IGuestFile> pFile; CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pFile.asOutParam())); AssertBreak(!pFile.isNull()); BOOL fRegistered; CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered)); Bstr strPath; CHECK_ERROR_BREAK(pFile, COMGETTER(FileName)(strPath.asOutParam())); RTPrintf("File \"%s\" %s\n", Utf8Str(strPath).c_str(), fRegistered ? "registered" : "unregistered"); if (fRegistered) { if (mfVerbose) RTPrintf("Registering ...\n"); /* Register for IGuestFile events. */ ComObjPtr<GuestFileEventListenerImpl> pListener; pListener.createObject(); CHECK_ERROR_BREAK(pListener, init(new GuestFileEventListener())); ComPtr<IEventSource> es; CHECK_ERROR_BREAK(pFile, COMGETTER(EventSource)(es.asOutParam())); com::SafeArray<VBoxEventType_T> eventTypes; eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged); CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */)); GuestFileStats fileStats(pListener); mFiles[pFile] = fileStats; } else { GuestEventFiles::iterator itFile = mFiles.find(pFile); if (itFile != mFiles.end()) { if (mfVerbose) RTPrintf("Unregistering file ...\n"); if (!itFile->first.isNull()) { /* Listener unregistration. */ ComPtr<IEventSource> pES; CHECK_ERROR(itFile->first, COMGETTER(EventSource)(pES.asOutParam())); if (!pES.isNull()) CHECK_ERROR(pES, UnregisterListener(itFile->second.mListener)); itFile->first->Release(); } mFiles.erase(itFile); } } } while (0); break; } case VBoxEventType_OnGuestProcessRegistered: { HRESULT rc; do { ComPtr<IGuestProcessRegisteredEvent> pEvent = aEvent; Assert(!pEvent.isNull()); ComPtr<IGuestProcess> pProcess; CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam())); AssertBreak(!pProcess.isNull()); BOOL fRegistered; CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered)); Bstr strPath; CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam())); RTPrintf("Process \"%s\" %s\n", Utf8Str(strPath).c_str(), fRegistered ? "registered" : "unregistered"); if (fRegistered) { if (mfVerbose) RTPrintf("Registering ...\n"); /* Register for IGuestProcess events. */ ComObjPtr<GuestProcessEventListenerImpl> pListener; pListener.createObject(); CHECK_ERROR_BREAK(pListener, init(new GuestProcessEventListener())); ComPtr<IEventSource> es; CHECK_ERROR_BREAK(pProcess, COMGETTER(EventSource)(es.asOutParam())); com::SafeArray<VBoxEventType_T> eventTypes; eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */)); GuestProcStats procStats(pListener); mProcs[pProcess] = procStats; } else { GuestEventProcs::iterator itProc = mProcs.find(pProcess); if (itProc != mProcs.end()) { if (mfVerbose) RTPrintf("Unregistering process ...\n"); if (!itProc->first.isNull()) { /* Listener unregistration. */ ComPtr<IEventSource> pES; CHECK_ERROR(itProc->first, COMGETTER(EventSource)(pES.asOutParam())); if (!pES.isNull()) CHECK_ERROR(pES, UnregisterListener(itProc->second.mListener)); itProc->first->Release(); } mProcs.erase(itProc); } } } while (0); break; } case VBoxEventType_OnGuestSessionStateChanged: { HRESULT rc; do { ComPtr<IGuestSessionStateChangedEvent> pEvent = aEvent; Assert(!pEvent.isNull()); ComPtr<IGuestSession> pSession; CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam())); AssertBreak(!pSession.isNull()); GuestSessionStatus_T sessSts; CHECK_ERROR_BREAK(pSession, COMGETTER(Status)(&sessSts)); ULONG uID; CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID)); Bstr strName; CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam())); RTPrintf("Session ID=%RU32 \"%s\" changed status to [%s]\n", uID, Utf8Str(strName).c_str(), gctlGuestSessionStatusToText(sessSts)); } while (0); break; } default: AssertFailed(); } return S_OK; }