Changeset 6447 in vbox
- Timestamp:
- Jan 22, 2008 3:32:45 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 27422
- Location:
- trunk
- Files:
-
- 4 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxGuest.h
r6445 r6447 1388 1388 VBGLR3DECL(int) VbglR3Init(void); 1389 1389 VBGLR3DECL(void) VbglR3Term(void); 1390 VBGLR3DECL(int) VbglR3GRAlloc(VMMDevRequestHeader **ppReq, uint32_t cbSize,1391 VMMDevRequestType reqType);1392 VBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq);1393 VBGLR3DECL(void) VbglR3GRFree(VMMDevRequestHeader *pReq);1394 1390 # ifdef ___iprt_time_h 1395 1391 VBGLR3DECL(int) VbglR3GetHostTime(PRTTIMESPEC pTime); -
trunk/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
r6445 r6447 98 98 VBoxGuestR3Lib_SOURCES = \ 99 99 VBoxGuestR3Lib.cpp \ 100 VBoxGuestR3LibClipboard.cpp \ 100 101 VBoxGuestR3LibDaemonize.cpp \ 101 VBoxGuestR3LibClipboard.cpp 102 VBoxGuestR3LibGR.cpp \ 103 VBoxGuestR3LibMouse.cpp \ 104 VBoxGuestR3LibMisc.cpp \ 105 VBoxGuestR3LibTime.cpp \ 102 106 103 107 … … 151 155 # 152 156 VBoxGuestR3LibLinux_TEMPLATE = VBOXLNX32GUESTR3LIB 153 VBoxGuestR3LibLinux_SOURCES = \ 154 VBoxGuestR3Lib.cpp \ 155 VBoxGuestR3LibDaemonize.cpp \ 156 VBoxGuestR3LibClipboard.cpp \ 157 VBoxGuestR3LibSeamless.cpp 157 VBoxGuestR3LibLinux_SOURCES = $(VBoxGuestR3Lib_SOURCES) 158 158 VBoxGuestR3LibLinux_DEFS = VBOX_HGCM 159 159 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h
r6398 r6447 1 /* $Id$ */ 1 2 /** @file 2 * 3 * VBoxGuestLib - A support library for VirtualBox guest additions: 4 * Internal header 3 * VBoxGuestR3Lib - Ring-3 support library for the guest additions, Internal header. 5 4 */ 6 5 … … 17 16 */ 18 17 19 #ifndef __ VBGLINTERNAL__H20 #define __ VBGLINTERNAL__H18 #ifndef ___VBGLR3Internal_h 19 #define ___VBGLR3Internal_h 21 20 22 /* I have added this include here as 23 a) This file is always included before VBGLInternal and 24 b) It contains a definition for VBGLHGCMHANDLE, so we definitely do not 25 need to redefine that here. The C (without ++) compiler was complaining 26 that it was defined twice. 27 */ 28 #include <VBox/VBoxGuestLib.h> 21 #include <VBox/VBoxGuest.h> 29 22 30 #if (defined(DEBUG) && !defined(NO_LOGGING)) || defined(LOG_ENABLED) 31 #include <VBox/log.h> 32 # define dprintf(a) RTLogBackdoorPrintf a 33 #else 34 # define dprintf(a) do {} while (0) 23 __BEGIN_DECLS 24 25 int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData); 26 int vbglR3GRAlloc(VMMDevRequestHeader **ppReq, uint32_t cb, VMMDevRequestType enmReqType); 27 int vbglR3GRPerform(VMMDevRequestHeader *pReq); 28 void vbglR3GRFree(VMMDevRequestHeader *pReq); 29 30 31 32 DECLINLINE(void) VbglHGCMParmUInt32Set(HGCMFunctionParameter *pParm, uint32_t u32) 33 { 34 pParm->type = VMMDevHGCMParmType_32bit; 35 pParm->u.value32 = u32; 36 } 37 38 39 DECLINLINE(int) VbglHGCMParmUInt32Get(HGCMFunctionParameter *pParm, uint32_t *pu32) 40 { 41 if (pParm->type == VMMDevHGCMParmType_32bit) 42 { 43 *pu32 = pParm->u.value32; 44 return VINF_SUCCESS; 45 } 46 return VERR_INVALID_PARAMETER; 47 } 48 49 50 DECLINLINE(void) VbglHGCMParmPtrSet(HGCMFunctionParameter *pParm, void *pv, uint32_t cb) 51 { 52 pParm->type = VMMDevHGCMParmType_LinAddr; 53 pParm->u.Pointer.size = cb; 54 pParm->u.Pointer.u.linearAddr = (vmmDevHypPtr)pv; 55 } 56 57 __END_DECLS 58 35 59 #endif 36 37 #include "SysHlp.h"38 39 #pragma pack(4)40 41 struct _VBGLPHYSHEAPBLOCK;42 typedef struct _VBGLPHYSHEAPBLOCK VBGLPHYSHEAPBLOCK;43 struct _VBGLPHYSHEAPCHUNK;44 typedef struct _VBGLPHYSHEAPCHUNK VBGLPHYSHEAPCHUNK;45 46 #ifndef VBGL_VBOXGUEST47 struct VBGLHGCMHANDLEDATA48 {49 uint32_t fAllocated;50 VBGLDRIVER driver;51 };52 #endif53 54 enum VbglLibStatus55 {56 VbglStatusNotInitialized = 0,57 VbglStatusInitializing,58 VbglStatusReady59 };60 61 typedef struct _VBGLDATA62 {63 enum VbglLibStatus status;64 65 VBGLIOPORT portVMMDev;66 67 VMMDevMemory *pVMMDevMemory;68 69 /**70 * Physical memory heap data.71 * @{72 */73 74 VBGLPHYSHEAPBLOCK *pFreeBlocksHead;75 VBGLPHYSHEAPBLOCK *pAllocBlocksHead;76 VBGLPHYSHEAPCHUNK *pChunkHead;77 78 RTSEMFASTMUTEX mutexHeap;79 /** @} */80 81 #ifndef VBGL_VBOXGUEST82 /**83 * Fast heap for HGCM handles data.84 * @{85 */86 87 RTSEMFASTMUTEX mutexHGCMHandle;88 89 struct VBGLHGCMHANDLEDATA aHGCMHandleData[64];90 91 /** @} */92 #endif93 } VBGLDATA;94 95 #pragma pack()96 97 #ifndef VBGL_DECL_DATA98 extern VBGLDATA g_vbgldata;99 #endif100 101 /* Check if library has been initialized before entering102 * a public library function.103 */104 int VbglEnter (void);105 106 #ifdef VBOX_HGCM107 #ifndef VBGL_VBOXGUEST108 /* Initialize HGCM subsystem. */109 int vbglHGCMInit (void);110 /* Terminate HGCM subsystem. */111 int vbglHGCMTerminate (void);112 #endif113 #endif114 115 #endif /* __VBGLINTERNAL__H */ -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.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, Core. 4 4 */ 5 5 … … 39 39 #include <iprt/alloca.h> 40 40 #include <VBox/VBoxGuest.h> 41 #include "VBGLR3Internal.h" 41 42 42 43 … … 183 184 } 184 185 185 186 VBGLR3DECL(int) VbglR3GRAlloc(VMMDevRequestHeader **ppReq, uint32_t cb, VMMDevRequestType enmReqType)187 {188 VMMDevRequestHeader *pReq;189 190 AssertPtrReturn(ppReq, VERR_INVALID_PARAMETER);191 AssertMsgReturn(cb >= sizeof(VMMDevRequestHeader), ("%#x vs %#zx\n", cb, sizeof(VMMDevRequestHeader)),192 VERR_INVALID_PARAMETER);193 194 pReq = (VMMDevRequestHeader *)RTMemTmpAlloc(cb);195 if (RT_UNLIKELY(!pReq))196 return VERR_NO_MEMORY;197 198 pReq->size = cb;199 pReq->version = VMMDEV_REQUEST_HEADER_VERSION;200 pReq->requestType = enmReqType;201 pReq->rc = VERR_GENERAL_FAILURE;202 pReq->reserved1 = 0;203 pReq->reserved2 = 0;204 205 *ppReq = pReq;206 207 return VINF_SUCCESS;208 }209 210 211 VBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq)212 {213 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_VMMREQUEST(pReq->size), pReq, pReq->size);214 }215 216 217 VBGLR3DECL(void) VbglR3GRFree(VMMDevRequestHeader *pReq)218 {219 RTMemTmpFree(pReq);220 }221 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 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibClipboard.cpp
r6000 r6447 1 /* *$Id$ */1 /* $Id$ */ 2 2 /** @file 3 3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Clipboard. … … 24 24 #include <iprt/string.h> 25 25 #include <iprt/assert.h> 26 27 28 /* Move this to a header { */ 29 30 extern int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData); 31 32 33 DECLINLINE(void) VbglHGCMParmUInt32Set(HGCMFunctionParameter *pParm, uint32_t u32) 34 { 35 pParm->type = VMMDevHGCMParmType_32bit; 36 pParm->u.value32 = u32; 37 } 38 39 40 DECLINLINE(int) VbglHGCMParmUInt32Get(HGCMFunctionParameter *pParm, uint32_t *pu32) 41 { 42 if (pParm->type == VMMDevHGCMParmType_32bit) 43 { 44 *pu32 = pParm->u.value32; 45 return VINF_SUCCESS; 46 } 47 return VERR_INVALID_PARAMETER; 48 } 49 50 51 DECLINLINE(void) VbglHGCMParmPtrSet(HGCMFunctionParameter *pParm, void *pv, uint32_t cb) 52 { 53 pParm->type = VMMDevHGCMParmType_LinAddr; 54 pParm->u.Pointer.size = cb; 55 pParm->u.Pointer.u.linearAddr = (vmmDevHypPtr)pv; 56 } 57 58 /* } */ 26 #include "VBGLR3Internal.h" 27 59 28 60 29 … … 62 31 /** 63 32 * Connects to the clipboard service. 64 * 33 * 65 34 * @returns VBox status code 66 35 * @param pu32ClientId Where to put the client id on success. The client id … … 88 57 /** 89 58 * Disconnect from the clipboard service. 90 * 59 * 91 60 * @returns VBox status code. 92 61 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). … … 107 76 /** 108 77 * Get a host message. 109 * 78 * 110 79 * This will block until a message becomes available. 111 * 80 * 112 81 * @returns VBox status code. 113 82 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). … … 154 123 /** 155 124 * Reads data from the host clipboard. 156 * 125 * 157 126 * @returns VBox status code. 158 127 * @retval VINF_BUFFER_OVERFLOW If there is more data available than the caller provided buffer space for. 159 * 128 * 160 129 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). 161 130 * @param fFormat The format we're requesting the data in. 162 131 * @param pv Where to store the data. 163 132 * @param cb The size of the buffer pointed to by pv. 164 * @param pcb The actual size of the host clipboard data. May be larger than cb. 133 * @param pcb The actual size of the host clipboard data. May be larger than cb. 165 134 */ 166 135 VBGLR3DECL(int) VbglR3ClipboardReadData(uint32_t u32ClientId, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcb) … … 199 168 /** 200 169 * Advertises guest clipboard formats to the host. 201 * 170 * 202 171 * @returns VBox status code. 203 172 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). … … 223 192 /** 224 193 * Send guest clipboard data to the host. 225 * 226 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message 194 * 195 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message 227 196 * from the host. 228 * 197 * 229 198 * @returns VBox status code. 230 199 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). -
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 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.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, Misc. 4 4 */ 5 5 … … 20 20 * Header Files * 21 21 *******************************************************************************/ 22 #ifdef RT_OS_OS223 # define INCL_BASE24 # define INCL_ERRORS25 # 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 #endif32 33 #include <iprt/time.h>34 #include <iprt/asm.h>35 #include <iprt/string.h>36 #include <iprt/file.h>37 22 #include <iprt/assert.h> 38 #include <iprt/mem.h> 39 #include <iprt/alloca.h> 40 #include <VBox/VBoxGuest.h> 41 42 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) 187 { 188 VMMDevRequestHeader *pReq; 189 190 AssertPtrReturn(ppReq, VERR_INVALID_PARAMETER); 191 AssertMsgReturn(cb >= sizeof(VMMDevRequestHeader), ("%#x vs %#zx\n", cb, sizeof(VMMDevRequestHeader)), 192 VERR_INVALID_PARAMETER); 193 194 pReq = (VMMDevRequestHeader *)RTMemTmpAlloc(cb); 195 if (RT_UNLIKELY(!pReq)) 196 return VERR_NO_MEMORY; 197 198 pReq->size = cb; 199 pReq->version = VMMDEV_REQUEST_HEADER_VERSION; 200 pReq->requestType = enmReqType; 201 pReq->rc = VERR_GENERAL_FAILURE; 202 pReq->reserved1 = 0; 203 pReq->reserved2 = 0; 204 205 *ppReq = pReq; 206 207 return VINF_SUCCESS; 208 } 209 210 211 VBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq) 212 { 213 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_VMMREQUEST(pReq->size), pReq, pReq->size); 214 } 215 216 217 VBGLR3DECL(void) VbglR3GRFree(VMMDevRequestHeader *pReq) 218 { 219 RTMemTmpFree(pReq); 220 } 221 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 } 23 #include "VBGLR3Internal.h" 265 24 266 25 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMouse.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, Mouse. 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> 35 #include <iprt/string.h> 36 #include <iprt/file.h> 37 #include <iprt/assert.h> 38 #include <iprt/mem.h> 39 #include <iprt/alloca.h> 40 #include <VBox/VBoxGuest.h> 41 42 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) 187 { 188 VMMDevRequestHeader *pReq; 189 190 AssertPtrReturn(ppReq, VERR_INVALID_PARAMETER); 191 AssertMsgReturn(cb >= sizeof(VMMDevRequestHeader), ("%#x vs %#zx\n", cb, sizeof(VMMDevRequestHeader)), 192 VERR_INVALID_PARAMETER); 193 194 pReq = (VMMDevRequestHeader *)RTMemTmpAlloc(cb); 195 if (RT_UNLIKELY(!pReq)) 196 return VERR_NO_MEMORY; 197 198 pReq->size = cb; 199 pReq->version = VMMDEV_REQUEST_HEADER_VERSION; 200 pReq->requestType = enmReqType; 201 pReq->rc = VERR_GENERAL_FAILURE; 202 pReq->reserved1 = 0; 203 pReq->reserved2 = 0; 204 205 *ppReq = pReq; 206 207 return VINF_SUCCESS; 208 } 209 210 211 VBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq) 212 { 213 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_VMMREQUEST(pReq->size), pReq, pReq->size); 214 } 215 216 217 VBGLR3DECL(void) VbglR3GRFree(VMMDevRequestHeader *pReq) 218 { 219 RTMemTmpFree(pReq); 220 } 221 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 } 22 #include "VBGLR3Internal.h" 233 23 234 24 … … 240 30 Req.pointerXPos = 0; 241 31 Req.pointerYPos = 0; 242 int rc = VbglR3GRPerform(&Req.header);32 int rc = vbglR3GRPerform(&Req.header); 243 33 if (RT_SUCCESS(rc)) 244 34 { … … 261 51 Req.pointerXPos = 0; 262 52 Req.pointerYPos = 0; 263 return VbglR3GRPerform(&Req.header);53 return vbglR3GRPerform(&Req.header); 264 54 } 265 55 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 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibTime.cpp
r6445 r6447 1 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, Time. 4 4 */ 5 5 … … 20 20 * Header Files * 21 21 *******************************************************************************/ 22 #ifdef RT_OS_OS223 # define INCL_BASE24 # define INCL_ERRORS25 # 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 #endif32 33 22 #include <iprt/time.h> 34 #include <iprt/asm.h> 35 #include <iprt/string.h> 36 #include <iprt/file.h> 37 #include <iprt/assert.h> 38 #include <iprt/mem.h> 39 #include <iprt/alloca.h> 40 #include <VBox/VBoxGuest.h> 41 42 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) 187 { 188 VMMDevRequestHeader *pReq; 189 190 AssertPtrReturn(ppReq, VERR_INVALID_PARAMETER); 191 AssertMsgReturn(cb >= sizeof(VMMDevRequestHeader), ("%#x vs %#zx\n", cb, sizeof(VMMDevRequestHeader)), 192 VERR_INVALID_PARAMETER); 193 194 pReq = (VMMDevRequestHeader *)RTMemTmpAlloc(cb); 195 if (RT_UNLIKELY(!pReq)) 196 return VERR_NO_MEMORY; 197 198 pReq->size = cb; 199 pReq->version = VMMDEV_REQUEST_HEADER_VERSION; 200 pReq->requestType = enmReqType; 201 pReq->rc = VERR_GENERAL_FAILURE; 202 pReq->reserved1 = 0; 203 pReq->reserved2 = 0; 204 205 *ppReq = pReq; 206 207 return VINF_SUCCESS; 208 } 209 210 211 VBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq) 212 { 213 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_VMMREQUEST(pReq->size), pReq, pReq->size); 214 } 215 216 217 VBGLR3DECL(void) VbglR3GRFree(VMMDevRequestHeader *pReq) 218 { 219 RTMemTmpFree(pReq); 220 } 23 #include "VBGLR3Internal.h" 221 24 222 25 … … 226 29 vmmdevInitRequest(&Req.header, VMMDevReq_GetHostTime); 227 30 Req.time = UINT64_MAX; 228 int rc = VbglR3GRPerform(&Req.header);31 int rc = vbglR3GRPerform(&Req.header); 229 32 if (RT_SUCCESS(rc)) 230 33 RTTimeSpecSetMilli(pTime, (int64_t)Req.time); … … 232 35 } 233 36 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.