Changeset 6447 in vbox for trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGR.cpp
- Timestamp:
- Jan 22, 2008 3:32:45 PM (17 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGR.cpp
r6445 r6447 1 /* *$Id$ */1 /* $Id$ */ 2 2 /** @file 3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions .3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, GR. 4 4 */ 5 5 … … 20 20 * Header Files * 21 21 *******************************************************************************/ 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> 35 24 #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> 40 26 #include <VBox/VBoxGuest.h> 27 #include "VBGLR3Internal.h" 41 28 42 29 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) 30 int vbglR3GRAlloc(VMMDevRequestHeader **ppReq, uint32_t cb, VMMDevRequestType enmReqType) 187 31 { 188 32 VMMDevRequestHeader *pReq; … … 209 53 210 54 211 VBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq)55 int vbglR3GRPerform(VMMDevRequestHeader *pReq) 212 56 { 213 57 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_VMMREQUEST(pReq->size), pReq, pReq->size); … … 215 59 216 60 217 VBGLR3DECL(void) VbglR3GRFree(VMMDevRequestHeader *pReq)61 void vbglR3GRFree(VMMDevRequestHeader *pReq) 218 62 { 219 63 RTMemTmpFree(pReq); 220 64 } 221 65 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 return269 * with a VERR_INTERRUPTED status.270 *271 * Can be used in combination with a termination flag variable for interrupting272 * event loops. Avoiding race conditions is the responsibility of the caller.273 *274 * @returns IPRT status code275 */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 code286 *287 * @remarks This currently does not accept more than 255 bytes of data at288 * one time. It should probably be rewritten to use pass a pointer289 * 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 STEP305 return rc;306 }307 308 309 /**310 * Change the IRQ filter mask.311 *312 * @returns IPRT status code313 * @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.