Changeset 14352 in vbox for trunk/src/VBox
- Timestamp:
- Nov 19, 2008 2:10:24 PM (16 years ago)
- Location:
- trunk/src/VBox/Additions
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest.cpp
r14219 r14352 341 341 342 342 #ifdef VBOX_WITH_HGCM 343 DECLVBGL(void) VBoxHGCMCallback (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data) 344 { 345 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvData; 346 347 dprintf(("VBoxHGCMCallback\n")); 348 343 void VBoxHGCMCallbackWorker (VMMDevHGCMRequestHeader *pHeader, PVBOXGUESTDEVEXT pDevExt, 344 uint32_t u32Timeout, bool fInterruptible) 345 { 349 346 /* Possible problem with request completion right between the fu32Flags check and KeWaitForSingleObject 350 347 * call; introduce a timeout to make sure we don't wait indefinitely. 351 348 */ 352 349 350 LARGE_INTEGER timeout; 351 if (u32Timeout == RT_INDEFINITE_WAIT) 352 timeout.QuadPart = pDevExt->HGCMWaitTimeout.QuadPart; 353 else 354 timeout.QuadPart = u32Timeout * -10000; /* relative in 100ns units */ 353 355 while ((pHeader->fu32Flags & VBOX_HGCM_REQ_DONE) == 0) 354 356 { 355 /* Specifying UserMode so killing the user process will abort the wait. 356 * @todo Since VbglGRCancel is not yet implemented, the wait itself must 357 * be not interruptible. The wait can be interrupted only when the 358 * calling process is being killed. 359 * When alertable is TRUE, the wait sometimes ends with STATUS_USER_APC. 360 */ 357 /* Specifying UserMode so killing the user process will abort the wait. */ 361 358 NTSTATUS rc = KeWaitForSingleObject (&pDevExt->keventNotification, Executive, 362 359 UserMode, 363 FALSE, /* NotAlertable */364 & pDevExt->HGCMWaitTimeout360 fInterruptible ? TRUE : FALSE, /* Alertable */ 361 &timeout 365 362 ); 366 363 dprintf(("VBoxHGCMCallback: Wait returned %d fu32Flags=%x\n", rc, pHeader->fu32Flags)); 367 364 368 if (rc == STATUS_TIMEOUT )365 if (rc == STATUS_TIMEOUT && u32Timeout == RT_INDEFINITE_WAIT) 369 366 continue; 370 367 … … 380 377 } 381 378 382 /* Note that VbglGRCancel *is* now implemented. */ 383 DECLVBGL(void) VBoxHGCMCallbackTimeout (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data) 379 DECLVBGL(void) VBoxHGCMCallback (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data) 384 380 { 385 381 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvData; 386 LARGE_INTEGER timeout; 387 timeout.QuadPart = u32Data * -10000; /* relative in 100ns units */ 388 dprintf(("VBoxHGCMCallbackTimeout: entering, timeout %llu\n", timeout.QuadPart)); 389 NTSTATUS rc = KeWaitForSingleObject (&pDevExt->keventNotification, Executive, 390 UserMode, 391 FALSE, /* Not Alertable */ 392 &timeout 393 ); 394 dprintf(("VBoxHGCMCallbackTimeout: Wait returned %d fu32Flags=%x\n", rc, pHeader->fu32Flags)); 395 396 if (rc != STATUS_WAIT_0) 397 dprintf(("VBoxHGCMCallbackTimeout: The external event was signalled or the wait timed out or terminated rc = 0x%08X.\n", rc)); 398 else 399 dprintf(("VBoxHGCMCallbackTimeout: fu32Flags = %08X\n", pHeader->fu32Flags)); 400 return; 382 383 dprintf(("VBoxHGCMCallback\n")); 384 VBoxHGCMCallbackWorker (pHeader, pDevExt, u32Data, false); 385 } 386 387 DECLVBGL(void) VBoxHGCMCallbackInterruptible (VMMDevHGCMRequestHeader *pHeader, void *pvData, 388 uint32_t u32Data) 389 { 390 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvData; 391 392 dprintf(("VBoxHGCMCallback\n")); 393 VBoxHGCMCallbackWorker (pHeader, pDevExt, u32Data, true); 401 394 } 402 395 … … 937 930 dprintf(("a) ptr->u32ClientID = %d\n", ptr->u32ClientID)); 938 931 939 int rc = VbglHGCMConnect (ptr, VBoxHGCMCallback, pDevExt, 0);932 int rc = VbglHGCMConnect (ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT); 940 933 941 934 dprintf(("b) ptr->u32ClientID = %d\n", ptr->u32ClientID)); … … 980 973 */ 981 974 982 int rc = VbglHGCMDisconnect (ptr, VBoxHGCMCallback, pDevExt, 0);975 int rc = VbglHGCMDisconnect (ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT); 983 976 984 977 if (RT_FAILURE(rc)) … … 1009 1002 VBoxGuestHGCMCallInfo *ptr = (VBoxGuestHGCMCallInfo *)pBuf; 1010 1003 1011 int rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, 0);1004 int rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, RT_INDEFINITE_WAIT); 1012 1005 1013 1006 if (RT_FAILURE(rc)) … … 1023 1016 } break; 1024 1017 1025 case VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT(0): /* (The size isn't relevant on NT.) */1026 { 1027 dprintf(("VBoxGuest::VBoxGuestDeviceControl: VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT\n"));1018 case VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0): /* (The size isn't relevant on NT.) */ 1019 { 1020 dprintf(("VBoxGuest::VBoxGuestDeviceControl: VBOXGUEST_IOCTL_HGCM_CALL_TIMED\n")); 1028 1021 1029 1022 Status = vboxHGCMVerifyIOBuffers (pStack, 1030 sizeof (VBoxGuestHGCMCallInfoTime out));1023 sizeof (VBoxGuestHGCMCallInfoTimed)); 1031 1024 1032 1025 if (Status != STATUS_SUCCESS) … … 1036 1029 } 1037 1030 1038 VBoxGuestHGCMCallInfoTime out *pInfo = (VBoxGuestHGCMCallInfoTimeout*)pBuf;1031 VBoxGuestHGCMCallInfoTimed *pInfo = (VBoxGuestHGCMCallInfoTimed *)pBuf; 1039 1032 VBoxGuestHGCMCallInfo *ptr = &pInfo->info; 1040 1033 1041 1034 int rc; 1042 if (pInfo->u32Timeout == RT_INDEFINITE_WAIT) 1043 { 1044 dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall with no timeout\n")); 1045 rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, 0); 1035 if (pInfo->fInterruptible) 1036 { 1037 dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall interruptible, timeout %lu ms\n", 1038 pInfo->u32Timeout)); 1039 rc = VbglHGCMCall (ptr, VBoxHGCMCallbackInterruptible, pDevExt, pInfo->u32Timeout); 1046 1040 } 1047 1041 else 1048 1042 { 1049 dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall timeout %lu ms\n",1043 dprintf(("VBoxGuest::VBoxGuestDeviceControl: calling VBoxHGCMCall, timeout %lu ms\n", 1050 1044 pInfo->u32Timeout)); 1051 rc = VbglHGCMCall (ptr, VBoxHGCMCallback Timeout, pDevExt, pInfo->u32Timeout);1045 rc = VbglHGCMCall (ptr, VBoxHGCMCallback, pDevExt, pInfo->u32Timeout); 1052 1046 } 1053 1047 1054 1048 if (RT_FAILURE(rc)) 1055 1049 { 1056 dprintf(("VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT: vbox rc = %Rrc\n", rc));1050 dprintf(("VBOXGUEST_IOCTL_HGCM_CALL_TIMED: vbox rc = %Rrc\n", rc)); 1057 1051 Status = STATUS_UNSUCCESSFUL; 1058 1052 } -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r14316 r14352 389 389 pSession->aHGCMClientIds[i] = 0; 390 390 Log(("VBoxGuestCloseSession: disconnecting client id %#RX32\n", Info.u32ClientID)); 391 VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, false /* uninterruptible */);391 VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT); 392 392 } 393 393 #endif … … 910 910 } 911 911 912 913 912 /** 914 913 * This is a callback for dealing with async waits. … … 918 917 static DECLCALLBACK(void) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User) 919 918 { 920 const bool fInterruptible = (bool)u32User;921 919 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser; 922 920 LogFunc(("requestType=%d\n", pHdr->header.requestType)); 923 VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, pDevExt, fInterruptible, RT_INDEFINITE_WAIT); 924 } 925 921 VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, 922 pDevExt, false /* fInterruptible */, 923 RT_INDEFINITE_WAIT); 924 } 926 925 927 926 /** … … 930 929 * It operates in a manner similar to VBoxGuestCommonIOCtl_WaitEvent. 931 930 */ 932 static DECLCALLBACK(void) VBoxGuestHGCMAsyncWaitCallbackTimeoutInterruptible(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User) 931 static DECLCALLBACK(void) VBoxGuestHGCMAsyncWaitCallbackInterruptible(VMMDevHGCMRequestHeader *pHdr, 932 void *pvUser, uint32_t u32User) 933 933 { 934 934 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser; 935 935 LogFunc(("requestType=%d\n", pHdr->header.requestType)); 936 VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, pDevExt, true /* fInterruptible */, u32User); 937 } 938 939 940 /** 941 * This is an uninterruptible callback for dealing with async waits with a timeout. 942 * 943 * It operates in a manner similar to VBoxGuestCommonIOCtl_WaitEvent. 944 */ 945 static DECLCALLBACK(void) VBoxGuestHGCMAsyncWaitCallbackTimeout(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User) 946 { 947 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser; 948 LogFunc(("requestType=%d\n", pHdr->header.requestType)); 949 VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, pDevExt, false /* fInterruptible */, u32User); 950 } 951 936 VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, 937 pDevExt, true /* fInterruptible */, 938 u32User); 939 } 952 940 953 941 static int VBoxGuestCommonIOCtl_HGCMConnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestHGCMConnectInfo *pInfo, … … 963 951 ? pInfo->Loc.u.host.achName : "<not local host>")); 964 952 965 int rc = VbglHGCMConnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, false /* uninterruptible */);953 int rc = VbglHGCMConnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT); 966 954 if (RT_SUCCESS(rc)) 967 955 { … … 993 981 Info.result = 0; 994 982 Info.u32ClientID = pInfo->u32ClientID; 995 VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, false /* uninterruptible */);983 VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT); 996 984 return VERR_TOO_MANY_OPEN_FILES; 997 985 } … … 1035 1023 */ 1036 1024 Log(("VBoxGuestCommonIOCtl: HGCM_DISCONNECT: u32Client=%RX32\n", pInfo->u32ClientID)); 1037 int rc = VbglHGCMDisconnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, false /* uninterruptible */);1025 int rc = VbglHGCMDisconnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT); 1038 1026 if (RT_SUCCESS(rc)) 1039 1027 { … … 1053 1041 1054 1042 1055 /** @remarks Identical to VBoxGuestCommonIOCtl_HGCMCallTimeout. */ 1056 static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestHGCMCallInfo *pInfo, 1043 static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt, 1044 PVBOXGUESTSESSION pSession, 1045 VBoxGuestHGCMCallInfo *pInfo, 1046 uint32_t u32Timeout, bool fInterruptible, 1057 1047 size_t cbData, size_t *pcbDataReturned) 1058 1048 { … … 1099 1089 */ 1100 1090 Log(("VBoxGuestCommonIOCtl: HGCM_CALL: u32Client=%RX32\n", pInfo->u32ClientID)); 1101 int rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, pSession->R0Process != NIL_RTR0PROCESS); 1091 int rc; 1092 if (fInterruptible) 1093 rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, 1094 u32Timeout); 1095 else 1096 rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, u32Timeout); 1102 1097 if (RT_SUCCESS(rc)) 1103 1098 { … … 1110 1105 } 1111 1106 1112 1113 # ifdef HGCM_TIMEOUT1114 /** @remarks Identical to VBoxGuestCommonIOCtl_HGCMCall.1115 * @todo r=bird: merge the two. */1116 static int VBoxGuestCommonIOCtl_HGCMCallTimeout(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestHGCMCallInfoTimeout *pInfoTimeout,1117 size_t cbData, size_t *pcbDataReturned)1118 {1119 VBoxGuestHGCMCallInfo *pInfo = &pInfoTimeout->info;1120 /*1121 * Some more validations.1122 */1123 if (pInfo->cParms > 4096) /* (Just make sure it doesn't overflow the next check.) */1124 {1125 Log(("VBoxGuestCommonIOCtl: HGCM_CALL: cParm=%RX32 is not sane\n", pInfo->cParms));1126 return VERR_INVALID_PARAMETER;1127 }1128 const size_t cbActual = sizeof(*pInfoTimeout) + pInfo->cParms * sizeof(HGCMFunctionParameter);1129 if (cbData < cbActual)1130 {1131 Log(("VBoxGuestCommonIOCtl: HGCM_CALL: cbData=%#zx (%zu) required size is %#zx (%zu)\n",1132 cbData, cbActual));1133 return VERR_INVALID_PARAMETER;1134 }1135 1136 /*1137 * Validate the client id.1138 */1139 const uint32_t u32ClientId = pInfo->u32ClientID;1140 unsigned i;1141 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;1142 RTSpinlockAcquireNoInts(pDevExt->SessionSpinlock, &Tmp);1143 for (i = 0; i < RT_ELEMENTS(pSession->aHGCMClientIds); i++)1144 if (pSession->aHGCMClientIds[i] == u32ClientId)1145 break;1146 RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock, &Tmp);1147 if (RT_UNLIKELY(i >= RT_ELEMENTS(pSession->aHGCMClientIds)))1148 {1149 static unsigned s_cErrors = 0;1150 if (s_cErrors++ > 32)1151 LogRel(("VBoxGuestCommonIOCtl: HGCM_CALL: Invalid handle. u32Client=%RX32\n", u32ClientId));1152 return VERR_INVALID_HANDLE;1153 }1154 1155 /*1156 * The VbglHGCMCall call will invoke the callback if the HGCM1157 * call is performed in an ASYNC fashion. This function can1158 * deal with cancelled requests, so we let user more requests1159 * be interruptible (should add a flag for this later I guess).1160 */1161 Log(("VBoxGuestCommonIOCtl: HGCM_CALL: u32Client=%RX32\n", pInfo->u32ClientID));1162 int rc;1163 if (pSession->R0Process == NIL_RTR0PROCESS)1164 rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallbackTimeout, pDevExt, pInfoTimeout->u32Timeout);1165 else1166 rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallbackTimeoutInterruptible, pDevExt,1167 pInfoTimeout->u32Timeout);1168 if (RT_SUCCESS(rc))1169 {1170 Log(("VBoxGuestCommonIOCtl: HGCM_CALL: result=%Rrc\n", pInfo->result));1171 if (pcbDataReturned)1172 *pcbDataReturned = cbActual;1173 }1174 Log(("VBoxGuestCommonIOCtl: HGCM_CALL: Failed. rc=%Rrc.\n", rc));1175 return rc;1176 }1177 # endif /* HGCM_TIMEOUT */1178 1179 1180 1107 /** 1181 1108 * @returns VBox status code. Unlike the other HGCM IOCtls this will combine … … 1196 1123 Info.result = (uint32_t)VERR_WRONG_ORDER; /** @todo Vitali, why is this member unsigned? */ 1197 1124 Info.u32ClientID = pDevExt->u32ClipboardClientId; 1198 rc = VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, 0);1125 rc = VbglHGCMDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT); 1199 1126 if (RT_SUCCESS(rc)) 1200 1127 { … … 1219 1146 Info.result = (uint32_t)VERR_WRONG_ORDER; 1220 1147 1221 rc = VbglHGCMConnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, 0);1148 rc = VbglHGCMConnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT); 1222 1149 if (RT_FAILURE(rc)) 1223 1150 { … … 1323 1250 * These ones are tricky and can be done later. 1324 1251 */ 1325 /**@todo r=bird: Merge the handling of these two. The only difference is that the 2nd has one or two extra argument preceeding the call info. */1326 1252 else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0))) 1327 1253 { 1328 1254 CHECKRET_MIN_SIZE("HGCM_CALL", sizeof(VBoxGuestHGCMCallInfo)); 1329 rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, cbData, pcbDataReturned); 1330 } 1331 # ifdef HGCM_TIMEOUT 1332 else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(0))) 1333 { 1334 CHECKRET_MIN_SIZE("HGCM_CALL_TIMEOUT", sizeof(VBoxGuestHGCMCallInfoTimeout)); 1335 rc = VBoxGuestCommonIOCtl_HGCMCallTimeout(pDevExt, pSession, (VBoxGuestHGCMCallInfoTimeout *)pvData, cbData, pcbDataReturned); 1336 } 1337 # endif /* HGCM_TIMEOUT */ 1255 bool fInterruptible = pSession->R0Process != NIL_RTR0PROCESS; 1256 rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, 1257 RT_INDEFINITE_WAIT, fInterruptible, 1258 cbData, pcbDataReturned); 1259 } 1260 else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0))) 1261 { 1262 CHECKRET_MIN_SIZE("HGCM_CALL_TIMED", sizeof(VBoxGuestHGCMCallInfoTimed)); 1263 VBoxGuestHGCMCallInfoTimed *pInfo = (VBoxGuestHGCMCallInfoTimed *)pvData; 1264 rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, &pInfo->info, 1265 pInfo->u32Timeout, !!pInfo->fInterruptible, 1266 cbData, pcbDataReturned); 1267 } 1338 1268 #endif /* VBOX_WITH_HGCM */ 1339 1269 else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_LOG(0))) -
trunk/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp
r14207 r14352 187 187 } 188 188 189 DECLVBGL(int) VbglHGCMCallTime out(VBGLHGCMHANDLE handle,190 VBoxGuestHGCMCallInfoTimeout*pData, uint32_t cbData)189 DECLVBGL(int) VbglHGCMCallTimed (VBGLHGCMHANDLE handle, 190 VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData) 191 191 { 192 192 int rc = VINF_SUCCESS; 193 193 194 VBGL_HGCM_ASSERTMsg(cbData >= sizeof (VBoxGuestHGCMCallInfoTimeout) + pData->info.cParms * sizeof (HGCMFunctionParameter), 195 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->info.cParms, sizeof (VBoxGuestHGCMCallInfoTimeout) + pData->info.cParms * sizeof (VBoxGuestHGCMCallInfo))); 196 197 if (pData->u32Timeout == RT_INDEFINITE_WAIT) 198 { 199 uint32_t cbDataNew = cbData - RT_OFFSETOF(VBoxGuestHGCMCallInfoTimeout, info); 200 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL(cbDataNew), &pData->info, 201 cbDataNew); 202 } 203 else 204 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(cbData), pData, cbData); 194 uint32_t cbExpected = sizeof (VBoxGuestHGCMCallInfoTimed) 195 + pData->info.cParms * sizeof (HGCMFunctionParameter); 196 VBGL_HGCM_ASSERTMsg(cbData >= cbExpected, 197 ("cbData = %d, cParms = %d (calculated size %d)\n", 198 cbData, pData->info.cParms, cbExpected)); 199 200 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMED(cbData), 201 pData, cbData); 205 202 206 203 return rc; -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
r14214 r14352 846 846 Msg.size.SetUInt32(0); 847 847 848 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT(sizeof(Msg)), &Msg, sizeof(Msg));848 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(sizeof(Msg)), &Msg, sizeof(Msg)); 849 849 if (RT_SUCCESS(rc)) 850 850 rc = Msg.hdr.info.result; -
trunk/src/VBox/Additions/linux/module/cmc.c
r14304 r14352 31 31 { 32 32 VBoxDevice *dev = pvData; 33 wait_event (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE); 33 if (u32Data == RT_INDEFINITE_WAIT) 34 wait_event (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE); 35 else 36 wait_event_timeout (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE, 37 msecs_to_jiffies (u32Data)); 34 38 } 35 39 … … 38 42 { 39 43 VBoxDevice *dev = pvData; 40 wait_event_interruptible (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE); 41 } 42 43 static DECLVBGL(void) 44 vboxadd_hgcm_callback_timeout (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data) 45 { 46 VBoxDevice *dev = pvData; 47 wait_event_interruptible_timeout (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE, 48 msecs_to_jiffies (u32Data)); 44 if (u32Data == RT_INDEFINITE_WAIT) 45 wait_event_interruptible (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE); 46 else 47 wait_event_interruptible_timeout (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE, 48 msecs_to_jiffies (u32Data)); 49 49 } 50 50 … … 56 56 if ( VBOXGUEST_IOCTL_STRIP_SIZE(func) 57 57 == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0))) 58 rc = VbglHGCMCall (data, vboxadd_hgcm_callback_interruptible, opaque, 0);58 rc = VbglHGCMCall (data, vboxadd_hgcm_callback_interruptible, opaque, RT_INDEFINITE_WAIT); 59 59 /* this function can handle cancelled requests */ 60 60 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(func) 61 == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT(0)))61 == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0))) 62 62 { 63 VBoxGuestHGCMCallInfoTimeout *pCallInfo; 64 pCallInfo = (VBoxGuestHGCMCallInfoTimeout *) data; 65 rc = VbglHGCMCall (&pCallInfo->info, vboxadd_hgcm_callback_timeout, 66 opaque, pCallInfo->u32Timeout); 63 VBoxGuestHGCMCallInfoTimed *pCallInfo; 64 pCallInfo = (VBoxGuestHGCMCallInfoTimed *) data; 65 if (pCallInfo->fInterruptible) 66 rc = VbglHGCMCall (&pCallInfo->info, vboxadd_hgcm_callback_interruptible, 67 opaque, pCallInfo->u32Timeout); 68 else 69 rc = VbglHGCMCall (&pCallInfo->info, vboxadd_hgcm_callback, 70 opaque, pCallInfo->u32Timeout); 67 71 } 68 72 else switch (func) … … 70 74 /* this function can NOT handle cancelled requests */ 71 75 case VBOXGUEST_IOCTL_HGCM_CONNECT: 72 rc = VbglHGCMConnect (data, vboxadd_hgcm_callback, opaque, 0);76 rc = VbglHGCMConnect (data, vboxadd_hgcm_callback, opaque, RT_INDEFINITE_WAIT); 73 77 break; 74 78 75 79 /* this function can NOT handle cancelled requests */ 76 80 case VBOXGUEST_IOCTL_HGCM_DISCONNECT: 77 rc = VbglHGCMDisconnect (data, vboxadd_hgcm_callback, opaque, 0);81 rc = VbglHGCMDisconnect (data, vboxadd_hgcm_callback, opaque, RT_INDEFINITE_WAIT); 78 82 break; 79 83 -
trunk/src/VBox/Additions/linux/module/vboxmod.c
r14218 r14352 420 420 * @param u32Size the size of the userspace structure 421 421 */ 422 static int vboxadd_hgcm_call_time out(unsigned long userspace_info,422 static int vboxadd_hgcm_call_timed(unsigned long userspace_info, 423 423 uint32_t u32Size) 424 424 { 425 VBoxGuestHGCMCallInfoTime out*pInfo = NULL;425 VBoxGuestHGCMCallInfoTimed *pInfo = NULL; 426 426 int rc = 0; 427 427 … … 445 445 LogRelFunc(("client ID %u\n", pInfo->info.u32ClientID)); 446 446 vrc = vboxadd_cmc_call(vboxDev, 447 VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT(u32Size), pInfo);447 VBOXGUEST_IOCTL_HGCM_CALL_TIMED(u32Size), pInfo); 448 448 rc = -RTErrConvertToErrno(vrc); 449 449 if ( rc >= 0 … … 624 624 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL", arg); 625 625 } 626 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT(0))626 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0)) 627 627 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 628 628 { 629 629 /* Do the HGCM call using the Vbgl bits */ 630 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT", arg);631 rc = vboxadd_hgcm_call_time out(arg, _IOC_SIZE(cmd));632 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIME OUT", arg);630 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 631 rc = vboxadd_hgcm_call_timed(arg, _IOC_SIZE(cmd)); 632 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 633 633 } 634 634 else
Note:
See TracChangeset
for help on using the changeset viewer.