Changeset 44558 in vbox
- Timestamp:
- Feb 6, 2013 7:54:11 AM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 83618
- Location:
- trunk/src/VBox/Additions
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/SharedFolders/driver/file.c
r42154 r44558 7 7 8 8 /* 9 * Copyright (C) 2012 Oracle Corporation9 * Copyright (C) 2012-2013 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 #include "vbsf.h" 21 21 #include <iprt/fs.h> 22 #include <iprt/mem.h> 23 24 25 /* How much data to transfer in one HGCM request. */ 26 #define VBSF_MAX_READ_WRITE_PAGES 256 27 28 29 typedef int FNVBSFTRANSFERBUFFER(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 30 uint64_t offset, uint32_t *pcbBuffer, 31 uint8_t *pBuffer, bool fLocked); 32 typedef FNVBSFTRANSFERBUFFER *PFNVBSFTRANSFERBUFFER; 33 34 typedef int FNVBSFTRANSFERPAGES(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 35 uint64_t offset, uint32_t *pcbBuffer, 36 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages); 37 typedef FNVBSFTRANSFERPAGES *PFNVBSFTRANSFERPAGES; 38 39 40 static int vbsfTransferBufferRead(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 41 uint64_t offset, uint32_t *pcbBuffer, 42 uint8_t *pBuffer, bool fLocked) 43 { 44 return vboxCallRead(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked); 45 } 46 47 static int vbsfTransferBufferWrite(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 48 uint64_t offset, uint32_t *pcbBuffer, 49 uint8_t *pBuffer, bool fLocked) 50 { 51 return vboxCallWrite(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked); 52 } 53 54 static int vbsfTransferPagesRead(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 55 uint64_t offset, uint32_t *pcbBuffer, 56 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages) 57 { 58 return VbglR0SharedFolderReadPageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages); 59 } 60 61 static int vbsfTransferPagesWrite(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 62 uint64_t offset, uint32_t *pcbBuffer, 63 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages) 64 { 65 return VbglR0SharedFolderWritePageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages); 66 } 67 68 69 typedef struct VBSFTRANSFERCTX 70 { 71 PVBSFCLIENT pClient; 72 PVBSFMAP pMap; 73 SHFLHANDLE hFile; 74 uint64_t offset; 75 uint32_t cbData; 76 77 PMDL pMdl; 78 uint8_t *pBuffer; 79 bool fLocked; 80 81 PFNVBSFTRANSFERBUFFER pfnTransferBuffer; 82 PFNVBSFTRANSFERPAGES pfnTransferPages; 83 } VBSFTRANSFERCTX; 84 85 86 static int vbsfTransferCommon(VBSFTRANSFERCTX *pCtx) 87 { 88 int rc = VINF_SUCCESS; 89 BOOLEAN fProcessed = FALSE; 90 91 uint32_t cbTransferred = 0; 92 93 uint32_t cbToTransfer; 94 uint32_t cbIO; 95 96 if (VbglR0CanUsePhysPageList()) 97 { 98 ULONG offFirstPage = MmGetMdlByteOffset(pCtx->pMdl); 99 ULONG cPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(pCtx->pMdl), pCtx->cbData); 100 ULONG cPagesToTransfer = RT_MIN(cPages, VBSF_MAX_READ_WRITE_PAGES); 101 RTGCPHYS64 *paPages = (RTGCPHYS64 *)RTMemTmpAlloc(cPagesToTransfer * sizeof(RTGCPHYS64)); 102 103 Log(("VBOXSF: vbsfTransferCommon: using page list: %d pages, offset 0x%03X\n", cPages, offFirstPage)); 104 105 if (paPages) 106 { 107 PPFN_NUMBER paPfns = MmGetMdlPfnArray(pCtx->pMdl); 108 ULONG cPagesTransferred = 0; 109 cbTransferred = 0; 110 111 while (cPagesToTransfer != 0) 112 { 113 ULONG iPage; 114 cbToTransfer = cPagesToTransfer * PAGE_SIZE - offFirstPage; 115 116 if (cbToTransfer > pCtx->cbData - cbTransferred) 117 { 118 cbToTransfer = pCtx->cbData - cbTransferred; 119 } 120 121 if (cbToTransfer == 0) 122 { 123 /* Nothing to transfer. */ 124 break; 125 } 126 127 cbIO = cbToTransfer; 128 129 Log(("VBOXSF: vbsfTransferCommon: transferring %d pages at %d; %d bytes at %d\n", 130 cPagesToTransfer, cPagesTransferred, cbToTransfer, cbTransferred)); 131 132 for (iPage = 0; iPage < cPagesToTransfer; iPage++) 133 { 134 paPages[iPage] = (RTGCPHYS64)paPfns[iPage + cPagesTransferred] << PAGE_SHIFT; 135 } 136 137 rc = pCtx->pfnTransferPages(pCtx->pClient, pCtx->pMap, pCtx->hFile, 138 pCtx->offset + cbTransferred, &cbIO, 139 (uint16_t)offFirstPage, (uint16_t)cPagesToTransfer, paPages); 140 if (RT_FAILURE(rc)) 141 { 142 Log(("VBOXSF: vbsfTransferCommon: pfnTransferPages %Rrc, cbTransferred %d\n", rc, cbTransferred)); 143 144 /* If some data was transferred, then it is no error. */ 145 if (cbTransferred > 0) 146 { 147 rc = VINF_SUCCESS; 148 } 149 150 break; 151 } 152 153 cbTransferred += cbIO; 154 155 if (cbToTransfer < cbIO) 156 { 157 /* Transferred less than requested, do not continue with the possibly remaining data. */ 158 break; 159 } 160 161 cPagesTransferred += cPagesToTransfer; 162 offFirstPage = 0; 163 164 cPagesToTransfer = cPages - cPagesTransferred; 165 if (cPagesToTransfer > VBSF_MAX_READ_WRITE_PAGES) 166 { 167 cPagesToTransfer = VBSF_MAX_READ_WRITE_PAGES; 168 } 169 } 170 171 RTMemTmpFree(paPages); 172 173 fProcessed = TRUE; 174 } 175 } 176 177 if (fProcessed != TRUE) 178 { 179 /* Split large transfers. */ 180 cbTransferred = 0; 181 cbToTransfer = RT_MIN(pCtx->cbData, VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE); 182 183 /* Page list not supported or a fallback. */ 184 Log(("VBOXSF: vbsfTransferCommon: using linear address\n")); 185 186 while (cbToTransfer != 0) 187 { 188 cbIO = cbToTransfer; 189 190 Log(("VBOXSF: vbsfTransferCommon: transferring %d bytes at %d\n", 191 cbToTransfer, cbTransferred)); 192 193 rc = pCtx->pfnTransferBuffer(pCtx->pClient, pCtx->pMap, pCtx->hFile, 194 pCtx->offset + cbTransferred, &cbIO, 195 pCtx->pBuffer + cbTransferred, true /* locked */); 196 197 if (RT_FAILURE(rc)) 198 { 199 Log(("VBOXSF: vbsfTransferCommon: pfnTransferBuffer %Rrc, cbTransferred %d\n", rc, cbTransferred)); 200 201 /* If some data was transferred, then it is no error. */ 202 if (cbTransferred > 0) 203 { 204 rc = VINF_SUCCESS; 205 } 206 207 break; 208 } 209 210 cbTransferred += cbIO; 211 212 if (cbToTransfer < cbIO) 213 { 214 /* Transferred less than requested, do not continue with the possibly remaining data. */ 215 break; 216 } 217 218 cbToTransfer = pCtx->cbData - cbTransferred; 219 if (cbToTransfer > VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE) 220 { 221 cbToTransfer = VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE; 222 } 223 } 224 } 225 226 pCtx->cbData = cbTransferred; 227 228 return rc; 229 } 22 230 23 231 static NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext) 24 232 { 25 233 NTSTATUS Status = STATUS_SUCCESS; 234 VBSFTRANSFERCTX ctx; 26 235 27 236 RxCaptureFcb; … … 81 290 } 82 291 83 /* @todo Split large reads. */ 84 vboxRC = vboxCallRead(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile, 85 ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */); 292 ctx.pClient = &pDeviceExtension->hgcmClient; 293 ctx.pMap = &pNetRootExtension->map; 294 ctx.hFile = pVBoxFobx->hFile; 295 ctx.offset = (uint64_t)ByteOffset; 296 ctx.cbData = ByteCount; 297 ctx.pMdl = BufferMdl; 298 ctx.pBuffer = (uint8_t *)pbUserBuffer; 299 ctx.fLocked = true; 300 ctx.pfnTransferBuffer = vbsfTransferBufferRead; 301 ctx.pfnTransferPages = vbsfTransferPagesRead; 302 303 vboxRC = vbsfTransferCommon(&ctx); 304 305 ByteCount = ctx.cbData; 86 306 87 307 Status = VBoxErrorToNTStatus(vboxRC); … … 137 357 { 138 358 NTSTATUS Status = STATUS_SUCCESS; 359 VBSFTRANSFERCTX ctx; 139 360 140 361 RxCaptureFcb; … … 175 396 } 176 397 177 /* @todo Split large writes. */ 178 vboxRC = vboxCallWrite(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile, 179 ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */); 398 ctx.pClient = &pDeviceExtension->hgcmClient; 399 ctx.pMap = &pNetRootExtension->map; 400 ctx.hFile = pVBoxFobx->hFile; 401 ctx.offset = (uint64_t)ByteOffset; 402 ctx.cbData = ByteCount; 403 ctx.pMdl = BufferMdl; 404 ctx.pBuffer = (uint8_t *)pbUserBuffer; 405 ctx.fLocked = true; 406 ctx.pfnTransferBuffer = vbsfTransferBufferWrite; 407 ctx.pfnTransferPages = vbsfTransferPagesWrite; 408 409 vboxRC = vbsfTransferCommon(&ctx); 410 411 ByteCount = ctx.cbData; 180 412 181 413 Status = VBoxErrorToNTStatus(vboxRC); -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBGLInternal.h
r42316 r44558 5 5 6 6 /* 7 * Copyright (C) 2006-201 2Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 139 139 * @param a_fLocked For the windows shared folders workarounds. 140 140 * 141 * @remarks Disable the PageList feature for 64-bit Windows, because shared 142 * folders do not work, if this is enabled. This should be reenabled 143 * again when the problem is fixed. 144 * @remarks Disabled the PageList feature for 32-bit Windows, see xTracker 145 * ticket 6096 and public ticket 10290. Hopefully this is the same 146 * issue as on Windows/AMD64. 141 * @remarks Disabled the PageList feature for locked memory on Windows, 142 * because a new MDL is created by VBGL to get the page addresses 143 * and the pages from the MDL are marked as dirty when they should not. 147 144 */ 148 145 #if defined(RT_OS_WINDOWS) 149 # ifdef RT_ARCH_AMD64 150 # define VBGLR0_CAN_USE_PHYS_PAGE_LIST(a_fLocked) ( 0 ) 151 # else 152 # define VBGLR0_CAN_USE_PHYS_PAGE_LIST(a_fLocked) \ 153 ( !(a_fLocked) && (g_vbgldata.hostVersion.features & VMMDEV_HVF_HGCM_PHYS_PAGE_LIST) ) 154 # endif 146 # define VBGLR0_CAN_USE_PHYS_PAGE_LIST(a_fLocked) \ 147 ( !(a_fLocked) && (g_vbgldata.hostVersion.features & VMMDEV_HVF_HGCM_PHYS_PAGE_LIST) ) 155 148 #else 156 149 # define VBGLR0_CAN_USE_PHYS_PAGE_LIST(a_fLocked) \ -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
r44528 r44558 5 5 6 6 /* 7 * Copyright (C) 2006-201 2Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 443 443 } 444 444 445 DECLVBGL(int) VbglR0SharedFolderReadPageList(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 446 uint64_t offset, uint32_t *pcbBuffer, 447 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages) 448 { 449 uint32_t cbToRead = *pcbBuffer; 450 uint32_t cbData = sizeof(VBoxSFRead) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]); 451 VBoxSFRead *pData = (VBoxSFRead *)RTMemTmpAlloc(cbData); 452 HGCMPageListInfo *pPgLst = (HGCMPageListInfo *)(pData + 1); 453 uint16_t iPage; 454 int rc; 455 456 if (RT_UNLIKELY(!pData)) 457 return VERR_NO_TMP_MEMORY; 458 459 VBOX_INIT_CALL(&pData->callInfo, READ, pClient); 460 461 pData->root.type = VMMDevHGCMParmType_32bit; 462 pData->root.u.value32 = pMap->root; 463 464 pData->handle.type = VMMDevHGCMParmType_64bit; 465 pData->handle.u.value64 = hFile; 466 pData->offset.type = VMMDevHGCMParmType_64bit; 467 pData->offset.u.value64 = offset; 468 pData->cb.type = VMMDevHGCMParmType_32bit; 469 pData->cb.u.value32 = cbToRead; 470 pData->buffer.type = VMMDevHGCMParmType_PageList; 471 pData->buffer.u.PageList.size = cbToRead; 472 pData->buffer.u.PageList.offset = sizeof(VBoxSFRead); 473 474 pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST; 475 pPgLst->offFirstPage = offFirstPage; 476 pPgLst->cPages = cPages; 477 for (iPage = 0; iPage < cPages; iPage++) 478 pPgLst->aPages[iPage] = paPages[iPage]; 479 480 rc = VbglHGCMCall(pClient->handle, &pData->callInfo, cbData); 481 if (RT_SUCCESS (rc)) 482 { 483 rc = pData->callInfo.result; 484 *pcbBuffer = pData->cb.u.value32; 485 } 486 487 RTMemTmpFree(pData); 488 return rc; 489 } 490 445 491 DECLVBGL(int) vboxCallWrite(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 446 492 uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked) … … 523 569 return rc; 524 570 571 } 572 573 DECLVBGL(int) VbglR0SharedFolderWritePageList(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 574 uint64_t offset, uint32_t *pcbBuffer, 575 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages) 576 { 577 uint32_t cbToWrite = *pcbBuffer; 578 uint32_t cbData = sizeof(VBoxSFWrite) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]); 579 VBoxSFWrite *pData = (VBoxSFWrite *)RTMemTmpAlloc(cbData); 580 HGCMPageListInfo *pPgLst = (HGCMPageListInfo *)(pData + 1); 581 uint16_t iPage; 582 int rc; 583 584 if (RT_UNLIKELY(!pData)) 585 return VERR_NO_TMP_MEMORY; 586 587 VBOX_INIT_CALL(&pData->callInfo, WRITE, pClient); 588 589 pData->root.type = VMMDevHGCMParmType_32bit; 590 pData->root.u.value32 = pMap->root; 591 592 pData->handle.type = VMMDevHGCMParmType_64bit; 593 pData->handle.u.value64 = hFile; 594 pData->offset.type = VMMDevHGCMParmType_64bit; 595 pData->offset.u.value64 = offset; 596 pData->cb.type = VMMDevHGCMParmType_32bit; 597 pData->cb.u.value32 = cbToWrite; 598 pData->buffer.type = VMMDevHGCMParmType_PageList; 599 pData->buffer.u.PageList.size = cbToWrite; 600 pData->buffer.u.PageList.offset = sizeof(VBoxSFWrite); 601 602 pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST; 603 pPgLst->offFirstPage = offFirstPage; 604 pPgLst->cPages = cPages; 605 for (iPage = 0; iPage < cPages; iPage++) 606 pPgLst->aPages[iPage] = paPages[iPage]; 607 608 rc = VbglHGCMCall (pClient->handle, &pData->callInfo, cbData); 609 if (RT_SUCCESS (rc)) 610 { 611 rc = pData->callInfo.result; 612 *pcbBuffer = pData->cb.u.value32; 613 } 614 615 RTMemTmpFree(pData); 616 return rc; 525 617 } 526 618 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h
r44528 r44558 4 4 5 5 /* 6 * Copyright (C) 2006-201 2Oracle Corporation6 * Copyright (C) 2006-2013 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 173 173 174 174 DECLVBGL(int) vboxCallRead (PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked); 175 DECLVBGL(int) VbglR0SharedFolderReadPageList(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 176 uint64_t offset, uint32_t *pcbBuffer, 177 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages); 175 178 DECLVBGL(int) vboxCallWrite (PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked); 176 179 DECLVBGL(int) VbglR0SfWritePhysCont(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer, RTCCPHYS PhysBuffer); 180 DECLVBGL(int) VbglR0SharedFolderWritePageList(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, 181 uint64_t offset, uint32_t *pcbBuffer, 182 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages); 177 183 178 184 DECLVBGL(int) vboxCallLock (PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile, uint64_t offset, uint64_t cbSize, uint32_t fLock); -
trunk/src/VBox/Additions/common/VBoxGuestLib/VbglR0CanUsePhysPageList.cpp
r44528 r44558 5 5 6 6 /* 7 * Copyright (C) 2006-201 2Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 35 35 DECLR0VBGL(bool) VbglR0CanUsePhysPageList(void) 36 36 { 37 /* a_fLocked is false, because the actual capability of the host is requested. 38 * See VBGLR0_CAN_USE_PHYS_PAGE_LIST definition. 39 */ 37 40 int rc = vbglR0Enter(); 38 41 return RT_SUCCESS(rc)
Note:
See TracChangeset
for help on using the changeset viewer.