/** * Construct a block driver instance. * * @copydoc FNPDMDRVCONSTRUCT */ static DECLCALLBACK(int) drvscsihostConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) { PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST); LogFlowFunc(("pDrvIns=%#p pCfg=%#p\n", pDrvIns, pCfg)); PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); /* * Initialize the instance data first because of the destructor. */ pDrvIns->IBase.pfnQueryInterface = drvscsihostQueryInterface; pThis->ISCSIConnector.pfnSCSIRequestSend = drvscsihostRequestSend; pThis->pDrvIns = pDrvIns; pThis->hDeviceFile = NIL_RTFILE; pThis->hQueueRequests = NIL_RTREQQUEUE; /* * Read the configuration. */ if (!CFGMR3AreValuesValid(pCfg, "DevicePath\0")) return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, N_("Invalid configuration for host scsi access driver")); /* Query the SCSI port interface above. */ pThis->pDevScsiPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMISCSIPORT); AssertMsgReturn(pThis->pDevScsiPort, ("Missing SCSI port interface above\n"), VERR_PDM_MISSING_INTERFACE); /* Create request queue. */ int rc = RTReqQueueCreate(&pThis->hQueueRequests); AssertMsgReturn(RT_SUCCESS(rc), ("Failed to create request queue rc=%Rrc\n"), rc); /* Open the device. */ rc = CFGMR3QueryStringAlloc(pCfg, "DevicePath", &pThis->pszDevicePath); if (RT_FAILURE(rc)) return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Configuration error: Failed to get the \"DevicePath\" value")); rc = RTFileOpen(&pThis->hDeviceFile, pThis->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvSCSIHost#%d: Failed to open device '%s'"), pDrvIns->iInstance, pThis->pszDevicePath); /* Create I/O thread. */ rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pAsyncIOThread, pThis, drvscsihostAsyncIOLoop, drvscsihostAsyncIOLoopWakeup, 0, RTTHREADTYPE_IO, "SCSI async IO"); AssertMsgReturn(RT_SUCCESS(rc), ("Failed to create async I/O thread rc=%Rrc\n"), rc); return VINF_SUCCESS; }
static void doTestsOnDefaultValues(PCFGMNODE pRoot) { /* integer */ uint64_t u64; RTTESTI_CHECK_RC(CFGMR3QueryU64(pRoot, "RamSize", &u64), VINF_SUCCESS); size_t cb = 0; RTTESTI_CHECK_RC(CFGMR3QuerySize(pRoot, "RamSize", &cb), VINF_SUCCESS); RTTESTI_CHECK(cb == sizeof(uint64_t)); /* string */ char *pszName = NULL; RTTESTI_CHECK_RC(CFGMR3QueryStringAlloc(pRoot, "Name", &pszName), VINF_SUCCESS); RTTESTI_CHECK_RC(CFGMR3QuerySize(pRoot, "Name", &cb), VINF_SUCCESS); RTTESTI_CHECK(cb == strlen(pszName) + 1); MMR3HeapFree(pszName); }
/** * @interface_method_impl{Construct a NAT network transport driver instance, * PDMDRVREG,pfnDestruct} */ static DECLCALLBACK(int) drvR3NetShaperConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) { PDRVNETSHAPER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSHAPER); LogFlow(("drvNetShaperConstruct:\n")); PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); /* * Init the static parts. */ pThis->pDrvInsR3 = pDrvIns; pThis->pDrvInsR0 = PDMDRVINS_2_R0PTR(pDrvIns); /* IBase */ pDrvIns->IBase.pfnQueryInterface = drvR3NetShaperIBase_QueryInterface; pThis->IBaseR0.pfnQueryInterface = drvR3NetShaperIBaseR0_QueryInterface; pThis->IBaseRC.pfnQueryInterface = drvR3NetShaperIBaseRC_QueryInterface; /* INetworkUp */ pThis->INetworkUpR3.pfnBeginXmit = drvNetShaperUp_BeginXmit; pThis->INetworkUpR3.pfnAllocBuf = drvNetShaperUp_AllocBuf; pThis->INetworkUpR3.pfnFreeBuf = drvNetShaperUp_FreeBuf; pThis->INetworkUpR3.pfnSendBuf = drvNetShaperUp_SendBuf; pThis->INetworkUpR3.pfnEndXmit = drvNetShaperUp_EndXmit; pThis->INetworkUpR3.pfnSetPromiscuousMode = drvNetShaperUp_SetPromiscuousMode; pThis->INetworkUpR3.pfnNotifyLinkChanged = drvR3NetShaperUp_NotifyLinkChanged; /* Resolve the ring-0 context interface addresses. */ int rc = pDrvIns->pHlpR3->pfnLdrGetR0InterfaceSymbols(pDrvIns, &pThis->INetworkUpR0, sizeof(pThis->INetworkUpR0), "drvNetShaperUp_", PDMINETWORKUP_SYM_LIST); AssertLogRelRCReturn(rc, rc); /* INetworkDown */ pThis->INetworkDown.pfnWaitReceiveAvail = drvR3NetShaperDown_WaitReceiveAvail; pThis->INetworkDown.pfnReceive = drvR3NetShaperDown_Receive; pThis->INetworkDown.pfnReceiveGso = drvR3NetShaperDown_ReceiveGso; pThis->INetworkDown.pfnXmitPending = drvR3NetShaperDown_XmitPending; /* INetworkConfig */ pThis->INetworkConfig.pfnGetMac = drvR3NetShaperDownCfg_GetMac; pThis->INetworkConfig.pfnGetLinkState = drvR3NetShaperDownCfg_GetLinkState; pThis->INetworkConfig.pfnSetLinkState = drvR3NetShaperDownCfg_SetLinkState; /* * Create the locks. */ rc = PDMDrvHlpCritSectInit(pDrvIns, &pThis->XmitLock, RT_SRC_POS, "NetShaper"); AssertRCReturn(rc, rc); /* * Validate the config. */ if (!CFGMR3AreValuesValid(pCfg, "BwGroup\0")) return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES; /* * Find the bandwidth group we have to attach to. */ rc = CFGMR3QueryStringAlloc(pCfg, "BwGroup", &pThis->pszBwGroup); if (RT_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND) { rc = PDMDRV_SET_ERROR(pDrvIns, rc, N_("DrvNetShaper: Configuration error: Querying \"BwGroup\" as string failed")); return rc; } else rc = VINF_SUCCESS; pThis->Filter.pIDrvNetR3 = &pThis->INetworkDown; rc = PDMDrvHlpNetShaperAttach(pDrvIns, pThis->pszBwGroup, &pThis->Filter); if (RT_FAILURE(rc)) { rc = PDMDRV_SET_ERROR(pDrvIns, rc, N_("DrvNetShaper: Configuration error: Failed to attach to bandwidth group")); return rc; } /* * Query the network port interface. */ pThis->pIAboveNet = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKDOWN); if (!pThis->pIAboveNet) { AssertMsgFailed(("Configuration error: the above device/driver didn't export the network port interface!\n")); return VERR_PDM_MISSING_INTERFACE_ABOVE; } /* * Query the network config interface. */ pThis->pIAboveConfig = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKCONFIG); if (!pThis->pIAboveConfig) { AssertMsgFailed(("Configuration error: the above device/driver didn't export the network config interface!\n")); return VERR_PDM_MISSING_INTERFACE_ABOVE; } /* * Query the network connector interface. */ PPDMIBASE pBaseDown; rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBaseDown); if ( rc == VERR_PDM_NO_ATTACHED_DRIVER || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME) { pThis->pIBelowNetR3 = NULL; pThis->pIBelowNetR0 = NIL_RTR0PTR; } else if (RT_SUCCESS(rc)) { pThis->pIBelowNetR3 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP); if (!pThis->pIBelowNetR3) { AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n")); return VERR_PDM_MISSING_INTERFACE_BELOW; } PPDMIBASER0 pBaseR0 = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMIBASER0); pThis->pIBelowNetR0 = pBaseR0 ? pBaseR0->pfnQueryInterface(pBaseR0, PDMINETWORKUP_IID) : NIL_RTR0PTR; } else { AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc)); return rc; } /* * Register statistics. */ PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesRequested, "Bytes/Tx/Requested", STAMUNIT_BYTES, "Number of requested TX bytes."); PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesDenied, "Bytes/Tx/Denied", STAMUNIT_BYTES, "Number of denied TX bytes."); PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->StatXmitBytesGranted, "Bytes/Tx/Granted", STAMUNIT_BYTES, "Number of granted TX bytes."); PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsRequested, "Packets/Tx/Requested", "Number of requested TX packets."); PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsDenied, "Packets/Tx/Denied", "Number of denied TX packets."); PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPktsGranted, "Packets/Tx/Granted", "Number of granted TX packets."); PDMDrvHlpSTAMRegCounter(pDrvIns, &pThis->StatXmitPendingCalled, "Tx/WakeUp", "Number of wakeup TX calls."); return VINF_SUCCESS; }
/** * Construct a host parallel driver instance. * * @copydoc FNPDMDRVCONSTRUCT */ static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) { PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL); LogFlowFunc(("iInstance=%d\n", pDrvIns->iInstance)); PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); /* * Init basic data members and interfaces. * * Must be done before returning any failure because we've got a destructor. */ pThis->hFileDevice = NIL_RTFILE; #ifndef VBOX_WITH_WIN_PARPORT_SUP pThis->hWakeupPipeR = NIL_RTPIPE; pThis->hWakeupPipeW = NIL_RTPIPE; #else pThis->hWinFileDevice = NIL_RTFILE; #endif pThis->pDrvInsR3 = pDrvIns; #ifdef VBOX_WITH_DRVINTNET_IN_R0 pThis->pDrvInsR0 = PDMDRVINS_2_R0PTR(pDrvIns); #endif /* IBase. */ pDrvIns->IBase.pfnQueryInterface = drvHostParallelQueryInterface; /* IHostParallelConnector. */ pThis->IHostParallelConnectorR3.pfnWrite = drvHostParallelWrite; pThis->IHostParallelConnectorR3.pfnRead = drvHostParallelRead; pThis->IHostParallelConnectorR3.pfnSetPortDirection = drvHostParallelSetPortDirection; pThis->IHostParallelConnectorR3.pfnWriteControl = drvHostParallelWriteControl; pThis->IHostParallelConnectorR3.pfnReadControl = drvHostParallelReadControl; pThis->IHostParallelConnectorR3.pfnReadStatus = drvHostParallelReadStatus; /* * Validate the config. */ if (!CFGMR3AreValuesValid(pCfg, "DevicePath\0")) return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, N_("Unknown host parallel configuration option, only supports DevicePath")); /* * Query configuration. */ /* Device */ int rc = CFGMR3QueryStringAlloc(pCfg, "DevicePath", &pThis->pszDevicePath); if (RT_FAILURE(rc)) { AssertMsgFailed(("Configuration error: query for \"DevicePath\" string returned %Rra.\n", rc)); return rc; } /* * Open the device */ rc = RTFileOpen(&pThis->hFileDevice, pThis->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Parallel#%d could not open '%s'"), pDrvIns->iInstance, pThis->pszDevicePath); #ifndef VBOX_WITH_WIN_PARPORT_SUP /* * Try to get exclusive access to parallel port */ rc = ioctl(RTFileToNative(pThis->hFileDevice), PPEXCL); if (rc < 0) return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS, N_("Parallel#%d could not get exclusive access for parallel port '%s'" "Be sure that no other process or driver accesses this port"), pDrvIns->iInstance, pThis->pszDevicePath); /* * Claim the parallel port */ rc = ioctl(RTFileToNative(pThis->hFileDevice), PPCLAIM); if (rc < 0) return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS, N_("Parallel#%d could not claim parallel port '%s'" "Be sure that no other process or driver accesses this port"), pDrvIns->iInstance, pThis->pszDevicePath); /* * Get the IHostParallelPort interface of the above driver/device. */ pThis->pDrvHostParallelPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIHOSTPARALLELPORT); if (!pThis->pDrvHostParallelPort) return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE, RT_SRC_POS, N_("Parallel#%d has no parallel port interface above"), pDrvIns->iInstance); /* * Create wakeup pipe. */ rc = RTPipeCreate(&pThis->hWakeupPipeR, &pThis->hWakeupPipeW, 0 /*fFlags*/); AssertRCReturn(rc, rc); /* * Start in SPP mode. */ pThis->enmModeCur = PDM_PARALLEL_PORT_MODE_INVALID; rc = drvHostParallelSetMode(pThis, PDM_PARALLEL_PORT_MODE_SPP); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("HostParallel#%d cannot change mode of parallel mode to SPP"), pDrvIns->iInstance); /* * Start waiting for interrupts. */ rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pMonitorThread, pThis, drvHostParallelMonitorThread, drvHostParallelWakeupMonitorThread, 0, RTTHREADTYPE_IO, "ParMon"); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("HostParallel#%d cannot create monitor thread"), pDrvIns->iInstance); #else /* VBOX_WITH_WIN_PARPORT_SUP */ pThis->fParportAvail = false; pThis->u32LptAddr = 0; pThis->u32LptAddrControl = 0; pThis->u32LptAddrStatus = 0; rc = drvWinHostGetparportAddr(pThis); /* If we have the char port availabe use it , else I am not getting exclusive access to parallel port. Read and write will be done only if addresses are available */ if (pThis->szParportName) { rc = RTFileOpen(&pThis->hWinFileDevice, (char *)pThis->szParportName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); } #endif return VINF_SUCCESS; }
/** * Construct a disk integrity driver instance. * * @copydoc FNPDMDRVCONSTRUCT */ static DECLCALLBACK(int) drvdiskintConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) { int rc = VINF_SUCCESS; PDRVDISKINTEGRITY pThis = PDMINS_2_DATA(pDrvIns, PDRVDISKINTEGRITY); LogFlow(("drvdiskintConstruct: iInstance=%d\n", pDrvIns->iInstance)); PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); /* * Validate configuration. */ if (!CFGMR3AreValuesValid(pCfg, "CheckConsistency\0" "TraceRequests\0" "CheckIntervalMs\0" "ExpireIntervalMs\0" "CheckDoubleCompletions\0" "HistorySize\0" "IoLog\0")) return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES; rc = CFGMR3QueryBoolDef(pCfg, "CheckConsistency", &pThis->fCheckConsistency, false); AssertRC(rc); rc = CFGMR3QueryBoolDef(pCfg, "TraceRequests", &pThis->fTraceRequests, false); AssertRC(rc); rc = CFGMR3QueryU32Def(pCfg, "CheckIntervalMs", &pThis->uCheckIntervalMs, 5000); /* 5 seconds */ AssertRC(rc); rc = CFGMR3QueryU32Def(pCfg, "ExpireIntervalMs", &pThis->uExpireIntervalMs, 20000); /* 20 seconds */ AssertRC(rc); rc = CFGMR3QueryBoolDef(pCfg, "CheckDoubleCompletions", &pThis->fCheckDoubleCompletion, false); AssertRC(rc); rc = CFGMR3QueryU32Def(pCfg, "HistorySize", &pThis->cEntries, 512); AssertRC(rc); char *pszIoLogFilename = NULL; rc = CFGMR3QueryStringAlloc(pCfg, "IoLog", &pszIoLogFilename); Assert(RT_SUCCESS(rc) || rc == VERR_CFGM_VALUE_NOT_FOUND); /* * Initialize most of the data members. */ pThis->pDrvIns = pDrvIns; /* IBase. */ pDrvIns->IBase.pfnQueryInterface = drvdiskintQueryInterface; /* IMedia */ pThis->IMedia.pfnRead = drvdiskintRead; pThis->IMedia.pfnWrite = drvdiskintWrite; pThis->IMedia.pfnFlush = drvdiskintFlush; pThis->IMedia.pfnGetSize = drvdiskintGetSize; pThis->IMedia.pfnIsReadOnly = drvdiskintIsReadOnly; pThis->IMedia.pfnBiosGetPCHSGeometry = drvdiskintBiosGetPCHSGeometry; pThis->IMedia.pfnBiosSetPCHSGeometry = drvdiskintBiosSetPCHSGeometry; pThis->IMedia.pfnBiosGetLCHSGeometry = drvdiskintBiosGetLCHSGeometry; pThis->IMedia.pfnBiosSetLCHSGeometry = drvdiskintBiosSetLCHSGeometry; pThis->IMedia.pfnGetUuid = drvdiskintGetUuid; /* IMediaAsync */ pThis->IMediaAsync.pfnStartRead = drvdiskintStartRead; pThis->IMediaAsync.pfnStartWrite = drvdiskintStartWrite; pThis->IMediaAsync.pfnStartFlush = drvdiskintStartFlush; /* IMediaAsyncPort. */ pThis->IMediaAsyncPort.pfnTransferCompleteNotify = drvdiskintAsyncTransferCompleteNotify; /* IMediaPort. */ pThis->IMediaPort.pfnQueryDeviceLocation = drvdiskintQueryDeviceLocation; /* Query the media port interface above us. */ pThis->pDrvMediaPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAPORT); if (!pThis->pDrvMediaPort) return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW, N_("No media port inrerface above")); /* Try to attach async media port interface above.*/ pThis->pDrvMediaAsyncPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAASYNCPORT); /* * Try attach driver below and query it's media interface. */ PPDMIBASE pBase; rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBase); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Failed to attach driver below us! %Rrc"), rc); pThis->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA); if (!pThis->pDrvMedia) return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW, N_("No media or async media interface below")); pThis->pDrvMediaAsync = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIAASYNC); if (pThis->pDrvMedia->pfnDiscard) pThis->IMedia.pfnDiscard = drvdiskintDiscard; if ( pThis->pDrvMediaAsync && pThis->pDrvMediaAsync->pfnStartDiscard) pThis->IMediaAsync.pfnStartDiscard = drvdiskintStartDiscard; if (pThis->fCheckConsistency) { /* Create the AVL tree. */ pThis->pTreeSegments = (PAVLRFOFFTREE)RTMemAllocZ(sizeof(AVLRFOFFTREE)); if (!pThis->pTreeSegments) rc = VERR_NO_MEMORY; } if (pThis->fTraceRequests) { for (unsigned i = 0; i < RT_ELEMENTS(pThis->apReqActive); i++) { pThis->apReqActive[i].pIoReq = NULL; pThis->apReqActive[i].tsStart = 0; } pThis->iNextFreeSlot = 0; /* Init event semaphore. */ rc = RTSemEventCreate(&pThis->SemEvent); AssertRC(rc); pThis->fRunning = true; rc = RTThreadCreate(&pThis->hThread, drvdiskIntIoReqExpiredCheck, pThis, 0, RTTHREADTYPE_INFREQUENT_POLLER, 0, "DiskIntegrity"); AssertRC(rc); } if (pThis->fCheckDoubleCompletion) { pThis->iEntry = 0; pThis->papIoReq = (PDRVDISKAIOREQ *)RTMemAllocZ(pThis->cEntries * sizeof(PDRVDISKAIOREQ)); AssertPtr(pThis->papIoReq); } if (pszIoLogFilename) { rc = VDDbgIoLogCreate(&pThis->hIoLogger, pszIoLogFilename, VDDBG_IOLOG_LOG_DATA); MMR3HeapFree(pszIoLogFilename); } return rc; }
int main() { /* * Init runtime. */ RTR3InitExeNoArguments(RTR3INIT_FLAGS_SUPLIB); /* * Create empty VM structure and init SSM. */ PVM pVM; int rc = SUPR3Init(NULL); if (RT_SUCCESS(rc)) rc = SUPR3PageAlloc(RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT, (void **)&pVM); if (RT_FAILURE(rc)) { RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc); return 1; } static UVM s_UVM; PUVM pUVM = &s_UVM; pUVM->pVM = pVM; pVM->pUVM = pUVM; rc = STAMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = MMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3Init(pVM, NULL, NULL); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3Init failed. rc=%Rrc\n", rc); return 1; } if (!CFGMR3GetRoot(pVM)) { RTPrintf("FAILURE: CFGMR3GetRoot failed\n"); return 1; } /* integer */ uint64_t u64; rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &u64); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryU64(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } size_t cb; rc = CFGMR3QuerySize(CFGMR3GetRoot(pVM), "RamSize", &cb); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QuerySize(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } if (cb != sizeof(uint64_t)) { RTPrintf("FAILURE: Incorrect valuesize %d for \"RamSize\" value.\n", cb); return 1; } /* string */ char *pszName = NULL; rc = CFGMR3QueryStringAlloc(CFGMR3GetRoot(pVM), "Name", &pszName); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryStringAlloc(,\"Name\" failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3QuerySize(CFGMR3GetRoot(pVM), "Name", &cb); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QuerySize(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } if (cb != strlen(pszName) + 1) { RTPrintf("FAILURE: Incorrect valuesize %d for \"Name\" value '%s'.\n", cb, pszName); return 1; } MMR3HeapFree(pszName); /* test multilevel node creation */ PCFGMNODE pChild = NULL; rc = CFGMR3InsertNode(CFGMR3GetRoot(pVM), "First/Second/Third//Final", &pChild); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3InsertNode(,\"First/Second/Third//Final\" failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3InsertInteger(pChild, "BoolValue", 1); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3InsertInteger(,\"BoolValue\", 1) failed. rc=%Rrc\n", rc); return 1; } PCFGMNODE pNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "First/Second/Third/Final"); if (pNode != pChild) { RTPrintf("FAILURE: CFGMR3GetChild(,\"First/Second/Third/Final/BoolValue\") failed. pNode=%p expected %p\n", pNode, pChild); return 1; } bool f = false; rc = CFGMR3QueryBool(pNode, "BoolValue", &f); if (RT_FAILURE(rc) || !f) { RTPrintf("FAILURE: CFGMR3QueryBool(,\"BoolValue\",) failed. rc=%Rrc f=%d\n", rc, f); return 1; } /* done */ rc = CFGMR3Term(pVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryU64(,\"RamSize\" failed. rc=%Rrc\n", rc); return 1; } RTPrintf("tstCFGM: SUCCESS\n"); return rc; }
/** * Construct a TCP socket stream driver instance. * * @copydoc FNPDMDRVCONSTRUCT */ static DECLCALLBACK(int) drvTCPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) { RT_NOREF(fFlags); PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); PDRVTCP pThis = PDMINS_2_DATA(pDrvIns, PDRVTCP); /* * Init the static parts. */ pThis->pDrvIns = pDrvIns; pThis->pszLocation = NULL; pThis->fIsServer = false; pThis->hTcpServ = NULL; pThis->hTcpSock = NIL_RTSOCKET; pThis->hPollSet = NIL_RTPOLLSET; pThis->hPipeWakeR = NIL_RTPIPE; pThis->hPipeWakeW = NIL_RTPIPE; pThis->fTcpSockInPollSet = false; pThis->ListenThread = NIL_RTTHREAD; pThis->fShutdown = false; /* IBase */ pDrvIns->IBase.pfnQueryInterface = drvTCPQueryInterface; /* IStream */ pThis->IStream.pfnPoll = drvTcpPoll; pThis->IStream.pfnPollInterrupt = drvTcpPollInterrupt; pThis->IStream.pfnRead = drvTcpRead; pThis->IStream.pfnWrite = drvTcpWrite; /* * Validate and read the configuration. */ PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "Location|IsServer", ""); int rc = CFGMR3QueryStringAlloc(pCfg, "Location", &pThis->pszLocation); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Configuration error: querying \"Location\" resulted in %Rrc"), rc); rc = CFGMR3QueryBool(pCfg, "IsServer", &pThis->fIsServer); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Configuration error: querying \"IsServer\" resulted in %Rrc"), rc); rc = RTPipeCreate(&pThis->hPipeWakeR, &pThis->hPipeWakeW, 0 /* fFlags */); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d: Failed to create wake pipe"), pDrvIns->iInstance); rc = RTPollSetCreate(&pThis->hPollSet); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d: Failed to create poll set"), pDrvIns->iInstance); rc = RTPollSetAddPipe(pThis->hPollSet, pThis->hPipeWakeR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, DRVTCP_POLLSET_ID_WAKEUP); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d failed to add wakeup pipe for %s to poll set"), pDrvIns->iInstance, pThis->pszLocation); /* * Create/Open the socket. */ if (pThis->fIsServer) { uint32_t uPort = 0; rc = RTStrToUInt32Ex(pThis->pszLocation, NULL, 10, &uPort); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d: The port part of the location is not a numerical value"), pDrvIns->iInstance); /** @todo Allow binding to distinct interfaces. */ rc = RTTcpServerCreateEx(NULL, uPort, &pThis->hTcpServ); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d failed to create server socket"), pDrvIns->iInstance); rc = RTThreadCreate(&pThis->ListenThread, drvTCPListenLoop, (void *)pThis, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "DrvTCPStream"); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d failed to create listening thread"), pDrvIns->iInstance); } else { char *pszPort = strchr(pThis->pszLocation, ':'); if (!pszPort) return PDMDrvHlpVMSetError(pDrvIns, VERR_NOT_FOUND, RT_SRC_POS, N_("DrvTCP#%d: The location misses the port to connect to"), pDrvIns->iInstance); *pszPort = '\0'; /* Overwrite temporarily to avoid copying the hostname into a temporary buffer. */ uint32_t uPort = 0; rc = RTStrToUInt32Ex(pszPort + 1, NULL, 10, &uPort); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d: The port part of the location is not a numerical value"), pDrvIns->iInstance); rc = RTTcpClientConnect(pThis->pszLocation, uPort, &pThis->hTcpSock); *pszPort = ':'; /* Restore delimiter before checking the status. */ if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d failed to connect to socket %s"), pDrvIns->iInstance, pThis->pszLocation); rc = RTPollSetAddSocket(pThis->hPollSet, pThis->hTcpSock, RTPOLL_EVT_READ | RTPOLL_EVT_WRITE | RTPOLL_EVT_ERROR, DRVTCP_POLLSET_ID_SOCKET); if (RT_FAILURE(rc)) return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("DrvTCP#%d failed to add socket for %s to poll set"), pDrvIns->iInstance, pThis->pszLocation); pThis->fTcpSockInPollSet = true; } LogRel(("DrvTCP: %s, %s\n", pThis->pszLocation, pThis->fIsServer ? "server" : "client")); return VINF_SUCCESS; }
/** * Initialize the debug info for a VM. * * This will check the CFGM for any symbols or symbol files * which needs loading. * * @returns VBox status code. * @param pVM The VM handle. */ int dbgfR3SymInit(PVM pVM) { int rc; /* * Initialize the symbol table. */ pVM->dbgf.s.pSymbolSpace = (PRTSTRSPACE)MMR3HeapAllocZ(pVM, MM_TAG_DBGF_SYMBOL, sizeof(*pVM->dbgf.s.pSymbolSpace)); AssertReturn(pVM->dbgf.s.pSymbolSpace, VERR_NO_MEMORY); #ifndef HAVE_DBGHELP /* modules & lines later */ rc = dbgfR3SymbolInit(pVM); if (RT_FAILURE(rc)) return rc; pVM->dbgf.s.fSymInited = true; #endif /* * Check if there are 'loadsyms' commands in the configuration. */ PCFGMNODE pNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "/DBGF/loadsyms/"); if (pNode) { /* * Enumerate the commands. */ for (PCFGMNODE pCmdNode = CFGMR3GetFirstChild(pNode); pCmdNode; pCmdNode = CFGMR3GetNextChild(pCmdNode)) { char szCmdName[128]; CFGMR3GetName(pCmdNode, &szCmdName[0], sizeof(szCmdName)); /* File */ char *pszFilename; rc = CFGMR3QueryStringAlloc(pCmdNode, "Filename", &pszFilename); AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'File' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* Delta (optional) */ RTGCINTPTR offDelta; rc = CFGMR3QueryGCPtrS(pNode, "Delta", &offDelta); if (rc == VERR_CFGM_VALUE_NOT_FOUND) offDelta = 0; else AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'Delta' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* Module (optional) */ char *pszModule; rc = CFGMR3QueryStringAlloc(pCmdNode, "Module", &pszModule); if (rc == VERR_CFGM_VALUE_NOT_FOUND) pszModule = NULL; else AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'Module' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* Module (optional) */ RTGCUINTPTR ModuleAddress; rc = CFGMR3QueryGCPtrU(pNode, "ModuleAddress", &ModuleAddress); if (rc == VERR_CFGM_VALUE_NOT_FOUND) ModuleAddress = 0; else AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'ModuleAddress' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* Image size (optional) */ RTGCUINTPTR cbModule; rc = CFGMR3QueryGCPtrU(pNode, "ModuleSize", &cbModule); if (rc == VERR_CFGM_VALUE_NOT_FOUND) cbModule = 0; else AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'ModuleAddress' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* * Execute the command. */ rc = DBGFR3ModuleLoad(pVM, pszFilename, offDelta, pszModule, ModuleAddress, cbModule); AssertMsgRCReturn(rc, ("pszFilename=%s offDelta=%RGv pszModule=%s ModuleAddress=%RGv cbModule=%RGv\n", pszFilename, offDelta, pszModule, ModuleAddress, cbModule), rc); MMR3HeapFree(pszModule); MMR3HeapFree(pszFilename); } } /* * Check if there are any 'symadd' commands in the configuration. */ return VINF_SUCCESS; }