VirtualBox

Ignore:
Timestamp:
Jan 22, 2008 3:32:45 PM (17 years ago)
Author:
vboxsync
Message:

Made VbglR3GR* private, split up the code a bit to make it more suitable for static linking.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGR.cpp

    r6445 r6447  
    1 /** $Id$ */
     1/* $Id$ */
    22/** @file
    3  * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions.
     3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, GR.
    44 */
    55
     
    2020*   Header Files                                                               *
    2121*******************************************************************************/
    22 #ifdef RT_OS_OS2
    23 # define INCL_BASE
    24 # define INCL_ERRORS
    25 # include <os2.h>
    26 #elif defined(RT_OS_SOLARIS)
    27 # include <sys/types.h>
    28 # include <sys/stat.h>
    29 # include <errno.h>
    30 # include <unistd.h>
    31 #endif
    32 
    33 #include <iprt/time.h>
    34 #include <iprt/asm.h>
     22#include <iprt/mem.h>
     23#include <iprt/assert.h>
    3524#include <iprt/string.h>
    36 #include <iprt/file.h>
    37 #include <iprt/assert.h>
    38 #include <iprt/mem.h>
    39 #include <iprt/alloca.h>
     25#include <iprt/err.h>
    4026#include <VBox/VBoxGuest.h>
     27#include "VBGLR3Internal.h"
    4128
    4229
    43 /*******************************************************************************
    44 *   Global Variables                                                           *
    45 *******************************************************************************/
    46 /** The VBoxGuest device handle. */
    47 static RTFILE g_File = NIL_RTFILE;
    48 
    49 
    50 VBGLR3DECL(int) VbglR3Init(void)
    51 {
    52     if (g_File != NIL_RTFILE)
    53         return VINF_SUCCESS;
    54 
    55 #if defined(RT_OS_OS2)
    56     /*
    57      * We might wish to compile this with Watcom, so stick to
    58      * the OS/2 APIs all the way. And in any case we have to use
    59      * DosDevIOCtl for the requests, why not use Dos* for everything.
    60      */
    61     HFILE hf = NULLHANDLE;
    62     ULONG ulAction = 0;
    63     APIRET rc = DosOpen((PCSZ)VBOXGUEST_DEVICE_NAME, &hf, &ulAction, 0, FILE_NORMAL,
    64                         OPEN_ACTION_OPEN_IF_EXISTS,
    65                         OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
    66                         NULL);
    67     if (rc)
    68         return RTErrConvertFromOS2(rc);
    69 
    70     if (hf < 16)
    71     {
    72         HFILE ahfs[16];
    73         unsigned i;
    74         for (i = 0; i < RT_ELEMENTS(ahfs); i++)
    75         {
    76             ahfs[i] = 0xffffffff;
    77             rc = DosDupHandle(hf, &ahfs[i]);
    78             if (rc)
    79                 break;
    80         }
    81 
    82         if (i-- > 1)
    83         {
    84             ULONG fulState = 0;
    85             rc = DosQueryFHState(ahfs[i], &fulState);
    86             if (!rc)
    87             {
    88                 fulState |= OPEN_FLAGS_NOINHERIT;
    89                 fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */
    90                 rc = DosSetFHState(ahfs[i], fulState);
    91             }
    92             if (!rc)
    93             {
    94                 rc = DosClose(hf);
    95                 AssertMsg(!rc, ("%ld\n", rc));
    96                 hf = ahfs[i];
    97             }
    98             else
    99                 i++;
    100             while (i-- > 0)
    101                 DosClose(ahfs[i]);
    102         }
    103     }
    104     g_File = hf;
    105 
    106      /* PORTME */
    107 #else
    108     /* the default implemenation. (linux, solaris) */
    109     RTFILE File;
    110     int rc = RTFileOpen(&File, VBOXGUEST_DEVICE_NAME, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    111     if (RT_FAILURE(rc))
    112         return rc;
    113     g_File = File;
    114 
    115 #endif
    116 
    117     return VINF_SUCCESS;
    118 }
    119 
    120 
    121 VBGLR3DECL(void) VbglR3Term(void)
    122 {
    123     RTFILE File = g_File;
    124     g_File = NIL_RTFILE;
    125     if (File == NIL_RTFILE)
    126         return;
    127 #if defined(RT_OS_OS2)
    128     APIRET rc = DosClose(File);
    129     AssertMsg(!rc, ("%ld\n", rc));
    130 #else
    131     int rc = RTFileClose(File);
    132     AssertRC(rc);
    133 #endif
    134 }
    135 
    136 
    137 /**
    138  * Internal wrapper around various OS specific ioctl implemenations.
    139  *
    140  * @returns VBox status code as returned by VBoxGuestCommonIOCtl, or
    141  *          an failure returned by the OS specific ioctl APIs.
    142  *
    143  * @param   iFunction   The requested function.
    144  * @param   pvData      The input and output data buffer.
    145  * @param   cbData      The size of the buffer.
    146  *
    147  * @remark  Exactly how the VBoxGuestCommonIOCtl is ferried back
    148  *          here is OS specific. On BSD and Darwin we can use errno,
    149  *          while on OS/2 we use the 2nd buffer of the IOCtl.
    150  */
    151 int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData)
    152 {
    153 #ifdef RT_OS_OS2
    154     ULONG cbOS2Parm = cbData;
    155     int32_t vrc = VERR_INTERNAL_ERROR;
    156     ULONG cbOS2Data = sizeof(vrc);
    157     APIRET rc = DosDevIOCtl(g_File, VBOXGUEST_IOCTL_CATEGORY, iFunction,
    158                             pvData, cbData, &cbOS2Parm,
    159                             &vrc, sizeof(vrc), &cbOS2Data);
    160     if (RT_LIKELY(!rc))
    161         return vrc;
    162     return RTErrConvertFromOS2(rc);
    163 
    164 #elif defined(RT_OS_SOLARIS)
    165     VBGLBIGREQ Hdr;
    166     Hdr.u32Magic = VBGLBIGREQ_MAGIC;
    167     Hdr.cbData = cbData;
    168     Hdr.pvDataR3 = pvData;
    169 
    170     int rc = ioctl((int)g_File, iFunction, &Hdr);
    171     if (rc == -1)
    172         rc = errno;
    173     return rc;
    174 
    175 #else
    176     /* Default implementation - PORTME: Do not use this without testings that error passing works! */
    177     int rc2 = VERR_INTERNAL_ERROR;
    178     int rc = RTFileIoCtl(g_File, (int)iFunction, pvData, cbData, &rc2);
    179     if (RT_SUCCESS(rc))
    180         rc = rc2;
    181     return rc;
    182 #endif
    183 }
    184 
    185 
    186 VBGLR3DECL(int) VbglR3GRAlloc(VMMDevRequestHeader **ppReq, uint32_t cb, VMMDevRequestType enmReqType)
     30int vbglR3GRAlloc(VMMDevRequestHeader **ppReq, uint32_t cb, VMMDevRequestType enmReqType)
    18731{
    18832    VMMDevRequestHeader *pReq;
     
    20953
    21054
    211 VBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq)
     55int vbglR3GRPerform(VMMDevRequestHeader *pReq)
    21256{
    21357    return vbglR3DoIOCtl(VBOXGUEST_IOCTL_VMMREQUEST(pReq->size), pReq, pReq->size);
     
    21559
    21660
    217 VBGLR3DECL(void) VbglR3GRFree(VMMDevRequestHeader *pReq)
     61void vbglR3GRFree(VMMDevRequestHeader *pReq)
    21862{
    21963    RTMemTmpFree(pReq);
    22064}
    22165
    222 
    223 VBGLR3DECL(int) VbglR3GetHostTime(PRTTIMESPEC pTime)
    224 {
    225     VMMDevReqHostTime Req;
    226     vmmdevInitRequest(&Req.header, VMMDevReq_GetHostTime);
    227     Req.time = UINT64_MAX;
    228     int rc = VbglR3GRPerform(&Req.header);
    229     if (RT_SUCCESS(rc))
    230         RTTimeSpecSetMilli(pTime, (int64_t)Req.time);
    231     return rc;
    232 }
    233 
    234 
    235 VBGLR3DECL(int) VbglR3GetMouseStatus(uint32_t *pfFeatures, uint32_t *px, uint32_t *py)
    236 {
    237     VMMDevReqMouseStatus Req;
    238     vmmdevInitRequest(&Req.header, VMMDevReq_GetMouseStatus);
    239     Req.mouseFeatures = 0;
    240     Req.pointerXPos = 0;
    241     Req.pointerYPos = 0;
    242     int rc = VbglR3GRPerform(&Req.header);
    243     if (RT_SUCCESS(rc))
    244     {
    245         if (pfFeatures)
    246             *pfFeatures = Req.mouseFeatures;
    247         if (px)
    248             *px = Req.pointerXPos;
    249         if (py)
    250             *py = Req.pointerYPos;
    251     }
    252     return rc;
    253 }
    254 
    255 
    256 VBGLR3DECL(int) VbglR3SetMouseStatus(uint32_t fFeatures)
    257 {
    258     VMMDevReqMouseStatus Req;
    259     vmmdevInitRequest(&Req.header, VMMDevReq_SetMouseStatus);
    260     Req.mouseFeatures = fFeatures;
    261     Req.pointerXPos = 0;
    262     Req.pointerYPos = 0;
    263     return VbglR3GRPerform(&Req.header);
    264 }
    265 
    266 
    267 /**
    268  * Cause any pending WaitEvent calls (VBOXGUEST_IOCTL_WAITEVENT) to return
    269  * with a VERR_INTERRUPTED status.
    270  *
    271  * Can be used in combination with a termination flag variable for interrupting
    272  * event loops. Avoiding race conditions is the responsibility of the caller.
    273  *
    274  * @returns IPRT status code
    275  */
    276 VBGLR3DECL(int) VbglR3InterruptEventWaits(void)
    277 {
    278     return vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT_INTERRUPT_ALL, 0, 0);
    279 }
    280 
    281 
    282 /**
    283  * Write to the backdoor logger from ring 3 guest code.
    284  *
    285  * @returns IPRT status code
    286  *
    287  * @remarks This currently does not accept more than 255 bytes of data at
    288  *          one time. It should probably be rewritten to use pass a pointer
    289  *          in the IOCtl.
    290  */
    291 VBGLR3DECL(int) VbglR3WriteLog(const char *pch, size_t cb)
    292 {
    293     /*
    294      * Solaris does not accept more than 255 bytes of data per ioctl request,
    295      * so split large string into 128 byte chunks to prevent truncation.
    296      */
    297 #define STEP 128 /** @todo increase to 512 when solaris ioctl code is fixed. (darwin limits us to 1024 IIRC) */
    298     int rc = VINF_SUCCESS;
    299     for (size_t off = 0; off < cb && RT_SUCCESS(rc); off += STEP)
    300     {
    301         size_t cbStep = RT_MIN(cb - off, STEP);
    302         rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cbStep), (char *)pch + off, cbStep);
    303     }
    304 #undef STEP
    305     return rc;
    306 }
    307 
    308 
    309 /**
    310  * Change the IRQ filter mask.
    311  *
    312  * @returns IPRT status code
    313  * @param   fOr     The OR mask.
    314  * @param   fNo     The NOT mask.
    315  */
    316 VBGLR3DECL(int) VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot)
    317 {
    318     VBoxGuestFilterMaskInfo Info;
    319     Info.u32OrMask = fOr;
    320     Info.u32NotMask = fNot;
    321     return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CTL_FILTER_MASK, &Info, sizeof(Info));
    322 }
    323 
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