Changeset 3090 in vbox for trunk/src/VBox/Additions/common/VBoxGuestLib
- Timestamp:
- Jun 11, 2007 1:16:07 PM (18 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxGuestLib
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
r2981 r3090 28 28 #include <iprt/string.h> 29 29 #include <iprt/assert.h> 30 #include <iprt/alloca.h> 30 31 31 32 /* These functions can be only used by VBoxGuest. */ … … 129 130 int rc; 130 131 131 if (!pCallInfo || !pAsyncCallback )132 if (!pCallInfo || !pAsyncCallback || pCallInfo->cParms > VBOX_HGCM_MAX_PARMS) 132 133 return VERR_INVALID_PARAMETER; 133 134 … … 145 146 if (VBOX_SUCCESS(rc)) 146 147 { 148 void **papvCtx = NULL; 149 147 150 /* Initialize request memory */ 148 151 pHGCMCall->header.fu32Flags = 0; … … 156 159 { 157 160 memcpy (VMMDEV_HGCM_CALL_PARMS(pHGCMCall), VBOXGUEST_HGCM_CALL_PARMS(pCallInfo), cbParms); 158 } 159 160 dprintf (("calling VbglGRPerform\n")); 161 162 /* Issue request */ 163 rc = VbglGRPerform (&pHGCMCall->header.header); 164 165 dprintf (("VbglGRPerform rc = %Vrc (header rc=%d)\n", rc, pHGCMCall->header.result)); 166 167 /** If the call failed, but as a result of the request itself, then pretend success 168 * Upper layers will interpret the result code in the packet. 169 */ 170 if (VBOX_FAILURE(rc) && rc == pHGCMCall->header.result) 171 { 172 Assert(pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE); 173 rc = VINF_SUCCESS; 174 } 175 161 162 /* Lock user buffers. */ 163 if (pCallInfo->cParms > 0) 164 { 165 papvCtx = (void **)alloca(pCallInfo->cParms * sizeof (papvCtx[0])); 166 memset (papvCtx, 0, pCallInfo->cParms * sizeof (papvCtx[0])); 167 } 168 169 HGCMFunctionParameter *pParm = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo); 170 171 unsigned iParm = 0; 172 for (; iParm < pCallInfo->cParms; iParm++, pParm++) 173 { 174 if ( pParm->type == VMMDevHGCMParmType_LinAddr_In 175 || pParm->type == VMMDevHGCMParmType_LinAddr_Out 176 || pParm->type == VMMDevHGCMParmType_LinAddr) 177 { 178 rc = vbglLockLinear (&papvCtx[iParm], (void *)pParm->u.Pointer.u.linearAddr, pParm->u.Pointer.size); 179 180 if (VBOX_FAILURE (rc)) 181 { 182 break; 183 } 184 } 185 } 186 } 187 188 /* Check that the parameter locking was ok. */ 176 189 if (VBOX_SUCCESS(rc)) 177 190 { 178 /* Check if host decides to process the request asynchronously. */ 179 if (rc == VINF_HGCM_ASYNC_EXECUTE) 180 { 181 /* Wait for request completion interrupt notification from host */ 182 pAsyncCallback (&pHGCMCall->header, pvAsyncData, u32AsyncData); 183 } 184 185 if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE) 186 { 187 if (cbParms) 188 { 189 memcpy (VBOXGUEST_HGCM_CALL_PARMS(pCallInfo), VMMDEV_HGCM_CALL_PARMS(pHGCMCall), cbParms); 190 } 191 pCallInfo->result = pHGCMCall->header.result; 192 } 193 else 194 { 195 /* The callback returns without completing the request, 196 * that means the wait was interrrupted. That can happen 197 * if system reboots or the VBoxService ended abnormally. 198 * In both cases it is OK to just leave the allocated memory 199 * in the physical heap. The memory leak does not affect normal 200 * operations. 201 * @todo VbglGRCancel (&pHGCMCall->header.header) need to be implemented. 202 * The host will not write to the cancelled memory. 203 */ 204 pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED; 191 dprintf (("calling VbglGRPerform\n")); 192 193 /* Issue request */ 194 rc = VbglGRPerform (&pHGCMCall->header.header); 195 196 dprintf (("VbglGRPerform rc = %Vrc (header rc=%d)\n", rc, pHGCMCall->header.result)); 197 198 /** If the call failed, but as a result of the request itself, then pretend success 199 * Upper layers will interpret the result code in the packet. 200 */ 201 if (VBOX_FAILURE(rc) && rc == pHGCMCall->header.result) 202 { 203 Assert(pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE); 204 rc = VINF_SUCCESS; 205 } 206 207 if (VBOX_SUCCESS(rc)) 208 { 209 /* Check if host decides to process the request asynchronously. */ 210 if (rc == VINF_HGCM_ASYNC_EXECUTE) 211 { 212 /* Wait for request completion interrupt notification from host */ 213 pAsyncCallback (&pHGCMCall->header, pvAsyncData, u32AsyncData); 214 } 215 216 if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE) 217 { 218 if (cbParms) 219 { 220 memcpy (VBOXGUEST_HGCM_CALL_PARMS(pCallInfo), VMMDEV_HGCM_CALL_PARMS(pHGCMCall), cbParms); 221 } 222 pCallInfo->result = pHGCMCall->header.result; 223 } 224 else 225 { 226 /* The callback returns without completing the request, 227 * that means the wait was interrrupted. That can happen 228 * if system reboots or the VBoxService ended abnormally. 229 * In both cases it is OK to just leave the allocated memory 230 * in the physical heap. The memory leak does not affect normal 231 * operations. 232 * @todo VbglGRCancel (&pHGCMCall->header.header) need to be implemented. 233 * The host will not write to the cancelled memory. 234 */ 235 pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED; 236 } 237 } 238 } 239 240 /* Unlock user buffers. */ 241 if (papvCtx != NULL) 242 { 243 HGCMFunctionParameter *pParm = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo); 244 245 unsigned iParm = 0; 246 for (; iParm < pCallInfo->cParms; iParm++, pParm++) 247 { 248 if ( pParm->type == VMMDevHGCMParmType_LinAddr_In 249 || pParm->type == VMMDevHGCMParmType_LinAddr_Out 250 || pParm->type == VMMDevHGCMParmType_LinAddr) 251 { 252 if (papvCtx[iParm] != NULL) 253 { 254 vbglUnlockLinear (papvCtx[iParm], (void *)pParm->u.Pointer.u.linearAddr, pParm->u.Pointer.size); 255 } 256 } 205 257 } 206 258 } -
trunk/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
r2981 r3090 44 44 SOURCES_GUESTLIBBASE = \ 45 45 GenericRequest.cpp \ 46 SysHlp.cpp \ 46 47 PhysHeap.cpp \ 47 48 Init.cpp \ -
trunk/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp
r2981 r3090 28 28 #include <iprt/assert.h> 29 29 30 int vbglLockLinear (void **ppvCtx, void *pv, uint32_t u32Size) 31 { 32 int rc = VINF_SUCCESS; 33 34 #ifdef __WIN__ 35 PMDL pMdl = IoAllocateMdl (pv, u32Size, FALSE, FALSE, NULL); 36 37 if (pMdl == NULL) 38 { 39 rc = VERR_NOT_SUPPORTED; 40 } 41 else 42 { 43 __try { 44 /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */ 45 MmProbeAndLockPages (pMdl, 46 KernelMode, 47 IoModifyAccess); 48 49 *ppvCtx = pMdl; 50 51 } __except(EXCEPTION_EXECUTE_HANDLER) { 52 53 IoFreeMdl (pMdl); 54 rc = VERR_INVALID_PARAMETER; 55 } 56 } 57 #else 58 NOREF(ppvCtx); 59 NOREF(pv); 60 NOREF(u32Size); 61 #endif /* __WIN__ */ 62 63 return rc; 64 } 65 66 void vbglUnlockLinear (void *pvCtx, void *pv, uint32_t u32Size) 67 { 68 NOREF(pv); 69 NOREF(u32Size); 70 71 #ifdef __WIN__ 72 PMDL pMdl = (PMDL)pvCtx; 73 74 if (pMdl != NULL) 75 { 76 MmUnlockPages (pMdl); 77 IoFreeMdl (pMdl); 78 } 79 #else 80 NOREF(pvCtx); 81 #endif /* __WIN__ */ 82 } 83 30 84 #ifndef VBGL_VBOXGUEST 31 85 -
trunk/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h
r2981 r3090 57 57 } VBGLDRIVER; 58 58 59 int vbglLockLinear (void **ppvCtx, void *pv, uint32_t u32Size); 60 void vbglUnlockLinear (void *pvCtx, void *pv, uint32_t u32Size); 61 59 62 60 63 #ifndef VBGL_VBOXGUEST
Note:
See TracChangeset
for help on using the changeset viewer.