儲存庫 vbox 的更動 59832
- 時間撮記:
- 2016-2-26 上午10:16:31 (9 年 以前)
- 位置:
- trunk/src/VBox/HostServices/DragAndDrop
- 檔案:
-
- 修改 2 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp
r58212 r59832 5 5 6 6 /* 7 * Copyright (C) 2011-201 5Oracle Corporation7 * Copyright (C) 2011-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 41 41 int DnDManager::addMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fAppend /* = true */) 42 42 { 43 int rc = VINF_SUCCESS; 44 45 LogFlowFunc(("uMsg=%RU32, cParms=%RU32, fAppend=%RTbool\n", uMsg, cParms, fAppend)); 43 int rc; 46 44 47 45 try 48 46 { 49 DnDMessage *pMessage = NULL; 50 51 switch (uMsg) 52 { 53 case DragAndDropSvc::HOST_DND_HG_EVT_ENTER: 54 { 55 clear(); 56 LogFlowFunc(("HOST_DND_HG_EVT_ENTER\n")); 57 break; 58 } 59 60 case DragAndDropSvc::HOST_DND_HG_EVT_MOVE: 61 { 62 LogFlowFunc(("HOST_DND_HG_EVT_MOVE\n")); 63 break; 64 } 65 66 case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE: 67 { 68 LogFlowFunc(("HOST_DND_HG_EVT_LEAVE\n")); 69 break; 70 } 71 72 case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED: 73 { 74 LogFlowFunc(("HOST_DND_HG_EVT_DROPPED\n")); 75 break; 76 } 77 78 case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL: 79 { 80 LogFlowFunc(("HOST_DND_HG_EVT_CANCEL\n")); 81 82 pMessage = new DnDHGCancelMessage(); 83 break; 84 } 85 86 case DragAndDropSvc::HOST_DND_HG_SND_DATA_HDR: 87 { 88 LogFlowFunc(("HOST_DND_HG_SND_DATA_HDR\n")); 89 break; 90 } 91 92 case DragAndDropSvc::HOST_DND_HG_SND_DATA: 93 { 94 LogFlowFunc(("HOST_DND_HG_SND_DATA\n")); 95 break; 96 } 97 98 case DragAndDropSvc::HOST_DND_HG_SND_DIR: 99 { 100 LogFlowFunc(("HOST_DND_HG_SND_DIR\n")); 101 break; 102 } 103 104 /* New since protocol version 2 (VBox 5.0). */ 105 case DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR: 106 { 107 LogFlowFunc(("HOST_DND_HG_SND_FILE_HDR\n")); 108 break; 109 } 110 111 case DragAndDropSvc::HOST_DND_HG_SND_FILE_DATA: 112 { 113 LogFlowFunc(("HOST_DND_HG_SND_FILE\n")); 114 115 /* No parameter verification here as, depending on the protocol version 116 * being used, the parameter count + types might change. */ 117 break; 118 } 119 120 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 121 case DragAndDropSvc::HOST_DND_GH_REQ_PENDING: 122 { 123 LogFlowFunc(("HOST_DND_GH_REQ_PENDING\n")); 124 break; 125 } 126 127 case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED: 128 { 129 LogFlowFunc(("HOST_DND_GH_EVT_DROPPED\n")); 130 break; 131 } 132 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 133 134 default: 135 rc = VERR_NOT_IMPLEMENTED; 136 break; 137 } 138 139 if (RT_SUCCESS(rc)) 140 { 141 if (!pMessage) /* Generic message needed? */ 142 pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 143 144 if (fAppend) 145 m_dndMessageQueue.append(pMessage); 146 else 147 m_dndMessageQueue.prepend(pMessage); 148 } 47 LogFlowFunc(("uMsg=%RU32, cParms=%RU32, fAppend=%RTbool\n", uMsg, cParms, fAppend)); 48 49 DnDMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 50 if (fAppend) 51 m_dndMessageQueue.append(pMessage); 52 else 53 m_dndMessageQueue.prepend(pMessage); 54 55 rc = VINF_SUCCESS; 149 56 } 150 57 catch(std::bad_alloc &) … … 153 60 } 154 61 62 LogFlowFuncLeaveRC(rc); 155 63 return rc; 156 64 } … … 254 162 void DnDManager::clear(void) 255 163 { 164 LogFlowFuncEnter(); 165 256 166 if (m_pCurMsg) 257 167 { -
trunk/src/VBox/HostServices/DragAndDrop/service.cpp
r58329 r59832 5 5 6 6 /* 7 * Copyright (C) 2011-201 5Oracle Corporation7 * Copyright (C) 2011-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 184 184 RT_ZERO(data); 185 185 /** @todo Magic needed? */ 186 /** @todo Add context ID. */ 186 187 187 188 if (m_SvcCtx.pfnHostCallback) … … 987 988 } 988 989 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 990 991 /* 992 * Note: This is a fire-and-forget message, as the host should 993 * not rely on an answer from the guest side in order to 994 * properly cancel the operation. 995 */ 996 case HOST_DND_HG_EVT_CANCEL: 997 { 998 LogFlowFunc(("HOST_DND_HG_EVT_CANCEL\n")); 999 1000 VBOXDNDCBEVTERRORDATA data; 1001 RT_ZERO(data); 1002 data.hdr.uMagic = CB_MAGIC_DND_GH_EVT_ERROR; 1003 1004 switch (pClient->protocol()) 1005 { 1006 case 3: 1007 { 1008 /* Protocol v3+ at least requires the context ID. */ 1009 if (cParms == 1) 1010 rc = paParms[0].getUInt32(&data.hdr.uContextID); 1011 1012 break; 1013 } 1014 1015 default: 1016 break; 1017 } 1018 1019 /* Tell the host that the guest has cancelled the operation. */ 1020 data.rc = VERR_CANCELLED; 1021 1022 DO_HOST_CALLBACK(); 1023 1024 /* Note: If the host is not prepared for handling the cancelling reply 1025 * from the guest, don't report this back to the guest. */ 1026 if (RT_FAILURE(rc)) 1027 rc = VINF_SUCCESS; 1028 break; 1029 } 1030 989 1031 default: 990 1032 { … … 997 1039 VBOXDNDCBHGGETNEXTHOSTMSGDATA data; 998 1040 RT_ZERO(data); 1041 999 1042 data.hdr.uMagic = VBOX_DND_CB_MAGIC_MAKE(0 /* uFn */, 0 /* uVer */); 1043 1000 1044 data.uMsg = u32Function; 1001 1045 data.cParms = cParms; … … 1008 1052 cParms = data.cParms; 1009 1053 paParms = data.paParms; 1054 } 1055 else 1056 { 1057 /* 1058 * In case the guest is too fast asking for the next message 1059 * and the host did not supply it yet, just defer the client's 1060 * return until a response from the host available. 1061 */ 1062 LogFlowFunc(("No new messages from the host (yet), deferring request: %Rrc\n", rc)); 1063 rc = VINF_HGCM_ASYNC_EXECUTE; 1010 1064 } 1011 1065 } … … 1040 1094 pClient->complete(callHandle, rc); 1041 1095 else 1096 { 1097 AssertMsgFailed(("Guest call failed with %Rrc\n", rc)); 1042 1098 rc = VERR_NOT_IMPLEMENTED; 1099 } 1043 1100 1044 1101 LogFlowFunc(("Returning rc=%Rrc\n", rc)); … … 1052 1109 1053 1110 int rc; 1054 if (u32Function == HOST_DND_SET_MODE) 1055 { 1056 if (cParms != 1) 1057 rc = VERR_INVALID_PARAMETER; 1058 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT) 1059 rc = VERR_INVALID_PARAMETER; 1060 else 1061 rc = modeSet(paParms[0].u.uint32); 1062 } 1063 else if (modeGet() != VBOX_DRAG_AND_DROP_MODE_OFF) 1064 { 1065 if (m_clientMap.size()) /* At least one client on the guest connected? */ 1111 1112 do 1113 { 1114 bool fSendToGuest = false; /* Whether to send the message down to the guest side or not. */ 1115 1116 switch (u32Function) 1066 1117 { 1118 case HOST_DND_SET_MODE: 1119 { 1120 if (cParms != 1) 1121 rc = VERR_INVALID_PARAMETER; 1122 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT) 1123 rc = VERR_INVALID_PARAMETER; 1124 else 1125 rc = modeSet(paParms[0].u.uint32); 1126 break; 1127 } 1128 1129 case HOST_DND_HG_EVT_ENTER: 1130 { 1131 /* Clear the message queue as a new DnD operation just began. */ 1132 m_pManager->clear(); 1133 1134 fSendToGuest = true; 1135 break; 1136 } 1137 1138 case HOST_DND_HG_EVT_CANCEL: 1139 { 1140 LogFlowFunc(("Cancelling all waiting clients ...\n")); 1141 1142 /* Clear the message queue as the host cancelled the whole operation. */ 1143 m_pManager->clear(); 1144 1145 /* 1146 * Wake up all deferred clients and tell them to process 1147 * the cancelling message next. 1148 */ 1149 DnDClientQueue::iterator itQueue = m_clientQueue.begin(); 1150 while (itQueue != m_clientQueue.end()) 1151 { 1152 DnDClientMap::iterator itClient = m_clientMap.find(*itQueue); 1153 Assert(itClient != m_clientMap.end()); 1154 1155 DragAndDropClient *pClient = itClient->second; 1156 AssertPtr(pClient); 1157 1158 int rc2 = pClient->addMessageInfo(HOST_DND_HG_EVT_CANCEL, 1159 /* Protocol v3+ also contains the context ID. */ 1160 pClient->protocol() >= 3 ? 1 : 0); 1161 pClient->completeDeferred(rc2); 1162 1163 m_clientQueue.erase(itQueue); 1164 itQueue = m_clientQueue.begin(); 1165 } 1166 1167 Assert(m_clientQueue.size() == 0); 1168 1169 /* Tell the host that everything went well. */ 1170 rc = VINF_SUCCESS; 1171 break; 1172 } 1173 1174 default: 1175 { 1176 fSendToGuest = true; 1177 break; 1178 } 1179 } 1180 1181 if (fSendToGuest) 1182 { 1183 if (modeGet() == VBOX_DRAG_AND_DROP_MODE_OFF) 1184 { 1185 /* Tell the host that a wrong drag'n drop mode is set. */ 1186 rc = VERR_ACCESS_DENIED; 1187 break; 1188 } 1189 1190 if (m_clientMap.size() == 0) /* At least one client on the guest connected? */ 1191 { 1192 /* 1193 * Tell the host that the guest does not support drag'n drop. 1194 * This might happen due to not installed Guest Additions or 1195 * not running VBoxTray/VBoxClient. 1196 */ 1197 rc = VERR_NOT_SUPPORTED; 1198 break; 1199 } 1200 1067 1201 rc = m_pManager->addMessage(u32Function, cParms, paParms, true /* fAppend */); 1068 if (RT_SUCCESS(rc)) 1069 { 1070 if (m_clientQueue.size()) /* Any clients in our queue ready for processing the next command? */ 1071 { 1072 uint32_t uClientNext = m_clientQueue.front(); 1073 DnDClientMap::iterator itClientNext = m_clientMap.find(uClientNext); 1074 Assert(itClientNext != m_clientMap.end()); 1075 1076 DragAndDropClient *pClient = itClientNext->second; 1077 AssertPtr(pClient); 1078 1079 /* 1080 * Check if this was a request for getting the next host 1081 * message. If so, return the message ID and the parameter 1082 * count. The message itself has to be queued. 1083 */ 1084 uint32_t uMsg = pClient->message(); 1085 if (uMsg == GUEST_DND_GET_NEXT_HOST_MSG) 1086 { 1087 LogFlowFunc(("Client %RU32 is waiting for next host msg\n", pClient->clientId())); 1088 1089 uint32_t uMsg1; 1090 uint32_t cParms1; 1091 rc = m_pManager->nextMessageInfo(&uMsg1, &cParms1); 1092 if (RT_SUCCESS(rc)) 1093 { 1094 rc = pClient->addMessageInfo(uMsg1, cParms1); 1095 1096 /* Note: Report the current rc back to the guest. */ 1097 pClient->completeDeferred(rc); 1098 1099 m_clientQueue.pop_front(); 1100 } 1101 } 1102 else 1103 AssertMsgFailed(("Client ID=%RU32 in wrong state with uMsg=%RU32\n", 1104 pClient->clientId(), uMsg)); 1105 } 1106 else 1107 LogFlowFunc(("All clients busy; delaying execution\n")); 1108 } 1109 else 1110 AssertMsgFailed(("Adding new message of type=%RU32 failed with rc=%Rrc\n", 1111 u32Function, rc)); 1112 } 1113 else 1114 { 1202 if (RT_FAILURE(rc)) 1203 { 1204 AssertMsgFailed(("Adding new message of type=%RU32 failed with rc=%Rrc\n", u32Function, rc)); 1205 break; 1206 } 1207 1208 /* Any clients in our queue ready for processing the next command? */ 1209 if (m_clientQueue.size() == 0) 1210 { 1211 LogFlowFunc(("All clients (%zu) busy -- delaying execution\n", m_clientMap.size())); 1212 break; 1213 } 1214 1215 uint32_t uClientNext = m_clientQueue.front(); 1216 DnDClientMap::iterator itClientNext = m_clientMap.find(uClientNext); 1217 Assert(itClientNext != m_clientMap.end()); 1218 1219 DragAndDropClient *pClient = itClientNext->second; 1220 AssertPtr(pClient); 1221 1115 1222 /* 1116 * Tell the host that the guest does not support drag'n drop.1117 * This might happen due to not installed Guest Additions or1118 * not running VBoxTray/VBoxClient.1223 * Check if this was a request for getting the next host 1224 * message. If so, return the message ID and the parameter 1225 * count. The message itself has to be queued. 1119 1226 */ 1120 rc = VERR_NOT_SUPPORTED; 1121 } 1122 } 1123 else 1124 { 1125 /* Tell the host that a wrong drag'n drop mode is set. */ 1126 rc = VERR_ACCESS_DENIED; 1127 } 1227 uint32_t uMsgClient = pClient->message(); 1228 1229 uint32_t uMsgNext = 0; 1230 uint32_t cParmsNext = 0; 1231 int rcNext = m_pManager->nextMessageInfo(&uMsgNext, &cParmsNext); 1232 1233 LogFlowFunc(("uMsgClient=%RU32, uMsgNext=%RU32, cParmsNext=%RU32, rcNext=%Rrc\n", 1234 uMsgClient, uMsgNext, cParmsNext, rcNext)); 1235 1236 if (RT_SUCCESS(rcNext)) 1237 { 1238 if (uMsgClient == GUEST_DND_GET_NEXT_HOST_MSG) 1239 { 1240 rc = pClient->addMessageInfo(uMsgNext, cParmsNext); 1241 1242 /* Note: Report the current rc back to the guest. */ 1243 pClient->completeDeferred(rc); 1244 1245 m_clientQueue.pop_front(); 1246 } 1247 /* 1248 * Does the message the client is waiting for match the message 1249 * next in the queue? Process it right away then. 1250 */ 1251 else if (uMsgClient == uMsgNext) 1252 { 1253 rc = m_pManager->nextMessage(u32Function, cParms, paParms); 1254 1255 /* Note: Report the current rc back to the guest. */ 1256 pClient->completeDeferred(rc); 1257 } 1258 else /* Should not happen. */ 1259 AssertMsgFailed(("Client ID=%RU32 in wrong state with uMsg=%RU32 (next message in queue: %RU32)\n", 1260 pClient->clientId(), uMsgClient, uMsgNext)); 1261 } 1262 1263 } /* fSendToGuest */ 1264 1265 } while (0); /* To use breaks. */ 1128 1266 1129 1267 LogFlowFuncLeaveRC(rc);
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器