VirtualBox

Changeset 75737 in vbox for trunk/include


Ignore:
Timestamp:
Nov 26, 2018 3:44:41 PM (6 years ago)
Author:
vboxsync
Message:

HGCM: Replace C++-style inline members on VBOXHGCMSVCPARM with simple functions.
bugref:9172: Shared folder performance tuning
Changes in bugref:9172 caused a build regression on Ubuntu 18.10 due to the
use of RT_ZERO on a structure containing an embedded VBOXHGCMSVCPARM, as
VBOXHGCMSVCPARM had member functions and was therefore not a simple plain-
old-data structure. Rather than just doing the sensible thing and zeroing
it in a different way, I converted the inline member getters and setters to
standard inline C functions, including fixing callers. Actually I had planned
this for some time, as the member function use seemed a bit gratuitous in
hindsight.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/hgcmsvc.h

    r75501 r75737  
    190190        } pointer;
    191191    } u;
     192} VBOXHGCMSVCPARM;
     193
     194/** Extract an uint32_t value from an HGCM parameter structure. */
     195static inline int HGCMSvcGetU32(struct VBOXHGCMSVCPARM *pParm, uint32_t *pu32)
     196{
     197    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     198    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     199    AssertPtrReturn(pu32, VERR_INVALID_POINTER);
     200    int rc = VINF_SUCCESS;
     201    if (pParm->type != VBOX_HGCM_SVC_PARM_32BIT)
     202        rc = VERR_INVALID_PARAMETER;
     203    if (RT_SUCCESS(rc))
     204        *pu32 = pParm->u.uint32;
     205    return rc;
     206}
     207
     208/** Extract an uint64_t value from an HGCM parameter structure. */
     209static inline int HGCMSvcGetU64(struct VBOXHGCMSVCPARM *pParm, uint64_t *pu64)
     210{
     211    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     212    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     213    AssertPtrReturn(pu64, VERR_INVALID_POINTER);
     214    int rc = VINF_SUCCESS;
     215    if (pParm->type != VBOX_HGCM_SVC_PARM_64BIT)
     216        rc = VERR_INVALID_PARAMETER;
     217    if (RT_SUCCESS(rc))
     218        *pu64 = pParm->u.uint64;
     219    return rc;
     220}
     221
     222/** Extract an pointer value from an HGCM parameter structure. */
     223static inline int HGCMSvcGetPv(struct VBOXHGCMSVCPARM *pParm, void **ppv,
     224                               uint32_t *pcb)
     225{
     226    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     227    AssertPtrReturn(ppv, VERR_INVALID_POINTER);
     228    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
     229    if (pParm->type == VBOX_HGCM_SVC_PARM_PTR)
     230    {
     231        *ppv = pParm->u.pointer.addr;
     232        *pcb = pParm->u.pointer.size;
     233        return VINF_SUCCESS;
     234    }
     235
     236    return VERR_INVALID_PARAMETER;
     237}
     238
     239/** Extract a constant pointer value from an HGCM parameter structure. */
     240static inline int HGCMSvcGetPcv(struct VBOXHGCMSVCPARM *pParm, const void **ppv,
     241                                uint32_t *pcb)
     242{
     243    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     244    AssertPtrReturn(ppv, VERR_INVALID_POINTER);
     245    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
     246    if (pParm->type == VBOX_HGCM_SVC_PARM_PTR)
     247    {
     248        *ppv = (const void *)pParm->u.pointer.addr;
     249        *pcb = pParm->u.pointer.size;
     250        return VINF_SUCCESS;
     251    }
     252
     253    return VERR_INVALID_PARAMETER;
     254}
     255
     256/** Extract a valid pointer to a non-empty buffer from an HGCM parameter
     257 * structure. */
     258static inline int HGCMSvcGetBuf(struct VBOXHGCMSVCPARM *pParm, void **ppv,
     259                                uint32_t *pcb)
     260{
     261    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     262    AssertPtrReturn(ppv, VERR_INVALID_POINTER);
     263    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
     264    if (   pParm->type == VBOX_HGCM_SVC_PARM_PTR
     265        && VALID_PTR(pParm->u.pointer.addr)
     266        && pParm->u.pointer.size > 0)
     267    {
     268        *ppv = pParm->u.pointer.addr;
     269        *pcb = pParm->u.pointer.size;
     270        return VINF_SUCCESS;
     271    }
     272
     273    return VERR_INVALID_PARAMETER;
     274}
     275
     276/** Extract a valid pointer to a non-empty constant buffer from an HGCM
     277 * parameter structure. */
     278static inline int HGCMSvcGetCBuf(struct VBOXHGCMSVCPARM *pParm,
     279                                 const void **ppv, uint32_t *pcb)
     280{
     281    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     282    AssertPtrReturn(ppv, VERR_INVALID_POINTER);
     283    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
     284    if (   pParm->type == VBOX_HGCM_SVC_PARM_PTR
     285        && VALID_PTR(pParm->u.pointer.addr)
     286        && pParm->u.pointer.size > 0)
     287    {
     288        *ppv = (const void *)pParm->u.pointer.addr;
     289        *pcb = pParm->u.pointer.size;
     290        return VINF_SUCCESS;
     291    }
     292
     293    return VERR_INVALID_PARAMETER;
     294}
     295
     296/** Extract a string value from an HGCM parameter structure. */
     297static inline int HGCMSvcGetStr(struct VBOXHGCMSVCPARM *pParm, char **ppch,
     298                                uint32_t *pcb)
     299{
     300    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     301    AssertPtrReturn(ppch, VERR_INVALID_POINTER);
     302    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
     303    if (   pParm->type == VBOX_HGCM_SVC_PARM_PTR
     304        && VALID_PTR(pParm->u.pointer.addr)
     305        && pParm->u.pointer.size > 0)
     306    {
     307        int rc = RTStrValidateEncodingEx((char *)pParm->u.pointer.addr,
     308                                         pParm->u.pointer.size,
     309                                         RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
     310        if (RT_FAILURE(rc))
     311            return rc;
     312        *ppch = (char *)pParm->u.pointer.addr;
     313        *pcb = pParm->u.pointer.size;
     314        return VINF_SUCCESS;
     315    }
     316
     317    return VERR_INVALID_PARAMETER;
     318}
     319
     320/** Extract a constant string value from an HGCM parameter structure. */
     321static inline int HGCMSvcGetCStr(struct VBOXHGCMSVCPARM *pParm,
     322                                 const char **ppch, uint32_t *pcb)
     323{
     324    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     325    AssertPtrReturn(ppch, VERR_INVALID_POINTER);
     326    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
     327    if (   pParm->type == VBOX_HGCM_SVC_PARM_PTR
     328        && VALID_PTR(pParm->u.pointer.addr)
     329        && pParm->u.pointer.size > 0)
     330    {
     331        int rc = RTStrValidateEncodingEx((char *)pParm->u.pointer.addr,
     332                                         pParm->u.pointer.size,
     333                                         RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
     334        if (RT_FAILURE(rc))
     335            return rc;
     336        *ppch = (char *)pParm->u.pointer.addr;
     337        *pcb = pParm->u.pointer.size;
     338        return VINF_SUCCESS;
     339    }
     340
     341    return VERR_INVALID_PARAMETER;
     342}
     343
     344/** Extract a constant string value from an HGCM parameter structure. */
     345static inline int HGCMSvcGetPsz(struct VBOXHGCMSVCPARM *pParm, const char **ppch,
     346                                uint32_t *pcb)
     347{
     348    AssertPtrReturn(pParm, VERR_INVALID_POINTER);
     349    AssertPtrReturn(ppch, VERR_INVALID_POINTER);
     350    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
     351    if (   pParm->type == VBOX_HGCM_SVC_PARM_PTR
     352        && VALID_PTR(pParm->u.pointer.addr)
     353        && pParm->u.pointer.size > 0)
     354    {
     355        int rc = RTStrValidateEncodingEx((const char *)pParm->u.pointer.addr,
     356                                         pParm->u.pointer.size,
     357                                         RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
     358        if (RT_FAILURE(rc))
     359            return rc;
     360        *ppch = (const char *)pParm->u.pointer.addr;
     361        *pcb = pParm->u.pointer.size;
     362        return VINF_SUCCESS;
     363    }
     364
     365    return VERR_INVALID_PARAMETER;
     366}
     367
     368/** Set a uint32_t value to an HGCM parameter structure */
     369static inline void HGCMSvcSetU32(struct VBOXHGCMSVCPARM *pParm, uint32_t u32)
     370{
     371    AssertPtr(pParm);
     372    pParm->type = VBOX_HGCM_SVC_PARM_32BIT;
     373    pParm->u.uint32 = u32;
     374}
     375
     376/** Set a uint64_t value to an HGCM parameter structure */
     377static inline void HGCMSvcSetU64(struct VBOXHGCMSVCPARM *pParm, uint64_t u64)
     378{
     379    AssertPtr(pParm);
     380    pParm->type = VBOX_HGCM_SVC_PARM_64BIT;
     381    pParm->u.uint64 = u64;
     382}
     383
     384/** Set a pointer value to an HGCM parameter structure */
     385static inline void HGCMSvcSetPv(struct VBOXHGCMSVCPARM *pParm, void *pv,
     386                                uint32_t cb)
     387{
     388    AssertPtr(pParm);
     389    pParm->u.pointer.addr = pv;
     390    pParm->u.pointer.size = cb;
     391}
     392
     393/** Set a pointer value to an HGCM parameter structure */
     394static inline void HGCMSvcSetStr(struct VBOXHGCMSVCPARM *pParm, const char *psz)
     395{
     396    AssertPtr(pParm);
     397    pParm->u.pointer.addr = (void *)psz;
     398    pParm->u.pointer.size = (uint32_t)strlen(psz) + 1;
     399}
     400
    192401#ifdef __cplusplus
    193     /** Extract an uint32_t value from an HGCM parameter structure */
    194     int getUInt32(uint32_t *u32)
    195     {
    196         AssertPtrReturn(u32, VERR_INVALID_POINTER);
    197         int rc = VINF_SUCCESS;
    198         if (type != VBOX_HGCM_SVC_PARM_32BIT)
    199             rc = VERR_INVALID_PARAMETER;
    200         if (RT_SUCCESS(rc))
    201             *u32 = u.uint32;
    202         return rc;
    203     }
    204 
    205     /** Extract a uint64_t value from an HGCM parameter structure */
    206     int getUInt64(uint64_t *u64)
    207     {
    208         AssertPtrReturn(u64, VERR_INVALID_POINTER);
    209         int rc = VINF_SUCCESS;
    210         if (type != VBOX_HGCM_SVC_PARM_64BIT)
    211             rc = VERR_INVALID_PARAMETER;
    212         if (RT_SUCCESS(rc))
    213             *u64 = u.uint64;
    214         return rc;
    215     }
    216 
    217     /** Extract a pointer value from an HGCM parameter structure */
    218     int getPointer(void **ppv, uint32_t *pcb)
    219     {
    220         AssertPtrReturn(ppv, VERR_INVALID_POINTER);
    221         AssertPtrReturn(pcb, VERR_INVALID_POINTER);
    222         if (type == VBOX_HGCM_SVC_PARM_PTR)
    223         {
    224             *ppv = u.pointer.addr;
    225             *pcb = u.pointer.size;
    226             return VINF_SUCCESS;
    227         }
    228 
    229         return VERR_INVALID_PARAMETER;
    230     }
    231 
    232     /** Extract a constant pointer value from an HGCM parameter structure */
    233     int getPointer(const void **ppcv, uint32_t *pcb)
    234     {
    235         AssertPtrReturn(ppcv, VERR_INVALID_POINTER);
    236         AssertPtrReturn(pcb, VERR_INVALID_POINTER);
    237         void *pv;
    238         int rc = getPointer(&pv, pcb);
    239         *ppcv = pv;
    240         return rc;
    241     }
    242 
    243     /** Extract a pointer value to a non-empty buffer from an HGCM parameter
    244      * structure */
    245     int getBuffer(void **ppv, uint32_t *pcb)
    246     {
    247         AssertPtrReturn(ppv, VERR_INVALID_POINTER);
    248         AssertPtrReturn(pcb, VERR_INVALID_POINTER);
    249         void *pv = NULL;
    250         uint32_t cb = 0;
    251         int rc = getPointer(&pv, &cb);
    252         if (   RT_SUCCESS(rc)
    253             && VALID_PTR(pv)
    254             && cb > 0)
    255         {
    256             *ppv = pv;
    257             *pcb = cb;
    258             return VINF_SUCCESS;
    259         }
    260 
    261         return VERR_INVALID_PARAMETER;
    262     }
    263 
    264     /** Extract a pointer value to a non-empty constant buffer from an HGCM
    265      * parameter structure */
    266     int getBuffer(const void **ppcv, uint32_t *pcb)
    267     {
    268         AssertPtrReturn(ppcv, VERR_INVALID_POINTER);
    269         AssertPtrReturn(pcb, VERR_INVALID_POINTER);
    270         void *pcv = NULL;
    271         int rc = getBuffer(&pcv, pcb);
    272         *ppcv = pcv;
    273         return rc;
    274     }
    275 
    276     /** Extract a string value from an HGCM parameter structure */
    277     int getString(char **ppch, uint32_t *pcb)
    278     {
    279         uint32_t cb = 0;
    280         char *pch = NULL;
    281         int rc = getBuffer((void **)&pch, &cb);
    282         if (RT_FAILURE(rc))
    283         {
    284             *ppch = NULL;
    285             *pcb = 0;
    286             return rc;
    287         }
    288         rc = RTStrValidateEncodingEx(pch, cb,
    289                                      RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
    290         *ppch = pch;
    291         *pcb = cb;
    292         return rc;
    293     }
    294 
    295     /** Extract a constant string value from an HGCM parameter structure */
    296     int getString(const char **ppch, uint32_t *pcb)
    297     {
    298         char *pch = NULL;
    299         int rc = getString(&pch, pcb);
    300         *ppch = pch;
    301         return rc;
    302     }
    303 
    304     /** Set a uint32_t value to an HGCM parameter structure */
    305     void setUInt32(uint32_t u32)
    306     {
    307         type = VBOX_HGCM_SVC_PARM_32BIT;
    308         u.uint32 = u32;
    309     }
    310 
    311     /** Set a uint64_t value to an HGCM parameter structure */
    312     void setUInt64(uint64_t u64)
    313     {
    314         type = VBOX_HGCM_SVC_PARM_64BIT;
    315         u.uint64 = u64;
    316     }
    317 
    318     /** Set a pointer value to an HGCM parameter structure */
    319     void setPointer(void *pv, uint32_t cb)
    320     {
    321         type = VBOX_HGCM_SVC_PARM_PTR;
    322         u.pointer.addr = pv;
    323         u.pointer.size = cb;
    324     }
    325 
    326     /** Set a const string value to an HGCM parameter structure */
    327     void setString(const char *psz)
    328     {
    329         type = VBOX_HGCM_SVC_PARM_PTR;
    330         u.pointer.addr = (void *)psz;
    331         u.pointer.size = (uint32_t)strlen(psz) + 1;
    332     }
    333 
    334 #ifdef ___iprt_cpp_ministring_h
    335     /** Set a const string value to an HGCM parameter structure */
    336     void setCppString(const RTCString &rString)
    337     {
    338         type = VBOX_HGCM_SVC_PARM_PTR;
    339         u.pointer.addr = (void *)rString.c_str();
    340         u.pointer.size = (uint32_t)rString.length() + 1;
    341     }
     402# ifdef ___iprt_cpp_ministring_h
     403/** Set a const string value to an HGCM parameter structure */
     404static inline void HGCMSvcSetRTCStr(struct VBOXHGCMSVCPARM *pParm,
     405                                    const RTCString &rString)
     406{
     407    AssertPtr(pParm);
     408    pParm->type = VBOX_HGCM_SVC_PARM_PTR;
     409    pParm->u.pointer.addr = (void *)rString.c_str();
     410    pParm->u.pointer.size = (uint32_t)rString.length() + 1;
     411}
     412# endif
    342413#endif
    343 
    344 #ifdef VBOX_TEST_HGCM_PARMS
    345     /** Test the getString member function.  Indirectly tests the getPointer
    346      * and getBuffer APIs.
    347      * @param  hTest  an running IPRT test
    348      * @param  aType  the type that the parameter should be set to before
    349      *                calling getString
    350      * @param  apcc   the value that the parameter should be set to before
    351      *                calling getString, and also the address (!) which we
    352      *                expect getString to return.  Stricter than needed of
    353      *                course, but I was feeling lazy.
    354      * @param  acb    the size that the parameter should be set to before
    355      *                calling getString, and also the size which we expect
    356      *                getString to return.
    357      * @param  rcExp  the expected return value of the call to getString.
    358      */
    359     void doTestGetString(RTTEST hTest, uint32_t aType, const char *apcc,
    360                          uint32_t acb, int rcExp)
    361     {
    362         /* An RTTest API like this, which would print out an additional line
    363          * of context if a test failed, would be nice.  This is because the
    364          * line number alone doesn't help much here, given that this is a
    365          * subroutine called many times. */
    366         /*
    367         RTTestContextF(hTest,
    368                        ("doTestGetString, aType=%u, apcc=%p, acp=%u, rcExp=%Rrc",
    369                         aType, apcc, acp, rcExp));
    370          */
    371         setPointer((void *)apcc, acb);
    372         type = aType;  /* in case we don't want VBOX_HGCM_SVC_PARM_PTR */
    373         const char *pcc = NULL;
    374         uint32_t cb = 0;
    375         int rc = getString(&pcc, &cb);
    376         RTTEST_CHECK_RC(hTest, rc, rcExp);
    377         if (RT_SUCCESS(rcExp))
    378         {
    379             RTTEST_CHECK_MSG_RETV(hTest, (pcc == apcc),
    380                                   (hTest, "expected %p, got %p", apcc, pcc));
    381             RTTEST_CHECK_MSG_RETV(hTest, (cb == acb),
    382                                   (hTest, "expected %u, got %u", acb, cb));
    383         }
    384     }
    385 
    386     /** Run some unit tests on the getString method and indirectly test
    387      * getPointer and getBuffer as well. */
    388     void testGetString(RTTEST hTest)
    389     {
    390         RTTestSub(hTest, "HGCM string parameter handling");
    391         doTestGetString(hTest, VBOX_HGCM_SVC_PARM_32BIT, "test", 3,
    392                         VERR_INVALID_PARAMETER);
    393         doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 5,
    394                         VINF_SUCCESS);
    395         doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 3,
    396                         VERR_BUFFER_OVERFLOW);
    397         doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test\xf0", 6,
    398                         VERR_INVALID_UTF8_ENCODING);
    399         doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 0,
    400                         VERR_INVALID_PARAMETER);
    401         doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, (const char *)0x1, 5,
    402                         VERR_INVALID_PARAMETER);
    403         RTTestSubDone(hTest);
    404     }
    405 #endif
    406 
    407     VBOXHGCMSVCPARM() : type(VBOX_HGCM_SVC_PARM_INVALID) {}
    408 #endif
    409 } VBOXHGCMSVCPARM;
    410414
    411415typedef VBOXHGCMSVCPARM *PVBOXHGCMSVCPARM;
Note: See TracChangeset for help on using the changeset viewer.

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