//.........这里部分代码省略.........
{
return false;
}
}
if (!(cbRecordCurrent & VBVA_F_RECORD_PARTIAL))
{
/* The record is completed by guest. Return it to the caller. */
*ppHdr = (VBVACMDHDR *)pVideoAccel->pu8VbvaPartial;
*pcbCmd = pVideoAccel->cbVbvaPartial;
pVideoAccel->pu8VbvaPartial = NULL;
pVideoAccel->cbVbvaPartial = 0;
/* Advance the record index. */
pVbvaMemory->indexRecordFirst = (indexRecordFirst + 1) % VBVA_MAX_RECORDS;
#ifdef DEBUG_sunlover
LogFlowFunc(("partial done ok, data = %d, free = %d\n",
pVbvaMemory->off32Data, pVbvaMemory->off32Free));
#endif /* DEBUG_sunlover */
}
return true;
}
/* A new record need to be processed. */
if (cbRecordCurrent & VBVA_F_RECORD_PARTIAL)
{
/* Current record is being written by guest. '=' is important here. */
if (cbRecord >= VBVA_RING_BUFFER_SIZE - VBVA_RING_BUFFER_THRESHOLD)
{
/* Partial read must be started. */
if (!i_vbvaPartialRead(&pVideoAccel->pu8VbvaPartial, &pVideoAccel->cbVbvaPartial, cbRecord, pVbvaMemory))
{
return false;
}
LogFlowFunc(("started partial record cbVbvaPartial = 0x%08X cbRecord 0x%08X, first = %d, free = %d\n",
pVideoAccel->cbVbvaPartial, cbRecordCurrent, indexRecordFirst, indexRecordFree));
}
return true;
}
/* Current record is complete. If it is not empty, process it. */
if (cbRecord)
{
/* The size of largest contiguous chunk in the ring biffer. */
uint32_t u32BytesTillBoundary = VBVA_RING_BUFFER_SIZE - pVbvaMemory->off32Data;
/* The ring buffer pointer. */
uint8_t *au8RingBuffer = &pVbvaMemory->au8RingBuffer[0];
/* The pointer to data in the ring buffer. */
uint8_t *src = &au8RingBuffer[pVbvaMemory->off32Data];
/* Fetch or point the data. */
if (u32BytesTillBoundary >= cbRecord)
{
/* The command does not cross buffer boundary. Return address in the buffer. */
*ppHdr = (VBVACMDHDR *)src;
/* Advance data offset. */
pVbvaMemory->off32Data = (pVbvaMemory->off32Data + cbRecord) % VBVA_RING_BUFFER_SIZE;
}
else
{
/* The command crosses buffer boundary. Rare case, so not optimized. */
uint8_t *dst = (uint8_t *)RTMemAlloc(cbRecord);
if (!dst)
{
LogRelFlowFunc(("could not allocate %d bytes from heap!!!\n", cbRecord));
pVbvaMemory->off32Data = (pVbvaMemory->off32Data + cbRecord) % VBVA_RING_BUFFER_SIZE;
return false;
}
i_vbvaFetchBytes(pVbvaMemory, dst, cbRecord);
*ppHdr = (VBVACMDHDR *)dst;
#ifdef DEBUG_sunlover
LogFlowFunc(("Allocated from heap %p\n", dst));
#endif /* DEBUG_sunlover */
}
}
*pcbCmd = cbRecord;
/* Advance the record index. */
pVbvaMemory->indexRecordFirst = (indexRecordFirst + 1) % VBVA_MAX_RECORDS;
#ifdef DEBUG_sunlover
LogFlowFunc(("done ok, data = %d, free = %d\n",
pVbvaMemory->off32Data, pVbvaMemory->off32Free));
#endif /* DEBUG_sunlover */
return true;
}
static int vbglR3DnDHGProcessURIMessages(uint32_t uClientId,
uint32_t *puScreenId,
char *pszFormat,
uint32_t cbFormat,
uint32_t *pcbFormatRecv,
void **ppvData,
uint32_t cbData,
size_t *pcbDataRecv)
{
/* Make a string list out of the uri data. */
RTCList<RTCString> uriList = RTCString(static_cast<char*>(*ppvData), *pcbDataRecv - 1).split("\r\n");
if (uriList.isEmpty())
return VINF_SUCCESS;
uint32_t cbTmpData = _1M * 10;
void *pvTmpData = RTMemAlloc(cbTmpData);
if (!pvTmpData)
return VERR_NO_MEMORY;
/* Create and query the drop target directory. */
char pszDropDir[RTPATH_MAX];
int rc = vbglR3DnDCreateDropDir(pszDropDir, sizeof(pszDropDir));
if (RT_FAILURE(rc))
{
RTMemFree(pvTmpData);
return rc;
}
/* Patch the old drop data with the new drop directory, so the drop target
* can find the files. */
RTCList<RTCString> guestUriList;
for (size_t i = 0; i < uriList.size(); ++i)
{
const RTCString &strUri = uriList.at(i);
/* Query the path component of a file URI. If this hasn't a
* file scheme, null is returned. */
if (char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO))
{
RTCString strFullPath = RTCString().printf("%s%c%s", pszDropDir, RTPATH_SLASH, pszFilePath);
char *pszNewUri = RTUriFileCreate(strFullPath.c_str());
if (pszNewUri)
{
guestUriList.append(pszNewUri);
RTStrFree(pszNewUri);
}
}
else
guestUriList.append(strUri);
}
/* Cleanup the old data and write the new data back to the event. */
RTMemFree(*ppvData);
RTCString newData = RTCString::join(guestUriList, "\r\n") + "\r\n";
*ppvData = RTStrDupN(newData.c_str(), newData.length());
*pcbDataRecv = newData.length() + 1;
/* Lists for holding created files & directories in the case of a
* rollback. */
RTCList<RTCString> guestDirList;
RTCList<RTCString> guestFileList;
char pszPathname[RTPATH_MAX];
uint32_t cbPathname = 0;
bool fLoop = true;
do
{
uint32_t uNextMsg;
uint32_t cNextParms;
rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false);
DO(("%Rrc - %d\n", rc , uNextMsg));
if (RT_SUCCESS(rc))
{
switch(uNextMsg)
{
case DragAndDropSvc::HOST_DND_HG_SND_DIR:
{
uint32_t fMode = 0;
rc = vbglR3DnDHGProcessSendDirMessage(uClientId,
pszPathname,
sizeof(pszPathname),
&cbPathname,
&fMode);
if (RT_SUCCESS(rc))
{
DO(("Got drop dir: %s - %o - %Rrc\n", pszPathname, fMode, rc));
char *pszNewDir = RTPathJoinA(pszDropDir, pszPathname);
rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0);
if (!guestDirList.contains(pszNewDir))
guestDirList.append(pszNewDir);
}
break;
}
case DragAndDropSvc::HOST_DND_HG_SND_FILE:
{
uint32_t cbDataRecv;
uint32_t fMode = 0;
rc = vbglR3DnDHGProcessSendFileMessage(uClientId,
pszPathname,
sizeof(pszPathname),
&cbPathname,
pvTmpData,
//.........这里部分代码省略.........
/**
* Get Parallel port address and update the shared data
* structure.
* @returns VBox status code.
* @param pThis The host parallel port instance data.
*/
static int drvWinHostGetparportAddr(PDRVHOSTPARALLEL pThis)
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
uint32_t u32Idx;
uint32_t u32ParportAddr;
int rc = VINF_SUCCESS;
hDevInfo = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (hDevInfo == INVALID_HANDLE_VALUE)
return VERR_INVALID_HANDLE;
/* Enumerate through all devices in Set. */
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (u32Idx = 0; SetupDiEnumDeviceInfo(hDevInfo, u32Idx, &DeviceInfoData); u32Idx++)
{
DWORD dwDataType;
uint8_t *pBuf = NULL;
DWORD dwBufSize = 0;
while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME,
(PDWORD)&dwDataType, (uint8_t *)pBuf,
dwBufSize, (PDWORD)&dwBufSize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
LogFlow(("ERROR_INSUFF_BUFF = %d. dwBufSz = %d\n", GetLastError(), dwBufSize));
if (pBuf)
RTMemFree(pBuf);
pBuf = (uint8_t *)RTMemAlloc(dwBufSize * 2);
}
else
{
/* No need to bother about this error (in most cases its errno=13,
* INVALID_DATA . Just break from here and proceed to next device
* enumerated item
*/
LogFlow(("GetDevProp Error = %d & dwBufSz = %d\n", GetLastError(), dwBufSize));
break;
}
}
if (RTStrStr((char*)pBuf, "LPT"))
{
u32ParportAddr = drvHostWinFindIORangeResource(DeviceInfoData.DevInst);
if (u32ParportAddr)
{
/* Find parallel port name and update the shared data struncture */
char *pCh = RTStrStr((char*)pBuf, "(");
char *pTmpCh = RTStrStr((char *)pBuf, ")");
/* check for the confirmation for the availability of parallel port */
if (!(pCh && pTmpCh))
{
LogFlowFunc(("Parallel port Not Found. \n"));
return VERR_NOT_FOUND;
}
if (((pTmpCh - (char *)pBuf) - (pCh - (char *)pBuf)) < 0) {
LogFlowFunc(("Parallel port string not properly formatted.\n"));
return VERR_NOT_FOUND;
}
/* check for the confirmation for the availability of parallel port */
if (RTStrCopyEx((char *)(pThis->szParportName), sizeof(pThis->szParportName),
pCh+1, ((pTmpCh - (char *)pBuf) - (pCh - (char *)pBuf)) - 1))
{
LogFlowFunc(("Parallel Port Not Found.\n"));
return VERR_NOT_FOUND;
}
*((char *)pThis->szParportName + (pTmpCh - (char *)pBuf) - (pCh - (char *)pBuf) + 1 ) = '\0';
/* checking again to make sure that we have got a valid name and in valid format too. */
if (RTStrNCmp((char *)pThis->szParportName, "LPT", 3)) {
LogFlowFunc(("Parallel Port name \"LPT\" Not Found.\n"));
return VERR_NOT_FOUND;
}
if (!RTStrStr((char *)pThis->szParportName, "LPT")
|| !(pThis->szParportName[3] >= '0'
&& pThis->szParportName[3] <= '9'))
{
RT_BZERO(pThis->szParportName, sizeof(pThis->szParportName));
LogFlowFunc(("Printer Port Name Not Found.\n"));
return VERR_NOT_FOUND;
}
pThis->fParportAvail = true;
pThis->u32LptAddr = u32ParportAddr;
pThis->u32LptAddrControl = pThis->u32LptAddr + CTRL_REG_OFFSET;
pThis->u32LptAddrStatus = pThis->u32LptAddr + STATUS_REG_OFFSET;
}
else
LogFlowFunc(("u32Parport Addr No Available \n"));
if (pThis->fParportAvail)
break;
}
if (pBuf)
//.........这里部分代码省略.........
/**
* Find IO port range for the parallel port and return the lower address.
*
* @returns parallel port IO address.
* @param DevInst Device Instance for parallel port.
*/
static uint32_t drvHostWinFindIORangeResource(const DEVINST DevInst)
{
uint8_t *pBuf = NULL;
short wHeaderSize;
uint32_t u32Size;
CONFIGRET cmRet;
LOG_CONF firstLogConf;
LOG_CONF nextLogConf;
RES_DES rdPrevResDes;
uint32_t u32ParportAddr = 0;
wHeaderSize = sizeof(IO_DES);
cmRet = CM_Get_First_Log_Conf(&firstLogConf, DevInst, ALLOC_LOG_CONF);
if (cmRet != CR_SUCCESS)
{
cmRet = CM_Get_First_Log_Conf(&firstLogConf, DevInst, BOOT_LOG_CONF);
if (cmRet != CR_SUCCESS)
return 0;
}
cmRet = CM_Get_Next_Res_Des(&nextLogConf, firstLogConf, 2, 0L, 0L);
if (cmRet != CR_SUCCESS)
{
CM_Free_Res_Des_Handle(firstLogConf);
return 0;
}
/* This loop is based on the fact that only one resourece is assigned to
* the LPT port. If multiple resources (address range) are assigned to
* to LPT port, it will pick and return the last one
*/
for (;;)
{
u32Size = 0;
cmRet = CM_Get_Res_Des_Data_Size((PULONG)(&u32Size), nextLogConf, 0L);
if (cmRet != CR_SUCCESS)
{
LogFlowFunc(("Failed to get Size \n"));
CM_Free_Res_Des_Handle(nextLogConf);
break;
}
pBuf = (uint8_t *)RTMemAlloc(u32Size + 1);
if (!pBuf)
{
LogFlowFunc(("Failed to get Buf %d\n", u32Size));
CM_Free_Res_Des_Handle(nextLogConf);
break;
}
cmRet = CM_Get_Res_Des_Data(nextLogConf, pBuf, u32Size, 0L);
if (cmRet != CR_SUCCESS)
{
LogFlowFunc(("Failed to get Des Data \n"));
CM_Free_Res_Des_Handle(nextLogConf);
if (pBuf)
RTMemFree(pBuf);
break;
}
LogFlowFunc(("call GetIOResource\n"));
if (pBuf)
u32ParportAddr = ((IO_DES *)pBuf)->IOD_Alloc_Base;
LogFlowFunc(("called GetIOResource, ret=%#x\n", u32ParportAddr));
rdPrevResDes = 0;
cmRet = CM_Get_Next_Res_Des(&rdPrevResDes,
nextLogConf,
2,
0L,
0L);
if (pBuf)
RTMemFree(pBuf);
if (cmRet != CR_SUCCESS)
break;
CM_Free_Res_Des_Handle(nextLogConf);
nextLogConf = rdPrevResDes;
}
CM_Free_Res_Des_Handle(nextLogConf);
LogFlowFunc(("return u32ParportAddr=%#x", u32ParportAddr));
return u32ParportAddr;
}
请发表评论