VirtualBox

Changeset 76693 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Jan 8, 2019 6:07:36 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
128000
Message:

os2/VBoxSF: Added fallbacks for older hosts that doesn't support embedded buffers and contiguous page lists.

Location:
trunk/src/VBox/Additions/os2/VBoxSF
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/os2/VBoxSF/VBoxSF.cpp

    r76448 r76693  
    5858*   Global Variables                                                                                                             *
    5959*********************************************************************************************************************************/
     60/** VMMDEV_HVF_XXX (set during init). */
     61uint32_t            g_fHostFeatures = 0;
    6062/** The shared mutex protecting folders list, drives and the connection. */
    6163MutexLock_t         g_MtxFolders;
  • trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFFile.cpp

    r76448 r76693  
    11911191
    11921192    /*
    1193      * Whatever we do now we're going to use a page list request.
    1194      * So, allocate one with sufficient space to cover the whole buffer.
     1193     * Whatever we do now we're going to use a page list request structure.
     1194     * So, we do one allocation large enough for both code paths below.
    11951195     */
    11961196    uint32_t cPages = ((cbToRead + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1;
     
    12221222        if (pvBuf)
    12231223        {
    1224             pReq->PgLst.offFirstPage = (uint16_t)GCPhys & (uint16_t)PAGE_OFFSET_MASK;
    1225             cPages = (cbToRead + ((uint16_t)GCPhys & (uint16_t)PAGE_OFFSET_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
    1226             GCPhys &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
    1227             for (uint32_t i = 0; i < cPages; i++, GCPhys += PAGE_SIZE)
    1228                 pReq->PgLst.aPages[i] = GCPhys;
    1229 
    12301224            APIRET rc;
    1231             int vrc = vboxSfOs2HostReqReadPgLst(pFolder, pReq, pSfFsd->hHostFile, offRead, cbToRead, cPages);
     1225            int vrc = vboxSfOs2HostReqReadContig(pFolder, pReq, pSfFsd->hHostFile, offRead, cbToRead, pvBuf, GCPhys);
    12321226            if (RT_SUCCESS(vrc))
    12331227            {
     
    13641358
    13651359    /*
    1366      * Whatever we do now we're going to use a page list request.
    1367      * So, allocate one with sufficient space to cover the whole buffer.
     1360     * Whatever we do now we're going to use a page list request structure.
     1361     * So, we do one allocation large enough for both code paths below.
    13681362     */
    13691363    uint32_t cPages = ((cbToWrite + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1;
     
    13981392            if (rc == NO_ERROR)
    13991393            {
    1400                 pReq->PgLst.offFirstPage = (uint16_t)GCPhys & (uint16_t)PAGE_OFFSET_MASK;
    1401                 cPages = (cbToWrite + ((uint16_t)GCPhys & (uint16_t)PAGE_OFFSET_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
    1402                 GCPhys &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
    1403                 for (uint32_t i = 0; i < cPages; i++, GCPhys += PAGE_SIZE)
    1404                     pReq->PgLst.aPages[i] = GCPhys;
    1405 
    14061394                APIRET rc;
    1407                 int vrc = vboxSfOs2HostReqWritePgLst(pFolder, pReq, pSfFsd->hHostFile, offWrite, cbToWrite, cPages);
     1395                int vrc = vboxSfOs2HostReqWriteContig(pFolder, pReq, pSfFsd->hHostFile, offWrite, cbToWrite, pvBuf, GCPhys);
    14081396                if (RT_SUCCESS(vrc))
    14091397                {
  • trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFInit.cpp

    r76665 r76693  
    104104                else
    105105                {
     106                    g_fHostFeatures = fFeatures;
    106107                    if (!(fFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS))
    107108                        RTLogBackdoorPrintf("VBoxSFR0Init: WARNING! Embedded buffers feature is missing.  Upgrade to latest VirtualBox!\n");
  • trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFInternal.h

    r76666 r76693  
    235235
    236236extern VBGLSFCLIENT g_SfClient;
     237extern uint32_t g_fHostFeatures;
    237238
    238239void        vboxSfOs2InitFileBuffers(void);
     
    274275    VMMDevHGCMCall          Call;
    275276    VBoxSFParmMapFolder     Parms;
    276     union
    277     {
    278         HGCMPageListInfo    PgLst;
    279         uint8_t             abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
    280     } u;
     277    HGCMPageListInfo        PgLst;
    281278} VBOXSFMAPFOLDERWITHBUFREQ;
    282279
     
    287284                                                 RTUTF16 wcDelimiter, bool fCaseSensitive)
    288285{
    289     pReq->Parms.id32Root.type               = VMMDevHGCMParmType_32bit;
    290     pReq->Parms.id32Root.u.value32          = SHFL_ROOT_NIL;
    291 
    292     pReq->Parms.uc32Delimiter.type          = VMMDevHGCMParmType_32bit;
    293     pReq->Parms.uc32Delimiter.u.value32     = wcDelimiter;
    294 
    295     pReq->Parms.fCaseSensitive.type         = VMMDevHGCMParmType_32bit;
    296     pReq->Parms.fCaseSensitive.u.value32    = fCaseSensitive;
    297 
    298     AssertReturn(pStrName->u16Size <= PAGE_SIZE - SHFLSTRING_HEADER_SIZE, VERR_FILENAME_TOO_LONG);
    299     pReq->Parms.pStrName.type               = VMMDevHGCMParmType_PageList;
    300     pReq->Parms.pStrName.u.PageList.size    = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
    301     pReq->Parms.pStrName.u.PageList.offset  = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    302     pReq->u.PgLst.flags                     = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
    303     pReq->u.PgLst.aPages[0]                 = VbglR0PhysHeapGetPhysAddr(pStrName);
    304     pReq->u.PgLst.offFirstPage              = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
    305     pReq->u.PgLst.aPages[0]                &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
    306     uint32_t cbReq;
    307     if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= pStrName->u16Size + SHFLSTRING_HEADER_SIZE)
    308     {
    309         pReq->u.PgLst.cPages            = 1;
    310         cbReq = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst.aPages[1]);
    311     }
    312     else
    313     {
    314         pReq->u.PgLst.aPages[1]         = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
    315         pReq->u.PgLst.cPages            = 2;
    316         cbReq = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, u.PgLst.aPages[2]);
    317     }
    318 
    319     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    320                                 SHFL_FN_MAP_FOLDER, SHFL_CPARMS_MAP_FOLDER, cbReq);
    321 
    322     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
     286    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     287                                SHFL_FN_MAP_FOLDER, SHFL_CPARMS_MAP_FOLDER, sizeof(*pReq));
     288
     289    pReq->Parms.id32Root.type                   = VMMDevHGCMParmType_32bit;
     290    pReq->Parms.id32Root.u.value32              = SHFL_ROOT_NIL;
     291
     292    pReq->Parms.uc32Delimiter.type              = VMMDevHGCMParmType_32bit;
     293    pReq->Parms.uc32Delimiter.u.value32         = wcDelimiter;
     294
     295    pReq->Parms.fCaseSensitive.type             = VMMDevHGCMParmType_32bit;
     296    pReq->Parms.fCaseSensitive.u.value32        = fCaseSensitive;
     297
     298    if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
     299    {
     300        pReq->Parms.pStrName.type               = VMMDevHGCMParmType_PageList;
     301        pReq->Parms.pStrName.u.PageList.size    = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
     302        pReq->Parms.pStrName.u.PageList.offset  = RT_UOFFSETOF(VBOXSFMAPFOLDERWITHBUFREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     303        pReq->PgLst.flags                       = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
     304        pReq->PgLst.aPages[0]                   = VbglR0PhysHeapGetPhysAddr(pStrName);
     305        pReq->PgLst.offFirstPage                = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
     306        pReq->PgLst.aPages[0]                  &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
     307        pReq->PgLst.cPages                      = 1;
     308    }
     309    else
     310    {
     311        pReq->Parms.pStrName.type               = VMMDevHGCMParmType_LinAddr_In;
     312        pReq->Parms.pStrName.u.LinAddr.cb       = SHFLSTRING_HEADER_SIZE + pStrName->u16Size;
     313        pReq->Parms.pStrName.u.LinAddr.uAddr    = (uintptr_t)pStrName;
     314    }
     315
     316    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
    323317    if (RT_SUCCESS(vrc))
    324318        vrc = pReq->Call.header.result;
     
    377371DECLINLINE(int) vboxSfOs2HostReqCreate(PVBOXSFFOLDER pFolder, VBOXSFCREATEREQ *pReq)
    378372{
    379     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    380                                 SHFL_FN_CREATE, SHFL_CPARMS_CREATE,
    381                                 RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size);
     373    uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
     374                         ? RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size
     375                         : RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms);
     376    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     377                                SHFL_FN_CREATE, SHFL_CPARMS_CREATE, cbReq);
    382378
    383379    pReq->Parms.id32Root.type                   = VMMDevHGCMParmType_32bit;
    384380    pReq->Parms.id32Root.u.value32              = pFolder->hHostFolder.root;
    385381
    386     pReq->Parms.pStrPath.type                   = VMMDevHGCMParmType_Embedded;
    387     pReq->Parms.pStrPath.u.Embedded.cbData      = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
    388     pReq->Parms.pStrPath.u.Embedded.offData     = RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    389     pReq->Parms.pStrPath.u.Embedded.fFlags      = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
    390 
    391     pReq->Parms.pCreateParms.type               = VMMDevHGCMParmType_Embedded;
    392     pReq->Parms.pCreateParms.u.Embedded.cbData  = sizeof(pReq->CreateParms);
    393     pReq->Parms.pCreateParms.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    394     pReq->Parms.pCreateParms.u.Embedded.fFlags  = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
    395 
    396     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
    397                                  RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + pReq->StrPath.u16Size);
     382    if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
     383    {
     384        pReq->Parms.pStrPath.type                   = VMMDevHGCMParmType_Embedded;
     385        pReq->Parms.pStrPath.u.Embedded.cbData      = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
     386        pReq->Parms.pStrPath.u.Embedded.offData     = RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     387        pReq->Parms.pStrPath.u.Embedded.fFlags      = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     388
     389        pReq->Parms.pCreateParms.type               = VMMDevHGCMParmType_Embedded;
     390        pReq->Parms.pCreateParms.u.Embedded.cbData  = sizeof(pReq->CreateParms);
     391        pReq->Parms.pCreateParms.u.Embedded.offData = RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     392        pReq->Parms.pCreateParms.u.Embedded.fFlags  = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
     393    }
     394    else
     395    {
     396        pReq->Parms.pStrPath.type                   = VMMDevHGCMParmType_LinAddr_In;
     397        pReq->Parms.pStrPath.u.LinAddr.cb           = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
     398        pReq->Parms.pStrPath.u.LinAddr.uAddr        = (uintptr_t)&pReq->StrPath;
     399
     400        pReq->Parms.pCreateParms.type               = VMMDevHGCMParmType_LinAddr;
     401        pReq->Parms.pCreateParms.u.LinAddr.cb       = sizeof(pReq->CreateParms);
     402        pReq->Parms.pCreateParms.u.LinAddr.uAddr    = (uintptr_t)&pReq->CreateParms;
     403    }
     404
     405    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
    398406    if (RT_SUCCESS(vrc))
    399407        vrc = pReq->Call.header.result;
     
    460468DECLINLINE(int) vboxSfOs2HostReqQueryVolInfo(PVBOXSFFOLDER pFolder, VBOXSFVOLINFOREQ *pReq, uint64_t hHostFile)
    461469{
    462     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    463                                 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
     470    uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
     471                         ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo);
     472    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     473                                SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
    464474
    465475    pReq->Parms.id32Root.type                   = VMMDevHGCMParmType_32bit;
     
    475485    pReq->Parms.cb32.u.value32                  = sizeof(pReq->VolInfo);
    476486
    477     pReq->Parms.pInfo.type                      = VMMDevHGCMParmType_Embedded;
    478     pReq->Parms.pInfo.u.Embedded.cbData         = sizeof(pReq->VolInfo);
    479     pReq->Parms.pInfo.u.Embedded.offData        = RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    480     pReq->Parms.pInfo.u.Embedded.fFlags         = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
    481 
    482     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
     487    if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
     488    {
     489        pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_Embedded;
     490        pReq->Parms.pInfo.u.Embedded.cbData     = sizeof(pReq->VolInfo);
     491        pReq->Parms.pInfo.u.Embedded.offData    = RT_UOFFSETOF(VBOXSFVOLINFOREQ, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     492        pReq->Parms.pInfo.u.Embedded.fFlags     = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
     493    }
     494    else
     495    {
     496        pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_LinAddr_Out;
     497        pReq->Parms.pInfo.u.LinAddr.cb          = sizeof(pReq->VolInfo);
     498        pReq->Parms.pInfo.u.LinAddr.uAddr       = (uintptr_t)&pReq->VolInfo;
     499    }
     500
     501    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
    483502    if (RT_SUCCESS(vrc))
    484503        vrc = pReq->Call.header.result;
     
    501520DECLINLINE(int) vboxSfOs2HostReqQueryObjInfo(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
    502521{
     522    uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
     523                         ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
     524    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     525                                SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
     526
     527    pReq->Parms.id32Root.type                   = VMMDevHGCMParmType_32bit;
     528    pReq->Parms.id32Root.u.value32              = pFolder->hHostFolder.root;
     529
     530    pReq->Parms.u64Handle.type                  = VMMDevHGCMParmType_64bit;
     531    pReq->Parms.u64Handle.u.value64             = hHostFile;
     532
     533    pReq->Parms.f32Flags.type                   = VMMDevHGCMParmType_32bit;
     534    pReq->Parms.f32Flags.u.value32              = SHFL_INFO_GET | SHFL_INFO_FILE;
     535
     536    pReq->Parms.cb32.type                       = VMMDevHGCMParmType_32bit;
     537    pReq->Parms.cb32.u.value32                  = sizeof(pReq->ObjInfo);
     538
     539    if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
     540    {
     541        pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_Embedded;
     542        pReq->Parms.pInfo.u.Embedded.cbData     = sizeof(pReq->ObjInfo);
     543        pReq->Parms.pInfo.u.Embedded.offData    = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     544        pReq->Parms.pInfo.u.Embedded.fFlags     = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
     545    }
     546    else
     547    {
     548        pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_LinAddr_Out;
     549        pReq->Parms.pInfo.u.LinAddr.cb          = sizeof(pReq->ObjInfo);
     550        pReq->Parms.pInfo.u.LinAddr.uAddr       = (uintptr_t)&pReq->ObjInfo;
     551    }
     552
     553    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
     554    if (RT_SUCCESS(vrc))
     555        vrc = pReq->Call.header.result;
     556    return vrc;
     557}
     558
     559
     560/**
     561 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request.
     562 */
     563DECLINLINE(int) vboxSfOs2HostReqSetObjInfo(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
     564{
     565    uint32_t const cbReq = g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS
     566                         ? sizeof(*pReq) : RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo);
     567    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     568                                SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
     569
     570    pReq->Parms.id32Root.type                   = VMMDevHGCMParmType_32bit;
     571    pReq->Parms.id32Root.u.value32              = pFolder->hHostFolder.root;
     572
     573    pReq->Parms.u64Handle.type                  = VMMDevHGCMParmType_64bit;
     574    pReq->Parms.u64Handle.u.value64             = hHostFile;
     575
     576    pReq->Parms.f32Flags.type                   = VMMDevHGCMParmType_32bit;
     577    pReq->Parms.f32Flags.u.value32              = SHFL_INFO_SET | SHFL_INFO_FILE;
     578
     579    pReq->Parms.cb32.type                       = VMMDevHGCMParmType_32bit;
     580    pReq->Parms.cb32.u.value32                  = sizeof(pReq->ObjInfo);
     581
     582    if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
     583    {
     584        pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_Embedded;
     585        pReq->Parms.pInfo.u.Embedded.cbData     = sizeof(pReq->ObjInfo);
     586        pReq->Parms.pInfo.u.Embedded.offData    = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     587        pReq->Parms.pInfo.u.Embedded.fFlags     = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
     588    }
     589    else
     590    {
     591        pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_LinAddr;
     592        pReq->Parms.pInfo.u.LinAddr.cb          = sizeof(pReq->ObjInfo);
     593        pReq->Parms.pInfo.u.LinAddr.uAddr       = (uintptr_t)&pReq->ObjInfo;
     594    }
     595
     596    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
     597    if (RT_SUCCESS(vrc))
     598        vrc = pReq->Call.header.result;
     599    return vrc;
     600}
     601
     602
     603/** Request structure for vboxSfOs2HostReqSetObjInfo.  */
     604typedef struct VBOXSFOBJINFOWITHBUFREQ
     605{
     606    VBGLIOCIDCHGCMFASTCALL  Hdr;
     607    VMMDevHGCMCall          Call;
     608    VBoxSFParmInformation   Parms;
     609    HGCMPageListInfo        PgLst;
     610} VBOXSFOBJINFOWITHBUFREQ;
     611
     612/**
     613 * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request, with separate
     614 * buffer (on the physical heap).
     615 */
     616DECLINLINE(int) vboxSfOs2HostReqSetObjInfoWithBuf(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOWITHBUFREQ *pReq, uint64_t hHostFile,
     617                                                  PSHFLFSOBJINFO pObjInfo, uint32_t offObjInfoInAlloc)
     618{
    503619    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    504620                                SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
     
    511627
    512628    pReq->Parms.f32Flags.type               = VMMDevHGCMParmType_32bit;
    513     pReq->Parms.f32Flags.u.value32          = SHFL_INFO_GET | SHFL_INFO_FILE;
     629    pReq->Parms.f32Flags.u.value32          = SHFL_INFO_SET | SHFL_INFO_FILE;
    514630
    515631    pReq->Parms.cb32.type                   = VMMDevHGCMParmType_32bit;
    516     pReq->Parms.cb32.u.value32              = sizeof(pReq->ObjInfo);
    517 
    518     pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_Embedded;
    519     pReq->Parms.pInfo.u.Embedded.cbData     = sizeof(pReq->ObjInfo);
    520     pReq->Parms.pInfo.u.Embedded.offData    = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    521     pReq->Parms.pInfo.u.Embedded.fFlags     = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
     632    pReq->Parms.cb32.u.value32              = sizeof(*pObjInfo);
     633
     634    if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
     635    {
     636        pReq->Parms.pInfo.type              = VMMDevHGCMParmType_ContiguousPageList;
     637        pReq->Parms.pInfo.u.PageList.size   = sizeof(*pObjInfo);
     638        pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     639        pReq->PgLst.flags                   = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
     640        pReq->PgLst.aPages[0]               = VbglR0PhysHeapGetPhysAddr((uint8_t *)pObjInfo - offObjInfoInAlloc) + offObjInfoInAlloc;
     641        pReq->PgLst.offFirstPage            = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
     642        pReq->PgLst.aPages[0]              &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
     643        pReq->PgLst.cPages                  = 1;
     644    }
     645    else
     646    {
     647        pReq->Parms.pInfo.type              = VMMDevHGCMParmType_LinAddr;
     648        pReq->Parms.pInfo.u.LinAddr.cb      = sizeof(*pObjInfo);
     649        pReq->Parms.pInfo.u.LinAddr.uAddr   = (uintptr_t)pObjInfo;
     650    }
    522651
    523652    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
    524     if (RT_SUCCESS(vrc))
    525         vrc = pReq->Call.header.result;
    526     return vrc;
    527 }
    528 
    529 
    530 /**
    531  * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request.
    532  */
    533 DECLINLINE(int) vboxSfOs2HostReqSetObjInfo(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOREQ *pReq, uint64_t hHostFile)
    534 {
    535     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    536                                 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
    537 
    538     pReq->Parms.id32Root.type               = VMMDevHGCMParmType_32bit;
    539     pReq->Parms.id32Root.u.value32          = pFolder->hHostFolder.root;
    540 
    541     pReq->Parms.u64Handle.type              = VMMDevHGCMParmType_64bit;
    542     pReq->Parms.u64Handle.u.value64         = hHostFile;
    543 
    544     pReq->Parms.f32Flags.type               = VMMDevHGCMParmType_32bit;
    545     pReq->Parms.f32Flags.u.value32          = SHFL_INFO_SET | SHFL_INFO_FILE;
    546 
    547     pReq->Parms.cb32.type                   = VMMDevHGCMParmType_32bit;
    548     pReq->Parms.cb32.u.value32              = sizeof(pReq->ObjInfo);
    549 
    550     pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_Embedded;
    551     pReq->Parms.pInfo.u.Embedded.cbData     = sizeof(pReq->ObjInfo);
    552     pReq->Parms.pInfo.u.Embedded.offData    = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    553     pReq->Parms.pInfo.u.Embedded.fFlags     = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
    554 
    555     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
    556     if (RT_SUCCESS(vrc))
    557         vrc = pReq->Call.header.result;
    558     return vrc;
    559 }
    560 
    561 
    562 /** Request structure for vboxSfOs2HostReqSetObjInfo.  */
    563 typedef struct VBOXSFOBJINFOWITHBUFREQ
    564 {
    565     VBGLIOCIDCHGCMFASTCALL  Hdr;
    566     VMMDevHGCMCall          Call;
    567     VBoxSFParmInformation   Parms;
    568     union
    569     {
    570         HGCMPageListInfo    PgLst;
    571         uint8_t             abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
    572     } u;
    573 } VBOXSFOBJINFOWITHBUFREQ;
    574 
    575 /**
    576  * SHFL_FN_INFORMATION[SHFL_INFO_SET | SHFL_INFO_FILE] request, with separate
    577  * buffer (on the physical heap).
    578  */
    579 DECLINLINE(int) vboxSfOs2HostReqSetObjInfoWithBuf(PVBOXSFFOLDER pFolder, VBOXSFOBJINFOWITHBUFREQ *pReq, uint64_t hHostFile,
    580                                                   PSHFLFSOBJINFO pObjInfo, uint32_t offObjInfoInAlloc)
    581 {
    582     pReq->Parms.id32Root.type           = VMMDevHGCMParmType_32bit;
    583     pReq->Parms.id32Root.u.value32      = pFolder->hHostFolder.root;
    584 
    585     pReq->Parms.u64Handle.type          = VMMDevHGCMParmType_64bit;
    586     pReq->Parms.u64Handle.u.value64     = hHostFile;
    587 
    588     pReq->Parms.f32Flags.type           = VMMDevHGCMParmType_32bit;
    589     pReq->Parms.f32Flags.u.value32      = SHFL_INFO_SET | SHFL_INFO_FILE;
    590 
    591     pReq->Parms.cb32.type               = VMMDevHGCMParmType_32bit;
    592     pReq->Parms.cb32.u.value32          = sizeof(*pObjInfo);
    593 
    594     pReq->Parms.pInfo.type              = VMMDevHGCMParmType_PageList;
    595     pReq->Parms.pInfo.u.PageList.size   = sizeof(*pObjInfo);
    596     pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(VBOXSFOBJINFOREQ, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    597     pReq->u.PgLst.flags                 = VBOX_HGCM_F_PARM_DIRECTION_BOTH;
    598     pReq->u.PgLst.aPages[0]             = VbglR0PhysHeapGetPhysAddr((uint8_t *)pObjInfo - offObjInfoInAlloc) + offObjInfoInAlloc;
    599     pReq->u.PgLst.offFirstPage          = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
    600     pReq->u.PgLst.aPages[0]            &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
    601     uint32_t cbReq;
    602     if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= sizeof(*pObjInfo))
    603     {
    604         pReq->u.PgLst.cPages            = 1;
    605         cbReq = RT_UOFFSETOF(VBOXSFOBJINFOWITHBUFREQ, u.PgLst.aPages[1]);
    606     }
    607     else
    608     {
    609         pReq->u.PgLst.aPages[1]         = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
    610         pReq->u.PgLst.cPages            = 2;
    611         cbReq = RT_UOFFSETOF(VBOXSFOBJINFOWITHBUFREQ, u.PgLst.aPages[2]);
    612     }
    613 
    614     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    615                                 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, cbReq);
    616 
    617     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
    618653    if (RT_SUCCESS(vrc))
    619654        vrc = pReq->Call.header.result;
     
    636671DECLINLINE(int) vboxSfOs2HostReqRemove(PVBOXSFFOLDER pFolder, VBOXSFREMOVEREQ *pReq, uint32_t fFlags)
    637672{
    638     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    639                                 SHFL_FN_REMOVE, SHFL_CPARMS_REMOVE,
    640                                 RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + pReq->StrPath.u16Size);
     673    uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String)
     674                         + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrPath.u16Size : 0);
     675    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     676                                SHFL_FN_REMOVE, SHFL_CPARMS_REMOVE, cbReq);
    641677
    642678    pReq->Parms.id32Root.type                   = VMMDevHGCMParmType_32bit;
    643679    pReq->Parms.id32Root.u.value32              = pFolder->hHostFolder.root;
    644680
    645     pReq->Parms.pStrPath.type                   = VMMDevHGCMParmType_Embedded;
    646     pReq->Parms.pStrPath.u.Embedded.cbData      = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
    647     pReq->Parms.pStrPath.u.Embedded.offData     = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    648     pReq->Parms.pStrPath.u.Embedded.fFlags      = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     681    if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
     682    {
     683        pReq->Parms.pStrPath.type               = VMMDevHGCMParmType_Embedded;
     684        pReq->Parms.pStrPath.u.Embedded.cbData  = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
     685        pReq->Parms.pStrPath.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     686        pReq->Parms.pStrPath.u.Embedded.fFlags  = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     687    }
     688    else
     689    {
     690        pReq->Parms.pStrPath.type               = VMMDevHGCMParmType_LinAddr_In;
     691        pReq->Parms.pStrPath.u.LinAddr.cb       = SHFLSTRING_HEADER_SIZE + pReq->StrPath.u16Size;
     692        pReq->Parms.pStrPath.u.LinAddr.uAddr    = (uintptr_t)&pReq->StrPath;
     693    }
    649694
    650695    pReq->Parms.f32Flags.type                   = VMMDevHGCMParmType_32bit;
    651696    pReq->Parms.f32Flags.u.value32              = fFlags;
    652697
    653     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
    654                                  RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + pReq->StrPath.u16Size);
     698    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
    655699    if (RT_SUCCESS(vrc))
    656700        vrc = pReq->Call.header.result;
     
    665709    VMMDevHGCMCall          Call;
    666710    VBoxSFParmRename        Parms;
    667     union
    668     {
    669         HGCMPageListInfo    PgLst;
    670         uint8_t             abPadding[8 + sizeof(RTGCPHYS64) * 2 /*RT_UOFFSETOF(HGCMPageListInfo, aPages[2])*/];
    671     } u;
     711    HGCMPageListInfo        PgLst;
    672712    SHFLSTRING              StrDstPath;
    673713} VBOXSFRENAMEWITHSRCBUFREQ;
     
    679719                                                 PSHFLSTRING pSrcStr, uint32_t fFlags)
    680720{
    681     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    682                                 SHFL_FN_RENAME, SHFL_CPARMS_RENAME,
    683                                 RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String) + pReq->StrDstPath.u16Size);
    684 
    685     pReq->Parms.id32Root.type                   = VMMDevHGCMParmType_32bit;
    686     pReq->Parms.id32Root.u.value32              = pFolder->hHostFolder.root;
    687 
    688     /** @todo Using page lists for contiguous buffers sucks.   */
    689     AssertReturn(pSrcStr->u16Size <= PAGE_SIZE - SHFLSTRING_HEADER_SIZE, VERR_FILENAME_TOO_LONG);
    690     pReq->Parms.pStrSrcPath.type                = VMMDevHGCMParmType_PageList;
    691     pReq->Parms.pStrSrcPath.u.PageList.size     = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
    692     pReq->Parms.pStrSrcPath.u.PageList.offset   = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, u.PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    693     pReq->u.PgLst.flags                         = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
    694     pReq->u.PgLst.aPages[0]                     = VbglR0PhysHeapGetPhysAddr(pSrcStr);
    695     pReq->u.PgLst.offFirstPage                  = (uint16_t)(pReq->u.PgLst.aPages[0] & PAGE_OFFSET_MASK);
    696     pReq->u.PgLst.aPages[0]                    &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
    697     if (PAGE_SIZE - pReq->u.PgLst.offFirstPage <= SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size)
    698     {
    699         pReq->u.PgLst.aPages[1]                 = NIL_RTGCPHYS64;
    700         pReq->u.PgLst.cPages                    = 1;
    701     }
    702     else
    703     {
    704         pReq->u.PgLst.aPages[1]                 = pReq->u.PgLst.aPages[0] + PAGE_SIZE;
    705         pReq->u.PgLst.cPages                    = 2;
    706     }
    707 
    708     pReq->Parms.pStrDstPath.type                = VMMDevHGCMParmType_Embedded;
    709     pReq->Parms.pStrDstPath.u.Embedded.cbData   = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
    710     pReq->Parms.pStrDstPath.u.Embedded.offData  = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    711     pReq->Parms.pStrDstPath.u.Embedded.fFlags   = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
    712 
    713     pReq->Parms.f32Flags.type                   = VMMDevHGCMParmType_32bit;
    714     pReq->Parms.f32Flags.u.value32              = fFlags;
    715 
    716     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr,
    717                                  RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String) + pReq->StrDstPath.u16Size);
     721    uint32_t const cbReq = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String)
     722                         + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? pReq->StrDstPath.u16Size : 0);
     723    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     724                                SHFL_FN_RENAME, SHFL_CPARMS_RENAME, cbReq);
     725
     726    pReq->Parms.id32Root.type                       = VMMDevHGCMParmType_32bit;
     727    pReq->Parms.id32Root.u.value32                  = pFolder->hHostFolder.root;
     728
     729    if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
     730    {
     731        pReq->Parms.pStrSrcPath.type                = VMMDevHGCMParmType_ContiguousPageList;
     732        pReq->Parms.pStrSrcPath.u.PageList.size     = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
     733        pReq->Parms.pStrSrcPath.u.PageList.offset   = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, PgLst)
     734                                                    - sizeof(VBGLIOCIDCHGCMFASTCALL);
     735        pReq->PgLst.flags                           = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     736        pReq->PgLst.aPages[0]                       = VbglR0PhysHeapGetPhysAddr(pSrcStr);
     737        pReq->PgLst.offFirstPage                    = (uint16_t)(pReq->PgLst.aPages[0] & PAGE_OFFSET_MASK);
     738        pReq->PgLst.aPages[0]                      &= ~(RTGCPHYS)PAGE_OFFSET_MASK;
     739        pReq->PgLst.cPages                          = 1;
     740    }
     741    else
     742    {
     743        pReq->Parms.pStrSrcPath.type                = VMMDevHGCMParmType_LinAddr_In;
     744        pReq->Parms.pStrSrcPath.u.LinAddr.cb        = SHFLSTRING_HEADER_SIZE + pSrcStr->u16Size;
     745        pReq->Parms.pStrSrcPath.u.LinAddr.uAddr     = (uintptr_t)pSrcStr;
     746    }
     747
     748    if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
     749    {
     750        pReq->Parms.pStrDstPath.type                = VMMDevHGCMParmType_Embedded;
     751        pReq->Parms.pStrDstPath.u.Embedded.cbData   = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
     752        pReq->Parms.pStrDstPath.u.Embedded.offData  = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath)
     753                                                    - sizeof(VBGLIOCIDCHGCMFASTCALL);
     754        pReq->Parms.pStrDstPath.u.Embedded.fFlags   = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     755    }
     756    else
     757    {
     758        pReq->Parms.pStrDstPath.type                = VMMDevHGCMParmType_LinAddr_In;
     759        pReq->Parms.pStrDstPath.u.LinAddr.cb        = SHFLSTRING_HEADER_SIZE + pReq->StrDstPath.u16Size;
     760        pReq->Parms.pStrDstPath.u.LinAddr.uAddr     = (uintptr_t)&pReq->StrDstPath;
     761    }
     762
     763    pReq->Parms.f32Flags.type                       = VMMDevHGCMParmType_32bit;
     764    pReq->Parms.f32Flags.u.value32                  = fFlags;
     765
     766    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
    718767    if (RT_SUCCESS(vrc))
    719768        vrc = pReq->Call.header.result;
     
    829878                                             uint64_t offRead, uint32_t cbToRead)
    830879{
    831     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    832                                 SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) + cbToRead);
     880    uint32_t const cbReq = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0])
     881                         + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToRead : 0);
     882    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     883                                SHFL_FN_READ, SHFL_CPARMS_READ, cbReq);
    833884
    834885    pReq->Parms.id32Root.type               = VMMDevHGCMParmType_32bit;
     
    844895    pReq->Parms.cb32Read.u.value32          = cbToRead;
    845896
    846     pReq->Parms.pBuf.type                   = VMMDevHGCMParmType_Embedded;
    847     pReq->Parms.pBuf.u.Embedded.cbData      = cbToRead;
    848     pReq->Parms.pBuf.u.Embedded.offData     = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    849     pReq->Parms.pBuf.u.Embedded.fFlags      = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
    850 
    851     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) + cbToRead);
    852     if (RT_SUCCESS(vrc))
    853         vrc = pReq->Call.header.result;
    854     return vrc;
    855 }
    856 
    857 
    858 /** Request structure for vboxSfOs2HostReqRead. */
     897    if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
     898    {
     899        pReq->Parms.pBuf.type               = VMMDevHGCMParmType_Embedded;
     900        pReq->Parms.pBuf.u.Embedded.cbData  = cbToRead;
     901        pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFREADEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     902        pReq->Parms.pBuf.u.Embedded.fFlags  = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
     903    }
     904    else
     905    {
     906        pReq->Parms.pBuf.type               = VMMDevHGCMParmType_LinAddr_Out;
     907        pReq->Parms.pBuf.u.LinAddr.cb       = cbToRead;
     908        pReq->Parms.pBuf.u.LinAddr.uAddr    = (uintptr_t)&pReq->abData[0];
     909    }
     910
     911    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
     912    if (RT_SUCCESS(vrc))
     913        vrc = pReq->Call.header.result;
     914    return vrc;
     915}
     916
     917
     918/** Request structure for vboxSfOs2HostReqRead & vboxSfOs2HostReqReadContig. */
    859919typedef struct VBOXSFREADPGLSTREQ
    860920{
     
    903963
    904964
     965/**
     966 * SHFL_FN_READ request using a physically contiguous buffer.
     967 */
     968DECLINLINE(int) vboxSfOs2HostReqReadContig(PVBOXSFFOLDER pFolder, VBOXSFREADPGLSTREQ *pReq, uint64_t hHostFile,
     969                                          uint64_t offRead, uint32_t cbToRead, void *pvBuffer, RTGCPHYS64 PhysBuffer)
     970{
     971    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     972                                SHFL_FN_READ, SHFL_CPARMS_READ, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
     973
     974    pReq->Parms.id32Root.type               = VMMDevHGCMParmType_32bit;
     975    pReq->Parms.id32Root.u.value32          = pFolder->hHostFolder.root;
     976
     977    pReq->Parms.u64Handle.type              = VMMDevHGCMParmType_64bit;
     978    pReq->Parms.u64Handle.u.value64         = hHostFile;
     979
     980    pReq->Parms.off64Read.type              = VMMDevHGCMParmType_64bit;
     981    pReq->Parms.off64Read.u.value64         = offRead;
     982
     983    pReq->Parms.cb32Read.type               = VMMDevHGCMParmType_32bit;
     984    pReq->Parms.cb32Read.u.value32          = cbToRead;
     985
     986    if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
     987    {
     988        pReq->Parms.pBuf.type               = VMMDevHGCMParmType_ContiguousPageList;
     989        pReq->Parms.pBuf.u.PageList.size    = cbToRead;
     990        pReq->Parms.pBuf.u.PageList.offset  = RT_UOFFSETOF(VBOXSFREADPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     991        pReq->PgLst.flags                   = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
     992        pReq->PgLst.offFirstPage            = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
     993        pReq->PgLst.cPages                  = 1;
     994        pReq->PgLst.aPages[0]               = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
     995    }
     996    else
     997    {
     998        pReq->Parms.pBuf.type               = VMMDevHGCMParmType_LinAddr_Out;
     999        pReq->Parms.pBuf.u.LinAddr.cb       = cbToRead;
     1000        pReq->Parms.pBuf.u.LinAddr.uAddr    = (uintptr_t)pvBuffer;
     1001    }
     1002
     1003    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, PgLst.aPages[1]));
     1004    if (RT_SUCCESS(vrc))
     1005        vrc = pReq->Call.header.result;
     1006    return vrc;
     1007}
     1008
     1009
    9051010
    9061011/** Request structure for vboxSfOs2HostReqWriteEmbedded. */
     
    9191024                                              uint64_t offWrite, uint32_t cbToWrite)
    9201025{
    921     VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
    922                                 SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) + cbToWrite);
     1026    uint32_t const cbReq = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0])
     1027                         + (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS ? cbToWrite : 0);
     1028    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     1029                                SHFL_FN_WRITE, SHFL_CPARMS_WRITE, cbReq);
    9231030
    9241031    pReq->Parms.id32Root.type               = VMMDevHGCMParmType_32bit;
     
    9341041    pReq->Parms.cb32Write.u.value32         = cbToWrite;
    9351042
    936     pReq->Parms.pBuf.type                   = VMMDevHGCMParmType_Embedded;
    937     pReq->Parms.pBuf.u.Embedded.cbData      = cbToWrite;
    938     pReq->Parms.pBuf.u.Embedded.offData     = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    939     pReq->Parms.pBuf.u.Embedded.fFlags      = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
    940 
    941     int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) + cbToWrite);
    942     if (RT_SUCCESS(vrc))
    943         vrc = pReq->Call.header.result;
    944     return vrc;
    945 }
    946 
    947 
    948 /** Request structure for vboxSfOs2HostReqWrite. */
     1043    if (g_fHostFeatures & VMMDEV_HVF_HGCM_EMBEDDED_BUFFERS)
     1044    {
     1045        pReq->Parms.pBuf.type               = VMMDevHGCMParmType_Embedded;
     1046        pReq->Parms.pBuf.u.Embedded.cbData  = cbToWrite;
     1047        pReq->Parms.pBuf.u.Embedded.offData = RT_UOFFSETOF(VBOXSFWRITEEMBEDDEDREQ, abData[0]) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     1048        pReq->Parms.pBuf.u.Embedded.fFlags  = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     1049    }
     1050    else
     1051    {
     1052        pReq->Parms.pBuf.type               = VMMDevHGCMParmType_LinAddr_In;
     1053        pReq->Parms.pBuf.u.LinAddr.cb       = cbToWrite;
     1054        pReq->Parms.pBuf.u.LinAddr.uAddr    = (uintptr_t)&pReq->abData[0];
     1055    }
     1056
     1057    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, cbReq);
     1058    if (RT_SUCCESS(vrc))
     1059        vrc = pReq->Call.header.result;
     1060    return vrc;
     1061}
     1062
     1063
     1064/** Request structure for vboxSfOs2HostReqWrite and vboxSfOs2HostReqWriteContig. */
    9491065typedef struct VBOXSFWRITEPGLSTREQ
    9501066{
     
    9941110
    9951111/**
     1112 * SHFL_FN_WRITE request using a physically contiguous buffer.
     1113 */
     1114DECLINLINE(int) vboxSfOs2HostReqWriteContig(PVBOXSFFOLDER pFolder, VBOXSFWRITEPGLSTREQ *pReq, uint64_t hHostFile,
     1115                                            uint64_t offWrite, uint32_t cbToWrite, void const *pvBuffer, RTGCPHYS64 PhysBuffer)
     1116{
     1117    VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient,
     1118                                SHFL_FN_WRITE, SHFL_CPARMS_WRITE, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
     1119
     1120    pReq->Parms.id32Root.type               = VMMDevHGCMParmType_32bit;
     1121    pReq->Parms.id32Root.u.value32          = pFolder->hHostFolder.root;
     1122
     1123    pReq->Parms.u64Handle.type              = VMMDevHGCMParmType_64bit;
     1124    pReq->Parms.u64Handle.u.value64         = hHostFile;
     1125
     1126    pReq->Parms.off64Write.type             = VMMDevHGCMParmType_64bit;
     1127    pReq->Parms.off64Write.u.value64        = offWrite;
     1128
     1129    pReq->Parms.cb32Write.type              = VMMDevHGCMParmType_32bit;
     1130    pReq->Parms.cb32Write.u.value32         = cbToWrite;
     1131
     1132    if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
     1133    {
     1134        pReq->Parms.pBuf.type               = VMMDevHGCMParmType_ContiguousPageList;
     1135        pReq->Parms.pBuf.u.PageList.size    = cbToWrite;
     1136        pReq->Parms.pBuf.u.PageList.offset  = RT_UOFFSETOF(VBOXSFWRITEPGLSTREQ, PgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     1137        pReq->PgLst.flags                   = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     1138        pReq->PgLst.offFirstPage            = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
     1139        pReq->PgLst.cPages                  = 1;
     1140        pReq->PgLst.aPages[0]               = PhysBuffer & ~(RTGCPHYS64)PAGE_OFFSET_MASK;
     1141    }
     1142    else
     1143    {
     1144        pReq->Parms.pBuf.type               = VMMDevHGCMParmType_LinAddr_In;
     1145        pReq->Parms.pBuf.u.LinAddr.cb       = cbToWrite;
     1146        pReq->Parms.pBuf.u.LinAddr.uAddr    = (uintptr_t)pvBuffer;
     1147    }
     1148
     1149    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, RT_UOFFSETOF_DYN(VBOXSFWRITEPGLSTREQ, PgLst.aPages[1]));
     1150    if (RT_SUCCESS(vrc))
     1151        vrc = pReq->Call.header.result;
     1152    return vrc;
     1153}
     1154
     1155
     1156/**
    9961157 * SHFL_FN_LIST request with separate string buffer and buffers for entries,
    9971158 * both allocated on the physical heap.
     
    10031164                                SHFL_FN_LIST, SHFL_CPARMS_LIST, sizeof(*pReq));
    10041165
    1005     pReq->Parms.id32Root.type                   = VMMDevHGCMParmType_32bit;
    1006     pReq->Parms.id32Root.u.value32              = pFolder->hHostFolder.root;
    1007 
    1008     pReq->Parms.u64Handle.type                  = VMMDevHGCMParmType_64bit;
    1009     pReq->Parms.u64Handle.u.value64             = hHostDir;
    1010 
    1011     pReq->Parms.f32Flags.type                   = VMMDevHGCMParmType_32bit;
    1012     pReq->Parms.f32Flags.u.value32              = fFlags;
    1013 
    1014     pReq->Parms.cb32Buffer.type                 = VMMDevHGCMParmType_32bit;
    1015     pReq->Parms.cb32Buffer.u.value32            = cbBuffer;
    1016 
    1017     pReq->Parms.pStrFilter.type                 = VMMDevHGCMParmType_ContiguousPageList;
    1018     pReq->Parms.pStrFilter.u.PageList.offset    = RT_UOFFSETOF(VBOXSFLISTDIRREQ, StrPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    1019     pReq->StrPgLst.flags                        = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
    1020     pReq->StrPgLst.cPages                       = 1;
    1021     if (pFilter)
    1022     {
    1023         pReq->Parms.pStrFilter.u.PageList.size  = SHFLSTRING_HEADER_SIZE + pFilter->u16Size;
    1024         RTGCPHYS32 const GCPhys       = VbglR0PhysHeapGetPhysAddr(pFilter);
     1166    pReq->Parms.id32Root.type                       = VMMDevHGCMParmType_32bit;
     1167    pReq->Parms.id32Root.u.value32                  = pFolder->hHostFolder.root;
     1168
     1169    pReq->Parms.u64Handle.type                      = VMMDevHGCMParmType_64bit;
     1170    pReq->Parms.u64Handle.u.value64                 = hHostDir;
     1171
     1172    pReq->Parms.f32Flags.type                       = VMMDevHGCMParmType_32bit;
     1173    pReq->Parms.f32Flags.u.value32                  = fFlags;
     1174
     1175    pReq->Parms.cb32Buffer.type                     = VMMDevHGCMParmType_32bit;
     1176    pReq->Parms.cb32Buffer.u.value32                = cbBuffer;
     1177
     1178    if (g_fHostFeatures & VMMDEV_HVF_HGCM_CONTIGUOUS_PAGE_LIST)
     1179    {
     1180        pReq->Parms.pStrFilter.type                 = VMMDevHGCMParmType_ContiguousPageList;
     1181        pReq->Parms.pStrFilter.u.PageList.offset    = RT_UOFFSETOF(VBOXSFLISTDIRREQ, StrPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     1182        pReq->StrPgLst.flags                        = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     1183        pReq->StrPgLst.cPages                       = 1;
     1184        if (pFilter)
     1185        {
     1186            pReq->Parms.pStrFilter.u.PageList.size  = SHFLSTRING_HEADER_SIZE + pFilter->u16Size;
     1187            RTGCPHYS32 const GCPhys       = VbglR0PhysHeapGetPhysAddr(pFilter);
     1188            uint32_t const   offFirstPage = GCPhys & PAGE_OFFSET_MASK;
     1189            pReq->StrPgLst.offFirstPage             = (uint16_t)offFirstPage;
     1190            pReq->StrPgLst.aPages[0]                = GCPhys - offFirstPage;
     1191        }
     1192        else
     1193        {
     1194            pReq->Parms.pStrFilter.u.PageList.size  = 0;
     1195            pReq->StrPgLst.offFirstPage             = 0;
     1196            pReq->StrPgLst.aPages[0]                = NIL_RTGCPHYS64;
     1197        }
     1198
     1199        pReq->Parms.pBuffer.type                    = VMMDevHGCMParmType_ContiguousPageList;
     1200        pReq->Parms.pBuffer.u.PageList.offset       = RT_UOFFSETOF(VBOXSFLISTDIRREQ, BufPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     1201        pReq->Parms.pBuffer.u.PageList.size         = cbBuffer;
     1202        pReq->BufPgLst.flags                        = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
     1203        pReq->BufPgLst.cPages                       = 1;
     1204        RTGCPHYS32 const GCPhys       = VbglR0PhysHeapGetPhysAddr(pBuffer);
    10251205        uint32_t const   offFirstPage = GCPhys & PAGE_OFFSET_MASK;
    1026         pReq->StrPgLst.offFirstPage             = (uint16_t)offFirstPage;
    1027         pReq->StrPgLst.aPages[0]                = GCPhys - offFirstPage;
    1028     }
    1029     else
    1030     {
    1031         pReq->Parms.pStrFilter.u.PageList.size  = 0;
    1032         pReq->StrPgLst.offFirstPage             = 0;
    1033         pReq->StrPgLst.aPages[0]                = NIL_RTGCPHYS64;
    1034     }
    1035 
    1036     pReq->Parms.pBuffer.type                    = VMMDevHGCMParmType_ContiguousPageList;
    1037     pReq->Parms.pBuffer.u.PageList.offset       = RT_UOFFSETOF(VBOXSFLISTDIRREQ, BufPgLst) - sizeof(VBGLIOCIDCHGCMFASTCALL);
    1038     pReq->Parms.pBuffer.u.PageList.size         = cbBuffer;
    1039     pReq->BufPgLst.flags                        = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
    1040     pReq->BufPgLst.cPages                       = 1;
    1041     RTGCPHYS32 const GCPhys       = VbglR0PhysHeapGetPhysAddr(pBuffer);
    1042     uint32_t const   offFirstPage = GCPhys & PAGE_OFFSET_MASK;
    1043     pReq->BufPgLst.offFirstPage                 = (uint16_t)offFirstPage;
    1044     pReq->BufPgLst.aPages[0]                    = GCPhys - offFirstPage;
    1045 
    1046     pReq->Parms.f32Done.type                    = VMMDevHGCMParmType_32bit;
    1047     pReq->Parms.f32Done.u.value32               = 0;
    1048 
    1049     pReq->Parms.c32Entries.type                 = VMMDevHGCMParmType_32bit;
    1050     pReq->Parms.c32Entries.u.value32            = 0;
     1206        pReq->BufPgLst.offFirstPage                 = (uint16_t)offFirstPage;
     1207        pReq->BufPgLst.aPages[0]                    = GCPhys - offFirstPage;
     1208    }
     1209    else
     1210    {
     1211        pReq->Parms.pStrFilter.type                 = VMMDevHGCMParmType_LinAddr_In;
     1212        pReq->Parms.pStrFilter.u.LinAddr.cb         = pFilter ? SHFLSTRING_HEADER_SIZE + pFilter->u16Size : 0;
     1213        pReq->Parms.pStrFilter.u.LinAddr.uAddr      = (uintptr_t)pFilter;
     1214
     1215        pReq->Parms.pBuffer.type                    = VMMDevHGCMParmType_LinAddr_Out;
     1216        pReq->Parms.pBuffer.u.LinAddr.cb            = cbBuffer;
     1217        pReq->Parms.pBuffer.u.LinAddr.uAddr         = (uintptr_t)pBuffer;
     1218    }
     1219
     1220    pReq->Parms.f32Done.type                        = VMMDevHGCMParmType_32bit;
     1221    pReq->Parms.f32Done.u.value32                   = 0;
     1222
     1223    pReq->Parms.c32Entries.type                     = VMMDevHGCMParmType_32bit;
     1224    pReq->Parms.c32Entries.u.value32                = 0;
    10511225
    10521226    int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq));
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette