Changeset 15704 in vbox
- Timestamp:
- Dec 19, 2008 4:44:54 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxGuest.h
r15699 r15704 916 916 #pragma pack() 917 917 918 #define VMMDEV_HGCM_CALL_PARMS(a) ((HGCMFunctionParameter *)((uint8_t *)a + sizeof (VMMDevHGCMCall))) 918 #define VMMDEV_HGCM_CALL_PARMS(a) ((HGCMFunctionParameter *)((uint8_t *)a + sizeof (VMMDevHGCMCall))) 919 #define VMMDEV_HGCM_CALL_PARMS32(a) ((HGCMFunctionParameter32 *)((uint8_t *)a + sizeof (VMMDevHGCMCall))) 919 920 920 921 #ifdef VBOX_WITH_64_BITS_GUESTS … … 1404 1405 1405 1406 # define VBOXGUEST_HGCM_CALL_PARMS(a) ((HGCMFunctionParameter *)((uint8_t *)(a) + sizeof (VBoxGuestHGCMCallInfo))) 1407 # define VBOXGUEST_HGCM_CALL_PARMS32(a) ((HGCMFunctionParameter32 *)((uint8_t *)(a) + sizeof (VBoxGuestHGCMCallInfo))) 1406 1408 1407 1409 #endif /* VBOX_WITH_HGCM */ -
trunk/include/VBox/VBoxGuestLib.h
r14352 r15704 200 200 DECLVBGL(int) VbglHGCMCall (VBoxGuestHGCMCallInfo *pCallInfo, 201 201 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData); 202 203 /** Call a HGCM service. (32 bits packet structure in a 64 bits guest) 204 * 205 * @note This function can deal with cancelled requests. 206 * 207 * @param pCallInfo The request data. 208 * @param pAsyncCallback Required pointer to function that is called when 209 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest 210 * implements waiting for an IRQ in this function. 211 * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback. 212 * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to callback. 213 * 214 * @return VBox status code. 215 */ 216 DECLVBGL(int) VbglHGCMCall32 (VBoxGuestHGCMCallInfo *pCallInfo, 217 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData); 202 218 203 219 #else /* !VBGL_VBOXGUEST */ -
trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest.cpp
r15703 r15704 993 993 case VBOXGUEST_IOCTL_HGCM_CALL(0): /* (The size isn't relevant on NT.) */ 994 994 { 995 int rc; 996 995 997 dprintf(("VBoxGuest::VBoxGuestDeviceControl: VBOXGUEST_IOCTL_HGCM_CALL\n")); 996 998 … … 1006 1008 VBoxGuestHGCMCallInfo *ptr = (VBoxGuestHGCMCallInfo *)pBuf; 1007 1009 1008 int rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT); 1010 # if ARCH_BITS == 64 1011 if (IoIs32bitProcess(pIrp)) 1012 rc = VbglHGCMCall32(ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT); 1013 else 1014 # endif 1015 rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT); 1009 1016 1010 1017 if (RT_FAILURE(rc)) … … 1019 1026 1020 1027 } break; 1021 1022 #if defined(VBOX_WITH_64_BITS_GUESTS) && ARCH_BITS == 641023 case VBOXGUEST_IOCTL_HGCM_CALL_32(0): /* (The size isn't relevant on NT.) */1024 {1025 dprintf(("VBoxGuest::VBoxGuestDeviceControl: VBOXGUEST_IOCTL_HGCM_CALL_32\n"));1026 1027 Status = vboxHGCMVerifyIOBuffers (pStack,1028 sizeof (VBoxGuestHGCMCallInfo));1029 1030 if (Status != STATUS_SUCCESS)1031 {1032 dprintf(("VBoxGuest::VBoxGuestDeviceControl: invalid parameter. Status: %p\n", Status));1033 break;1034 }1035 1036 VBoxGuestHGCMCallInfo *ptr32 = (VBoxGuestHGCMCallInfo *)pBuf;1037 VBoxGuestHGCMCallInfo *ptr64;1038 1039 unsigned cbPtr32 = sizeof(*ptr32)+ptr32->cParms*sizeof(HGCMFunctionParameter32);1040 unsigned cbPtr64 = sizeof(*ptr32)+ptr32->cParms*sizeof(HGCMFunctionParameter);1041 1042 /*@todo r=Leonid, same should be applied to case VBOXGUEST_IOCTL_HGCM_CALL(0) as well,1043 * because vboxHGCMVerifyIOBuffers, checks for sizeof (VBoxGuestHGCMCallInfo) only.1044 */1045 if (pStack->Parameters.DeviceIoControl.InputBufferLength < cbPtr32)1046 {1047 dprintf(("VBoxGuest::vboxHGCMVerifyIOBuffers: InputBufferLength %d < %d\n",1048 pStack->Parameters.DeviceIoControl.InputBufferLength, cbPtr32));1049 Status = STATUS_INVALID_PARAMETER;1050 break;1051 }1052 1053 ptr64 = (VBoxGuestHGCMCallInfo *) RTMemTmpAlloc(cbPtr64);1054 1055 if (!ptr64)1056 {1057 dprintf(("VBoxGuest::VBoxGuestDeviceControl: No memory\n"));1058 Status = STATUS_UNSUCCESSFUL;1059 break;1060 }1061 1062 /*copy 32bit call info into 64bit*/1063 {1064 unsigned iParm;1065 HGCMFunctionParameter *pParm64;1066 HGCMFunctionParameter32 *pParm32;1067 1068 /*copy header*/1069 memcpy(ptr64, ptr32, sizeof(VBoxGuestHGCMCallInfo));1070 1071 pParm64 = VBOXGUEST_HGCM_CALL_PARMS(ptr64);1072 pParm32 = (HGCMFunctionParameter32*) VBOXGUEST_HGCM_CALL_PARMS(ptr32);1073 1074 for (iParm = 0; iParm < ptr32->cParms; ++iParm)1075 {1076 pParm64->type = pParm32->type;1077 1078 switch(pParm64->type)1079 {1080 case VMMDevHGCMParmType_PhysAddr:1081 pParm64->u.Pointer.size = pParm32->u.Pointer.size;1082 pParm64->u.Pointer.u.physAddr = pParm32->u.Pointer.u.physAddr;1083 break;1084 case VMMDevHGCMParmType_LinAddr:1085 case VMMDevHGCMParmType_LinAddr_In:1086 case VMMDevHGCMParmType_LinAddr_Out:1087 case VMMDevHGCMParmType_LinAddr_Locked:1088 case VMMDevHGCMParmType_LinAddr_Locked_In:1089 case VMMDevHGCMParmType_LinAddr_Locked_Out:1090 pParm64->u.Pointer.size = pParm32->u.Pointer.size;1091 pParm64->u.Pointer.u.linearAddr = pParm32->u.Pointer.u.linearAddr;1092 break;1093 case VMMDevHGCMParmType_32bit:1094 pParm64->u.value32 = pParm32->u.value32;1095 break;1096 case VMMDevHGCMParmType_64bit:1097 pParm64->u.value64 = pParm32->u.value64;1098 break;1099 default:1100 Status = STATUS_UNSUCCESSFUL;1101 break;1102 }1103 1104 ++pParm32;1105 ++pParm64;1106 }1107 1108 if (Status != STATUS_SUCCESS)1109 {1110 dprintf(("VBoxGuest::VBoxGuestDeviceControl: invalid parameter. Status: %p\n", Status));1111 break;1112 }1113 }1114 1115 int rc = VbglHGCMCall (ptr64, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT);1116 1117 if (RT_FAILURE(rc))1118 {1119 dprintf(("VBOXGUEST_IOCTL_HGCM_CALL: vbox rc = %Rrc\n", rc));1120 Status = STATUS_UNSUCCESSFUL;1121 }1122 else1123 {1124 cbOut = pStack->Parameters.DeviceIoControl.OutputBufferLength;1125 }1126 1127 /*copy results back*/1128 {1129 unsigned iParm;1130 HGCMFunctionParameter *pParm64;1131 HGCMFunctionParameter32 *pParm32;1132 1133 /*copy header*/1134 memcpy(ptr32, ptr64, sizeof(VBoxGuestHGCMCallInfo));1135 1136 pParm64 = VBOXGUEST_HGCM_CALL_PARMS(ptr64);1137 pParm32 = (HGCMFunctionParameter32*) VBOXGUEST_HGCM_CALL_PARMS(ptr32);1138 1139 /*@todo r=Leonid, FIXME: I think pointer values couldn't change but not sure so better play it safe*/1140 for (iParm = 0; iParm < ptr32->cParms; ++iParm)1141 {1142 pParm32->type = pParm64->type;1143 1144 switch(pParm64->type)1145 {1146 case VMMDevHGCMParmType_PhysAddr:1147 pParm32->u.Pointer.size = pParm64->u.Pointer.size;1148 pParm32->u.Pointer.u.physAddr = pParm64->u.Pointer.u.physAddr;1149 break;1150 case VMMDevHGCMParmType_LinAddr:1151 case VMMDevHGCMParmType_LinAddr_In:1152 case VMMDevHGCMParmType_LinAddr_Out:1153 case VMMDevHGCMParmType_LinAddr_Locked:1154 case VMMDevHGCMParmType_LinAddr_Locked_In:1155 case VMMDevHGCMParmType_LinAddr_Locked_Out:1156 pParm32->u.Pointer.size = pParm64->u.Pointer.size;1157 pParm32->u.Pointer.u.linearAddr = pParm64->u.Pointer.u.linearAddr;1158 break;1159 case VMMDevHGCMParmType_32bit:1160 pParm32->u.value32 = pParm64->u.value32;1161 break;1162 case VMMDevHGCMParmType_64bit:1163 pParm32->u.value64 = pParm64->u.value64;1164 break;1165 default:1166 Status = STATUS_UNSUCCESSFUL;1167 break;1168 }1169 1170 ++pParm32;1171 ++pParm64;1172 }1173 1174 if (Status != STATUS_SUCCESS)1175 {1176 dprintf(("VBoxGuest::VBoxGuestDeviceControl: invalid parameter. Status: %p\n", Status));1177 break;1178 }1179 }1180 1181 RTMemTmpFree(ptr64);1182 1183 } break;1184 #endif1185 1028 1186 1029 case VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0): /* (The size isn't relevant on NT.) */ -
trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
r14217 r15704 286 286 return rc; 287 287 } 288 # if ARCH_BITS == 64 289 DECLVBGL(int) VbglHGCMCall32 (VBoxGuestHGCMCallInfo *pCallInfo, 290 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData) 291 { 292 VMMDevHGCMCall *pHGCMCall; 293 uint32_t cbParms; 294 HGCMFunctionParameter32 *pParm; 295 unsigned iParm; 296 int rc; 297 298 if (!pCallInfo || !pAsyncCallback || pCallInfo->cParms > VBOX_HGCM_MAX_PARMS) 299 { 300 AssertFailed(); 301 return VERR_INVALID_PARAMETER; 302 } 303 304 Log (("VbglHGCMCall: pCallInfo->cParms = %d, pHGCMCall->u32Function = %d\n", pCallInfo->cParms, pCallInfo->u32Function)); 305 306 pHGCMCall = NULL; 307 308 cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter32); 309 310 /* Allocate request */ 311 rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMCall, sizeof (VMMDevHGCMCall) + cbParms, VMMDevReq_HGCMCall32); 312 313 Log (("VbglHGCMCall Allocated gr %p, rc = %Rrc, cbParms = %d\n", pHGCMCall, rc, cbParms)); 314 315 if (RT_SUCCESS(rc)) 316 { 317 void *apvCtx[VBOX_HGCM_MAX_PARMS]; 318 memset (apvCtx, 0, sizeof(void *) * pCallInfo->cParms); 319 320 /* Initialize request memory */ 321 pHGCMCall->header.fu32Flags = 0; 322 pHGCMCall->header.result = VINF_SUCCESS; 323 324 pHGCMCall->u32ClientID = pCallInfo->u32ClientID; 325 pHGCMCall->u32Function = pCallInfo->u32Function; 326 pHGCMCall->cParms = pCallInfo->cParms; 327 328 if (cbParms) 329 { 330 /* Lock user buffers. */ 331 pParm = VBOXGUEST_HGCM_CALL_PARMS32(pCallInfo); 332 333 for (iParm = 0; iParm < pCallInfo->cParms; iParm++, pParm++) 334 { 335 switch (pParm->type) 336 { 337 case VMMDevHGCMParmType_LinAddr_Locked_In: 338 pParm->type = VMMDevHGCMParmType_LinAddr_In; 339 break; 340 case VMMDevHGCMParmType_LinAddr_Locked_Out: 341 pParm->type = VMMDevHGCMParmType_LinAddr_Out; 342 break; 343 case VMMDevHGCMParmType_LinAddr_Locked: 344 pParm->type = VMMDevHGCMParmType_LinAddr; 345 break; 346 347 case VMMDevHGCMParmType_LinAddr_In: 348 case VMMDevHGCMParmType_LinAddr_Out: 349 case VMMDevHGCMParmType_LinAddr: 350 /* PORTME: When porting this to Darwin and other systems where the entire kernel isn't mapped 351 into every process, all linear address will have to be converted to physical SG lists at 352 this point. Care must also be taken on these guests to not mix kernel and user addresses 353 in HGCM calls, or we'll end up locking the wrong memory. If VMMDev/HGCM gets a linear address 354 it will assume that it's in the current memory context (i.e. use CR3 to translate it). 355 356 These kind of problems actually applies to some patched linux kernels too, including older 357 fedora releases. (The patch is the infamous 4G/4G patch, aka 4g4g, by Ingo Molnar.) */ 358 rc = vbglLockLinear (&apvCtx[iParm], (void *)pParm->u.Pointer.u.linearAddr, pParm->u.Pointer.size, (pParm->type == VMMDevHGCMParmType_LinAddr_In) ? false : true /* write access */); 359 break; 360 default: 361 /* make gcc happy */ 362 break; 363 } 364 if (RT_FAILURE (rc)) 365 break; 366 } 367 memcpy (VMMDEV_HGCM_CALL_PARMS32(pHGCMCall), VBOXGUEST_HGCM_CALL_PARMS32(pCallInfo), cbParms); 368 } 369 370 /* Check that the parameter locking was ok. */ 371 if (RT_SUCCESS(rc)) 372 { 373 Log (("calling VbglGRPerform\n")); 374 375 /* Issue request */ 376 rc = VbglGRPerform (&pHGCMCall->header.header); 377 378 Log (("VbglGRPerform rc = %Rrc (header rc=%d)\n", rc, pHGCMCall->header.result)); 379 380 /** If the call failed, but as a result of the request itself, then pretend success 381 * Upper layers will interpret the result code in the packet. 382 */ 383 if (RT_FAILURE(rc) && rc == pHGCMCall->header.result) 384 { 385 Assert(pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE); 386 rc = VINF_SUCCESS; 387 } 388 389 if (RT_SUCCESS(rc)) 390 { 391 /* Check if host decides to process the request asynchronously. */ 392 if (rc == VINF_HGCM_ASYNC_EXECUTE) 393 { 394 /* Wait for request completion interrupt notification from host */ 395 Log (("Processing HGCM call asynchronously\n")); 396 pAsyncCallback (&pHGCMCall->header, pvAsyncData, u32AsyncData); 397 } 398 399 if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE) 400 { 401 if (cbParms) 402 memcpy (VBOXGUEST_HGCM_CALL_PARMS32(pCallInfo), VMMDEV_HGCM_CALL_PARMS32(pHGCMCall), cbParms); 403 404 pCallInfo->result = pHGCMCall->header.result; 405 } 406 else 407 { 408 /* The callback returns without completing the request, 409 * that means the wait was interrrupted. That can happen 410 * if the request times out, the system reboots or the 411 * VBoxService ended abnormally. 412 * 413 * Cancel the request, the host will not write to the 414 * memory related to the cancelled request. 415 */ 416 Log (("Cancelling HGCM call\n")); 417 pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED; 418 419 pHGCMCall->header.header.requestType = VMMDevReq_HGCMCancel; 420 VbglGRPerform (&pHGCMCall->header.header); 421 } 422 } 423 } 424 425 /* Unlock user buffers. */ 426 pParm = VBOXGUEST_HGCM_CALL_PARMS32(pCallInfo); 427 428 for (iParm = 0; iParm < pCallInfo->cParms; iParm++, pParm++) 429 { 430 if ( pParm->type == VMMDevHGCMParmType_LinAddr_In 431 || pParm->type == VMMDevHGCMParmType_LinAddr_Out 432 || pParm->type == VMMDevHGCMParmType_LinAddr) 433 { 434 if (apvCtx[iParm] != NULL) 435 { 436 vbglUnlockLinear (apvCtx[iParm], (void *)pParm->u.Pointer.u.linearAddr, pParm->u.Pointer.size); 437 } 438 } 439 else 440 Assert(!apvCtx[iParm]); 441 } 442 443 if ((pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_CANCELLED) == 0) 444 VbglGRFree (&pHGCMCall->header.header); 445 else 446 rc = VERR_INTERRUPTED; 447 } 448 449 return rc; 450 } 451 # endif /* ARCH_BITS == 64 */ 288 452 289 453 #endif /* VBGL_VBOXGUEST */
Note:
See TracChangeset
for help on using the changeset viewer.