Changeset 85318 in vbox
- Timestamp:
- Jul 13, 2020 9:07:41 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
include/VBox/HostServices/Service.h (modified) (14 diffs)
-
src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.cpp (modified) (23 diffs)
-
src/VBox/HostServices/common/client.cpp (modified) (16 diffs)
-
src/VBox/HostServices/common/message.cpp (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/HostServices/Service.h
r85121 r85318 30 30 #endif 31 31 32 #include <memory> /* for auto_ptr */33 34 32 #include <VBox/log.h> 35 33 #include <VBox/hgcmsvc.h> … … 39 37 #include <iprt/cpp/utils.h> 40 38 39 #include <new> 40 41 41 42 42 namespace HGCM … … 50 50 /** HGCM helper functions. */ 51 51 PVBOXHGCMSVCHELPERS pHelpers; 52 /* 52 /** 53 53 * Callback function supplied by the host for notification of updates 54 54 * to properties. … … 65 65 { 66 66 public: 67 68 67 Message(void); 69 70 68 Message(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]); 71 72 69 virtual ~Message(void); 73 70 74 uint32_t GetParamCount(void) const; 75 76 int GetData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) const; 77 78 int GetParmU32(uint32_t uParm, uint32_t *pu32Info) const; 79 80 int GetParmU64(uint32_t uParm, uint64_t *pu64Info) const; 81 82 int GetParmPtr(uint32_t uParm, void **ppvAddr, uint32_t *pcbSize) const; 83 84 uint32_t GetType(void) const; 85 86 public: 87 88 static int CopyParms(PVBOXHGCMSVCPARM paParmsDst, uint32_t cParmsDst, 89 PVBOXHGCMSVCPARM paParmsSrc, uint32_t cParmsSrc, 90 bool fDeepCopy); 91 92 protected: 93 94 int initData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]); 95 96 void reset(); 71 uint32_t GetParamCount(void) const RT_NOEXCEPT; 72 int GetData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) const RT_NOEXCEPT; 73 int GetParmU32(uint32_t uParm, uint32_t *pu32Info) const RT_NOEXCEPT; 74 int GetParmU64(uint32_t uParm, uint64_t *pu64Info) const RT_NOEXCEPT; 75 int GetParmPtr(uint32_t uParm, void **ppvAddr, uint32_t *pcbSize) const RT_NOEXCEPT; 76 uint32_t GetType(void) const RT_NOEXCEPT; 77 78 public: 79 static int CopyParms(PVBOXHGCMSVCPARM paParmsDst, uint32_t cParmsDst, 80 PVBOXHGCMSVCPARM paParmsSrc, uint32_t cParmsSrc, 81 bool fDeepCopy) RT_NOEXCEPT; 82 83 protected: 84 int initData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) RT_NOEXCEPT; 85 void reset() RT_NOEXCEPT; 97 86 98 87 protected: … … 112 101 { 113 102 public: 114 115 Client(uint32_t uClientID); 116 103 Client(uint32_t idClient); 117 104 virtual ~Client(void); 118 105 119 106 public: 120 121 int Complete(VBOXHGCMCALLHANDLE hHandle, int rcOp = VINF_SUCCESS); 122 123 int CompleteDeferred(int rcOp = VINF_SUCCESS); 124 125 uint32_t GetClientID(void) const; 126 127 VBOXHGCMCALLHANDLE GetHandle(void) const; 128 129 uint32_t GetMsgType(void) const; 130 131 uint32_t GetMsgParamCount(void) const; 132 133 uint32_t GetProtocolVer(void) const; 134 135 bool IsDeferred(void) const; 136 137 void SetDeferred(VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 138 139 void SetProtocolVer(uint32_t uVersion); 140 141 void SetSvcContext(const VBOXHGCMSVCTX &SvcCtx); 142 143 public: 144 145 int SetDeferredMsgInfo(uint32_t uMsg, uint32_t cParms); 146 147 int SetDeferredMsgInfo(const Message *pMessage); 148 149 protected: 150 151 int completeInternal(VBOXHGCMCALLHANDLE hHandle, int rcOp); 152 153 void reset(void); 154 155 protected: 156 107 int Complete(VBOXHGCMCALLHANDLE hHandle, int rcOp = VINF_SUCCESS) RT_NOEXCEPT; 108 int CompleteDeferred(int rcOp = VINF_SUCCESS) RT_NOEXCEPT; 109 uint32_t GetClientID(void) const RT_NOEXCEPT; 110 VBOXHGCMCALLHANDLE GetHandle(void) const RT_NOEXCEPT; 111 uint32_t GetMsgType(void) const RT_NOEXCEPT; 112 uint32_t GetMsgParamCount(void) const RT_NOEXCEPT; 113 uint32_t GetProtocolVer(void) const RT_NOEXCEPT; 114 bool IsDeferred(void) const RT_NOEXCEPT; 115 void SetDeferred(VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT; 116 void SetProtocolVer(uint32_t uVersion) RT_NOEXCEPT; 117 void SetSvcContext(const VBOXHGCMSVCTX &SvcCtx) RT_NOEXCEPT; 118 119 public: 120 int SetDeferredMsgInfo(uint32_t uMsg, uint32_t cParms) RT_NOEXCEPT; 121 int SetDeferredMsgInfo(const Message *pMessage) RT_NOEXCEPT; 122 123 protected: 124 int completeInternal(VBOXHGCMCALLHANDLE hHandle, int rcOp) RT_NOEXCEPT; 125 void reset(void) RT_NOEXCEPT; 126 127 protected: 157 128 /** The client's HGCM client ID. */ 158 uint32_t m_uClientID; 159 /** Optional protocol version the client uses. Set to 0 by default. */ 129 uint32_t m_idClient; 130 /** Optional protocol version the client uses. Set to 0 by default. 131 * @todo r=bird: This does not belong here. Whether a service has a "protocol 132 * version" isn't given and I've argued that it's an inflexible bad idea. */ 160 133 uint32_t m_uProtocolVer; 161 134 /** The HGCM service context this client is bound to. */ … … 172 145 /** The client's HGCM call handle. Needed for completing a deferred call. */ 173 146 VBOXHGCMCALLHANDLE hHandle; 174 /** Message type (function number) to use when completing the deferred call. */ 147 /** Message type (function number) to use when completing the deferred call. 148 * @todo r=bird: uType or uMsg? Make up your mind (Message::m_uMsg). */ 175 149 uint32_t uType; 176 150 /** Parameter count to use when completing the deferred call. */ … … 204 178 else 205 179 { 206 RT_GCC_NO_WARN_DEPRECATED_BEGIN 207 std::auto_ptr<AbstractService> apService; 208 /* No exceptions may propagate outside. */ 209 try 210 { 211 apService = std::auto_ptr<AbstractService>(new T(pTable->pHelpers)); 212 } catch (int rcThrown) 213 { 214 rc = rcThrown; 215 } catch (...) 216 { 217 rc = VERR_UNRESOLVED_ERROR; 218 } 219 RT_GCC_NO_WARN_DEPRECATED_END 180 AbstractService *pService = NULL; 181 /* No exceptions may propagate outside (callbacks like this one are nothrow/noexcept). */ 182 try { pService = new T(pTable->pHelpers); } 183 catch (std::bad_alloc &) { rc = VERR_NO_MEMORY; } 184 catch (...) { rc = VERR_UNEXPECTED_EXCEPTION; } 220 185 if (RT_SUCCESS(rc)) 221 186 { 222 /* 223 * We don't need an additional client data area on the host, 224 * because we're a class which can have members for that :-). 225 */ 226 pTable->cbClient = 0; 187 /* We don't need an additional client data area on the host, 188 because we're a class which can have members for that :-). */ 189 pTable->cbClient = 0; 227 190 228 191 /* These functions are mandatory */ … … 238 201 239 202 /* Let the service itself initialize. */ 240 rc = apService->init(pTable); 241 242 /* Only on success stop the auto release of the auto_ptr. */ 203 rc = pService->init(pTable); 243 204 if (RT_SUCCESS(rc)) 244 pTable->pvService = apService.release(); 205 pTable->pvService = pService; 206 else 207 delete pService; 245 208 } 246 209 } … … 258 221 m_SvcCtx.pHelpers = pHelpers; 259 222 } 260 virtual int init(VBOXHGCMSVCFNTABLE *ptable) { RT_NOREF1(ptable); return VINF_SUCCESS; } 261 virtual int uninit() { return VINF_SUCCESS; } 262 virtual int clientConnect(uint32_t u32ClientID, void *pvClient) = 0; 263 virtual int clientDisconnect(uint32_t u32ClientID, void *pvClient) = 0; 264 virtual void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) = 0; 265 virtual int hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 223 virtual int init(VBOXHGCMSVCFNTABLE *ptable) RT_NOEXCEPT 224 { RT_NOREF1(ptable); return VINF_SUCCESS; } 225 virtual int uninit() RT_NOEXCEPT 226 { return VINF_SUCCESS; } 227 virtual int clientConnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT = 0; 228 virtual int clientDisconnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT = 0; 229 virtual void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t idClient, void *pvClient, uint32_t eFunction, 230 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT = 0; 231 virtual int hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT 266 232 { RT_NOREF3(eFunction, cParms, paParms); return VINF_SUCCESS; } 267 233 … … 291 257 */ 292 258 static DECLCALLBACK(int) svcConnect(void *pvService, 293 uint32_t u32ClientID,259 uint32_t idClient, 294 260 void *pvClient, 295 261 uint32_t fRequestor, … … 298 264 RT_NOREF(fRequestor, fRestoring); 299 265 AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER); 300 LogFlowFunc(("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient));301 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 302 int rc = pSelf->clientConnect( u32ClientID, pvClient);266 LogFlowFunc(("pvService=%p, idClient=%u, pvClient=%p\n", pvService, idClient, pvClient)); 267 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 268 int rc = pSelf->clientConnect(idClient, pvClient); 303 269 LogFlowFunc(("rc=%Rrc\n", rc)); 304 270 return rc; … … 310 276 */ 311 277 static DECLCALLBACK(int) svcDisconnect(void *pvService, 312 uint32_t u32ClientID,278 uint32_t idClient, 313 279 void *pvClient) 314 280 { 315 281 AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER); 316 LogFlowFunc(("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient));317 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 318 int rc = pSelf->clientDisconnect( u32ClientID, pvClient);282 LogFlowFunc(("pvService=%p, idClient=%u, pvClient=%p\n", pvService, idClient, pvClient)); 283 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 284 int rc = pSelf->clientDisconnect(idClient, pvClient); 319 285 LogFlowFunc(("rc=%Rrc\n", rc)); 320 286 return rc; … … 325 291 * Wraps to the call member function 326 292 */ 327 static DECLCALLBACK(void) svcCall(void * pvService,293 static DECLCALLBACK(void) svcCall(void *pvService, 328 294 VBOXHGCMCALLHANDLE callHandle, 329 uint32_t u32ClientID,295 uint32_t idClient, 330 296 void *pvClient, 331 297 uint32_t u32Function, … … 335 301 { 336 302 AssertLogRelReturnVoid(VALID_PTR(pvService)); 337 LogFlowFunc(("pvService=%p, callHandle=%p, u32ClientID=%u, pvClient=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, callHandle, u32ClientID, pvClient, u32Function, cParms, paParms)); 338 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 339 pSelf->guestCall(callHandle, u32ClientID, pvClient, u32Function, cParms, paParms); 303 LogFlowFunc(("pvService=%p, callHandle=%p, idClient=%u, pvClient=%p, u32Function=%u, cParms=%u, paParms=%p\n", 304 pvService, callHandle, idClient, pvClient, u32Function, cParms, paParms)); 305 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 306 pSelf->guestCall(callHandle, idClient, pvClient, u32Function, cParms, paParms); 340 307 LogFlowFunc(("returning\n")); 341 308 RT_NOREF_PV(tsArrival); -
trunk/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.cpp
r85145 r85318 50 50 { 51 51 public: 52 53 DragAndDropClient(uint32_t uClientID) 54 : HGCM::Client(uClientID) 52 DragAndDropClient(uint32_t idClient) 53 : HGCM::Client(idClient) 55 54 { 56 55 RT_ZERO(m_SvcCtx); … … 63 62 64 63 public: 65 66 void disconnect(void); 64 void disconnect(void) RT_NOEXCEPT; 67 65 }; 68 66 … … 79 77 { 80 78 public: 81 82 79 explicit DragAndDropService(PVBOXHGCMSVCHELPERS pHelpers) 83 80 : HGCM::AbstractService<DragAndDropService>(pHelpers) 84 , m_pManager(NULL) {} 81 , m_pManager(NULL) 82 , m_u32Mode(VBOX_DRAG_AND_DROP_MODE_OFF) 83 {} 85 84 86 85 protected: 87 88 int init(VBOXHGCMSVCFNTABLE *pTable);89 int uninit(void);90 int client Connect(uint32_t u32ClientID, void *pvClient);91 int clientDisconnect(uint32_t u32ClientID, void *pvClient);92 void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);93 int hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) ;94 95 int modeSet(uint32_t u32Mode); 96 in line uint32_t modeGet(void) const { return m_u32Mode; };97 98 protected: 86 int init(VBOXHGCMSVCFNTABLE *pTable) RT_NOEXCEPT RT_OVERRIDE; 87 int uninit(void) RT_NOEXCEPT RT_OVERRIDE; 88 int clientConnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT RT_OVERRIDE; 89 int clientDisconnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT RT_OVERRIDE; 90 void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t idClient, void *pvClient, uint32_t u32Function, 91 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT RT_OVERRIDE; 92 int hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT RT_OVERRIDE; 93 94 private: 95 int modeSet(uint32_t u32Mode) RT_NOEXCEPT; 96 inline uint32_t modeGet(void) const RT_NOEXCEPT 97 { return m_u32Mode; }; 99 98 100 99 static DECLCALLBACK(int) progressCallback(uint32_t uStatus, uint32_t uPercentage, int rc, void *pvUser); 101 100 102 protected: 103 101 private: 104 102 /** Pointer to our DnD manager instance. */ 105 103 DnDManager *m_pManager; … … 112 110 * to process new commands. The key is the (unique) client ID. */ 113 111 DnDClientQueue m_clientQueue; 114 /** Current drag and drop mode . */112 /** Current drag and drop mode, VBOX_DRAG_AND_DROP_MODE_XXX. */ 115 113 uint32_t m_u32Mode; 116 114 }; … … 123 121 /** 124 122 * Called when the HGCM client disconnected on the guest side. 123 * 125 124 * This function takes care of the client's data cleanup and also lets the host 126 125 * know that the client has been disconnected. 127 *128 126 */ 129 void DragAndDropClient::disconnect(void) 127 void DragAndDropClient::disconnect(void) RT_NOEXCEPT 130 128 { 131 LogFlowThisFunc(("uClient=%RU32\n", m_ uClientID));129 LogFlowThisFunc(("uClient=%RU32\n", m_idClient)); 132 130 133 131 if (IsDeferred()) … … 146 144 int rc2 = m_SvcCtx.pfnHostCallback(m_SvcCtx.pvHostData, GUEST_DND_DISCONNECT, &data, sizeof(data)); 147 145 if (RT_FAILURE(rc2)) 148 LogFlowFunc(("Warning: Unable to notify host about client %RU32 disconnect, rc=%Rrc\n", m_ uClientID, rc2));146 LogFlowFunc(("Warning: Unable to notify host about client %RU32 disconnect, rc=%Rrc\n", m_idClient, rc2)); 149 147 /* Not fatal. */ 150 148 } … … 156 154 *********************************************************************************************************************************/ 157 155 158 int DragAndDropService::init(VBOXHGCMSVCFNTABLE *pTable) 156 int DragAndDropService::init(VBOXHGCMSVCFNTABLE *pTable) RT_NOEXCEPT 159 157 { 160 158 /* Register functions. */ … … 174 172 m_pManager = new DnDManager(&DragAndDropService::progressCallback, this); 175 173 } 176 catch (std::bad_alloc &)174 catch (std::bad_alloc &) 177 175 { 178 176 rc = VERR_NO_MEMORY; … … 183 181 } 184 182 185 int DragAndDropService::uninit(void) 183 int DragAndDropService::uninit(void) RT_NOEXCEPT 186 184 { 187 185 LogFlowFuncEnter(); … … 205 203 } 206 204 207 int DragAndDropService::clientConnect(uint32_t u32ClientID, void *pvClient)205 int DragAndDropService::clientConnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT 208 206 { 209 207 RT_NOREF1(pvClient); … … 214 212 } 215 213 216 int rc = VINF_SUCCESS;217 214 218 215 /* 219 216 * Add client to our client map. 220 217 */ 221 if (m_clientMap.find(u32ClientID) != m_clientMap.end()) 222 rc = VERR_ALREADY_EXISTS; 223 224 if (RT_SUCCESS(rc)) 225 { 226 try 227 { 228 DragAndDropClient *pClient = new DragAndDropClient(u32ClientID); 229 pClient->SetSvcContext(m_SvcCtx); 230 m_clientMap[u32ClientID] = pClient; 231 } 232 catch(std::bad_alloc &) 233 { 234 rc = VERR_NO_MEMORY; 235 } 236 237 if (RT_SUCCESS(rc)) 238 { 239 /* 240 * Reset the message queue as soon as a new clients connect 241 * to ensure that every client has the same state. 242 */ 243 if (m_pManager) 244 m_pManager->Reset(); 245 } 246 } 247 248 LogFlowFunc(("Client %RU32 connected, rc=%Rrc\n", u32ClientID, rc)); 249 return rc; 218 if (m_clientMap.find(idClient) != m_clientMap.end()) 219 { 220 LogFunc(("Client %RU32 is already connected!\n", idClient)); 221 return VERR_ALREADY_EXISTS; 222 } 223 224 try 225 { 226 DragAndDropClient *pClient = new DragAndDropClient(idClient); 227 pClient->SetSvcContext(m_SvcCtx); 228 m_clientMap[idClient] = pClient; 229 } 230 catch (std::bad_alloc &) 231 { 232 LogFunc(("Client %RU32 - VERR_NO_MEMORY!\n", idClient)); 233 return VERR_NO_MEMORY; 234 } 235 236 /* 237 * Reset the message queue as soon as a new clients connect 238 * to ensure that every client has the same state. 239 */ 240 if (m_pManager) 241 m_pManager->Reset(); 242 243 LogFlowFunc(("Client %RU32 connected (VINF_SUCCESS)\n", idClient)); 244 return VINF_SUCCESS; 250 245 } 251 246 252 int DragAndDropService::clientDisconnect(uint32_t u32ClientID, void *pvClient)247 int DragAndDropService::clientDisconnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT 253 248 { 254 249 RT_NOREF1(pvClient); 255 250 256 251 /* Client not found? Bail out early. */ 257 DnDClientMap::iterator itClient = m_clientMap.find( u32ClientID);252 DnDClientMap::iterator itClient = m_clientMap.find(idClient); 258 253 if (itClient == m_clientMap.end()) 254 { 255 LogFunc(("Client %RU32 not found!\n", idClient)); 259 256 return VERR_NOT_FOUND; 257 } 260 258 261 259 /* 262 260 * Remove from waiters queue. 263 261 */ 264 m_clientQueue.remove( u32ClientID);262 m_clientQueue.remove(idClient); 265 263 266 264 /* … … 272 270 m_clientMap.erase(itClient); 273 271 274 LogFlowFunc(("Client %RU32 disconnected\n", u32ClientID));272 LogFlowFunc(("Client %RU32 disconnected\n", idClient)); 275 273 return VINF_SUCCESS; 276 274 } 277 275 278 int DragAndDropService::modeSet(uint32_t u32Mode) 276 int DragAndDropService::modeSet(uint32_t u32Mode) RT_NOEXCEPT 279 277 { 280 278 #ifndef VBOX_WITH_DRAG_AND_DROP_GH … … 304 302 } 305 303 306 void DragAndDropService::guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,304 void DragAndDropService::guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t idClient, 307 305 void *pvClient, uint32_t u32Function, 308 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 306 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT 309 307 { 310 308 RT_NOREF1(pvClient); 311 LogFlowFunc(("u32ClientID=%RU32, u32Function=%RU32, cParms=%RU32\n", 312 u32ClientID, u32Function, cParms)); 309 LogFlowFunc(("idClient=%RU32, u32Function=%RU32, cParms=%RU32\n", idClient, u32Function, cParms)); 313 310 314 311 /* Check if we've the right mode set. */ … … 319 316 { 320 317 if (modeGet() != VBOX_DRAG_AND_DROP_MODE_OFF) 321 {322 318 rc = VINF_SUCCESS; 323 }324 319 else 325 320 { … … 341 336 break; 342 337 } 338 343 339 case GUEST_DND_HG_ACK_OP: 344 340 case GUEST_DND_HG_REQ_DATA: … … 347 343 if ( modeGet() == VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL 348 344 || modeGet() == VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST) 349 {350 345 rc = VINF_SUCCESS; 351 }352 346 else 353 LogFlowFunc(("Host -> Guest DnD mode disabled, ignoring request\n"));347 LogFlowFunc(("Host -> Guest DnD mode disabled, failing request\n")); 354 348 break; 355 349 } … … 366 360 if ( modeGet() == VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL 367 361 || modeGet() == VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST) 368 {369 362 rc = VINF_SUCCESS; 370 }371 363 else 372 364 #endif 373 LogFlowFunc(("Guest -> Host DnD mode disabled, ignoring request\n"));365 LogFlowFunc(("Guest -> Host DnD mode disabled, failing request\n")); 374 366 break; 375 367 } … … 397 389 DragAndDropClient *pClient = NULL; 398 390 399 DnDClientMap::iterator itClient = m_clientMap.find( u32ClientID);391 DnDClientMap::iterator itClient = m_clientMap.find(idClient); 400 392 if (itClient != m_clientMap.end()) 401 393 { … … 405 397 else 406 398 { 407 LogFunc(("Client %RU32 was not found\n", u32ClientID));399 LogFunc(("Client %RU32 was not found\n", idClient)); 408 400 rc = VERR_NOT_FOUND; 409 401 } … … 412 404 * Will set rc to VERR_INVALID_PARAMETER otherwise. See #9777. */ 413 405 #define VERIFY_BUFFER_SIZE_UINT32(a_ParmUInt32, a_SizeExpected) \ 414 { \406 do { \ 415 407 uint32_t cbTemp = 0; \ 416 408 rc = HGCMSvcGetU32(&a_ParmUInt32, &cbTemp); \ 417 409 ASSERT_GUEST_STMT(RT_SUCCESS(rc) && cbTemp == a_SizeExpected, rc = VERR_INVALID_PARAMETER); \ 418 } 410 } while (0) 419 411 420 412 if (rc == VINF_SUCCESS) /* Note: rc might be VINF_HGCM_ASYNC_EXECUTE! */ … … 990 982 AssertPtr(pClient); 991 983 pClient->SetDeferred(callHandle, u32Function, cParms, paParms); 992 m_clientQueue.push_back( u32ClientID);984 m_clientQueue.push_back(idClient); 993 985 } 994 986 catch (std::bad_alloc &) … … 1010 1002 1011 1003 int DragAndDropService::hostCall(uint32_t u32Function, 1012 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 1004 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT 1013 1005 { 1014 1006 LogFlowFunc(("u32Function=%RU32, cParms=%RU32, cClients=%zu, cQueue=%zu\n", … … 1016 1008 1017 1009 int rc; 1018 1019 do 1020 { 1021 bool fSendToGuest = false; /* Whether to send the message down to the guest side or not. */ 1022 1023 switch (u32Function) 1010 bool fSendToGuest = false; /* Whether to send the message down to the guest side or not. */ 1011 1012 switch (u32Function) 1013 { 1014 case HOST_DND_SET_MODE: 1024 1015 { 1025 case HOST_DND_SET_MODE: 1026 { 1027 if (cParms != 1) 1028 rc = VERR_INVALID_PARAMETER; 1029 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT) 1030 rc = VERR_INVALID_PARAMETER; 1031 else 1032 rc = modeSet(paParms[0].u.uint32); 1033 break; 1034 } 1035 1036 case HOST_DND_CANCEL: 1037 { 1038 LogFlowFunc(("Cancelling all waiting clients ...\n")); 1039 1040 /* Reset the message queue as the host cancelled the whole operation. */ 1041 m_pManager->Reset(); 1042 1043 rc = m_pManager->AddMsg(u32Function, cParms, paParms, true /* fAppend */); 1044 if (RT_FAILURE(rc)) 1045 { 1046 AssertMsgFailed(("Adding new message of type=%RU32 failed with rc=%Rrc\n", u32Function, rc)); 1047 break; 1048 } 1049 1050 /* 1051 * Wake up all deferred clients and tell them to process 1052 * the cancelling message next. 1053 */ 1054 DnDClientQueue::iterator itQueue = m_clientQueue.begin(); 1055 while (itQueue != m_clientQueue.end()) 1056 { 1057 DnDClientMap::iterator itClient = m_clientMap.find(*itQueue); 1058 Assert(itClient != m_clientMap.end()); 1059 1060 DragAndDropClient *pClient = itClient->second; 1061 AssertPtr(pClient); 1062 1063 int rc2 = pClient->SetDeferredMsgInfo(HOST_DND_CANCEL, 1064 /* Protocol v3+ also contains the context ID. */ 1065 pClient->GetProtocolVer() >= 3 ? 1 : 0); 1066 pClient->CompleteDeferred(rc2); 1067 1068 m_clientQueue.erase(itQueue); 1069 itQueue = m_clientQueue.begin(); 1070 } 1071 1072 Assert(m_clientQueue.empty()); 1073 1074 /* Tell the host that everything went well. */ 1075 rc = VINF_SUCCESS; 1076 break; 1077 } 1078 1079 case HOST_DND_HG_EVT_ENTER: 1080 { 1081 /* Reset the message queue as a new DnD operation just began. */ 1082 m_pManager->Reset(); 1083 1084 fSendToGuest = true; 1085 rc = VINF_SUCCESS; 1086 break; 1087 } 1088 1089 default: 1090 { 1091 fSendToGuest = true; 1092 rc = VINF_SUCCESS; 1093 break; 1094 } 1016 if (cParms != 1) 1017 rc = VERR_INVALID_PARAMETER; 1018 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT) 1019 rc = VERR_INVALID_PARAMETER; 1020 else 1021 rc = modeSet(paParms[0].u.uint32); 1022 break; 1095 1023 } 1096 1024 1025 case HOST_DND_CANCEL: 1026 { 1027 LogFlowFunc(("Cancelling all waiting clients ...\n")); 1028 1029 /* Reset the message queue as the host cancelled the whole operation. */ 1030 m_pManager->Reset(); 1031 1032 rc = m_pManager->AddMsg(u32Function, cParms, paParms, true /* fAppend */); 1033 if (RT_FAILURE(rc)) 1034 { 1035 AssertMsgFailed(("Adding new message of type=%RU32 failed with rc=%Rrc\n", u32Function, rc)); 1036 break; 1037 } 1038 1039 /* 1040 * Wake up all deferred clients and tell them to process 1041 * the cancelling message next. 1042 */ 1043 DnDClientQueue::iterator itQueue = m_clientQueue.begin(); 1044 while (itQueue != m_clientQueue.end()) 1045 { 1046 DnDClientMap::iterator itClient = m_clientMap.find(*itQueue); 1047 Assert(itClient != m_clientMap.end()); 1048 1049 DragAndDropClient *pClient = itClient->second; 1050 AssertPtr(pClient); 1051 1052 int rc2 = pClient->SetDeferredMsgInfo(HOST_DND_CANCEL, 1053 /* Protocol v3+ also contains the context ID. */ 1054 pClient->GetProtocolVer() >= 3 ? 1 : 0); 1055 pClient->CompleteDeferred(rc2); 1056 1057 m_clientQueue.erase(itQueue); 1058 itQueue = m_clientQueue.begin(); 1059 } 1060 1061 Assert(m_clientQueue.empty()); 1062 1063 /* Tell the host that everything went well. */ 1064 rc = VINF_SUCCESS; 1065 break; 1066 } 1067 1068 case HOST_DND_HG_EVT_ENTER: 1069 { 1070 /* Reset the message queue as a new DnD operation just began. */ 1071 m_pManager->Reset(); 1072 1073 fSendToGuest = true; 1074 rc = VINF_SUCCESS; 1075 break; 1076 } 1077 1078 default: 1079 { 1080 fSendToGuest = true; 1081 rc = VINF_SUCCESS; 1082 break; 1083 } 1084 } 1085 1086 do /* goto avoidance break-loop. */ 1087 { 1097 1088 if (fSendToGuest) 1098 1089 { -
trunk/src/VBox/HostServices/common/client.cpp
r82968 r85318 27 27 using namespace HGCM; 28 28 29 Client::Client(uint32_t uClientID)30 : m_ uClientID(uClientID)29 Client::Client(uint32_t idClient) 30 : m_idClient(idClient) 31 31 , m_uProtocolVer(0) 32 32 , m_fDeferred(false) … … 49 49 * @param rcOp Return code to return to the guest side. 50 50 */ 51 int Client::completeInternal(VBOXHGCMCALLHANDLE hHandle, int rcOp) 52 { 53 LogFlowThisFunc((" uClientID=%RU32\n", m_uClientID));51 int Client::completeInternal(VBOXHGCMCALLHANDLE hHandle, int rcOp) RT_NOEXCEPT 52 { 53 LogFlowThisFunc(("idClient=%RU32\n", m_idClient)); 54 54 55 55 if ( m_SvcCtx.pHelpers … … 68 68 * Resets the client's internal state. 69 69 */ 70 void Client::reset(void) 70 void Client::reset(void) RT_NOEXCEPT 71 71 { 72 72 m_fDeferred = false; … … 83 83 * @param rcOp Return code to return to the guest side. 84 84 */ 85 int Client::Complete(VBOXHGCMCALLHANDLE hHandle, int rcOp /* = VINF_SUCCESS */) 85 int Client::Complete(VBOXHGCMCALLHANDLE hHandle, int rcOp /* = VINF_SUCCESS */) RT_NOEXCEPT 86 86 { 87 87 return completeInternal(hHandle, rcOp); … … 95 95 * @param rcOp Return code to return to the guest side. 96 96 */ 97 int Client::CompleteDeferred(int rcOp) 97 int Client::CompleteDeferred(int rcOp) RT_NOEXCEPT 98 98 { 99 99 if (m_fDeferred) … … 108 108 } 109 109 110 AssertMsg(m_fDeferred, ("Client %RU32 is not in deferred mode\n", m_ uClientID));110 AssertMsg(m_fDeferred, ("Client %RU32 is not in deferred mode\n", m_idClient)); 111 111 return VERR_INVALID_STATE; 112 112 } … … 117 117 * @returns HGCM handle. 118 118 */ 119 VBOXHGCMCALLHANDLE Client::GetHandle(void) const 119 VBOXHGCMCALLHANDLE Client::GetHandle(void) const RT_NOEXCEPT 120 120 { 121 121 return m_Deferred.hHandle; … … 127 127 * @returns HGCM handle. 128 128 */ 129 uint32_t Client::GetMsgType(void) const 129 uint32_t Client::GetMsgType(void) const RT_NOEXCEPT 130 130 { 131 131 return m_Deferred.uType; 132 132 } 133 133 134 uint32_t Client::GetMsgParamCount(void) const 134 uint32_t Client::GetMsgParamCount(void) const RT_NOEXCEPT 135 135 { 136 136 return m_Deferred.cParms; … … 142 142 * @returns The client's (HGCM) ID. 143 143 */ 144 uint32_t Client::GetClientID(void) const 145 { 146 return m_ uClientID;144 uint32_t Client::GetClientID(void) const RT_NOEXCEPT 145 { 146 return m_idClient; 147 147 } 148 148 … … 152 152 * @returns Protocol version, or 0 if not set. 153 153 */ 154 uint32_t Client::GetProtocolVer(void) const 154 uint32_t Client::GetProtocolVer(void) const RT_NOEXCEPT 155 155 { 156 156 return m_uProtocolVer; … … 162 162 * @returns \c True if in deferred mode, \c False if not. 163 163 */ 164 bool Client::IsDeferred(void) const 164 bool Client::IsDeferred(void) const RT_NOEXCEPT 165 165 { 166 166 return m_fDeferred; … … 171 171 * until CompleteDeferred() has been called. 172 172 */ 173 void Client::SetDeferred(VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 174 { 175 LogFlowThisFunc(("uClient=%RU32\n", m_ uClientID));173 void Client::SetDeferred(VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT 174 { 175 LogFlowThisFunc(("uClient=%RU32\n", m_idClient)); 176 176 177 177 #ifndef DEBUG_bird /** r=bird: This bugger triggers in the DnD service when restoring saved state. Not tested? */ … … 192 192 * @param uVersion Version number to set. 193 193 */ 194 void Client::SetProtocolVer(uint32_t uVersion) 194 void Client::SetProtocolVer(uint32_t uVersion) RT_NOEXCEPT 195 195 { 196 196 m_uProtocolVer = uVersion; … … 202 202 * @param SvcCtx Service context to set. 203 203 */ 204 void Client::SetSvcContext(const VBOXHGCMSVCTX &SvcCtx) 204 void Client::SetSvcContext(const VBOXHGCMSVCTX &SvcCtx) RT_NOEXCEPT 205 205 { 206 206 m_SvcCtx = SvcCtx; … … 216 216 * @param cParms Number of parameters the message needs. 217 217 */ 218 int Client::SetDeferredMsgInfo(uint32_t uMsg, uint32_t cParms) 218 int Client::SetDeferredMsgInfo(uint32_t uMsg, uint32_t cParms) RT_NOEXCEPT 219 219 { 220 220 if (m_fDeferred) … … 243 243 * @param pMessage Message to get message type and required parameters from. 244 244 */ 245 int Client::SetDeferredMsgInfo(const Message *pMessage) 245 int Client::SetDeferredMsgInfo(const Message *pMessage) RT_NOEXCEPT 246 246 { 247 247 AssertPtrReturn(pMessage, VERR_INVALID_POINTER); -
trunk/src/VBox/HostServices/common/message.cpp
r82968 r85318 23 23 : m_uMsg(0) 24 24 , m_cParms(0) 25 , m_paParms(NULL) { } 25 , m_paParms(NULL) 26 { 27 } 26 28 27 29 Message::Message(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) … … 41 43 * Resets the message by free'ing all allocated parameters and resetting the rest. 42 44 */ 43 void Message::reset(void) 45 void Message::reset(void) RT_NOEXCEPT 44 46 { 45 47 if (m_paParms) … … 67 69 * @returns Parameter count. 68 70 */ 69 uint32_t Message::GetParamCount(void) const 71 uint32_t Message::GetParamCount(void) const RT_NOEXCEPT 70 72 { 71 73 return m_cParms; … … 80 82 * @param aParms Where to store the HGCM parameter data. 81 83 */ 82 int Message::GetData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) const 84 int Message::GetData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) const RT_NOEXCEPT 83 85 { 84 86 if (m_uMsg != uMsg) … … 103 105 * @param pu32Info Where to store the parameter value. 104 106 */ 105 int Message::GetParmU32(uint32_t uParm, uint32_t *pu32Info) const 107 int Message::GetParmU32(uint32_t uParm, uint32_t *pu32Info) const RT_NOEXCEPT 106 108 { 107 109 AssertPtrNullReturn(pu32Info, VERR_INVALID_PARAMETER); … … 121 123 * @param pu64Info Where to store the parameter value. 122 124 */ 123 int Message::GetParmU64(uint32_t uParm, uint64_t *pu64Info) const 125 int Message::GetParmU64(uint32_t uParm, uint64_t *pu64Info) const RT_NOEXCEPT 124 126 { 125 127 AssertPtrNullReturn(pu64Info, VERR_INVALID_PARAMETER); … … 142 144 * @remarks Does not copy (store) the actual content of the pointer (deep copy). 143 145 */ 144 int Message::GetParmPtr(uint32_t uParm, void **ppvAddr, uint32_t *pcbSize) const 146 int Message::GetParmPtr(uint32_t uParm, void **ppvAddr, uint32_t *pcbSize) const RT_NOEXCEPT 145 147 { 146 148 AssertPtrNullReturn(ppvAddr, VERR_INVALID_PARAMETER); … … 160 162 * @returns Message type. 161 163 */ 162 uint32_t Message::GetType(void) const 164 uint32_t Message::GetType(void) const RT_NOEXCEPT 163 165 { 164 166 return m_uMsg; … … 180 182 int Message::CopyParms(PVBOXHGCMSVCPARM paParmsDst, uint32_t cParmsDst, 181 183 PVBOXHGCMSVCPARM paParmsSrc, uint32_t cParmsSrc, 182 bool fDeepCopy) 184 bool fDeepCopy) RT_NOEXCEPT 183 185 { 184 186 AssertPtrReturn(paParmsSrc, VERR_INVALID_POINTER); … … 188 190 return VERR_BUFFER_OVERFLOW; 189 191 190 int rc = VINF_SUCCESS;191 192 for (uint32_t i = 0; i < cParmsSrc; i++) 192 193 { … … 215 216 paParmsDst[i].u.pointer.addr = RTMemAlloc(paParmsDst[i].u.pointer.size); 216 217 if (!paParmsDst[i].u.pointer.addr) 217 { 218 rc = VERR_NO_MEMORY; 219 break; 220 } 218 return VERR_NO_MEMORY; 221 219 } 222 220 } … … 225 223 /* No, but we have to check if there is enough room. */ 226 224 if (paParmsDst[i].u.pointer.size < paParmsSrc[i].u.pointer.size) 227 { 228 rc = VERR_BUFFER_OVERFLOW; 229 break; 230 } 225 return VERR_BUFFER_OVERFLOW; 231 226 } 232 227 … … 235 230 if ( paParmsDst[i].u.pointer.addr 236 231 && paParmsDst[i].u.pointer.size) 237 {238 232 memcpy(paParmsDst[i].u.pointer.addr, 239 233 paParmsSrc[i].u.pointer.addr, 240 234 RT_MIN(paParmsDst[i].u.pointer.size, paParmsSrc[i].u.pointer.size)); 241 }242 235 else 243 r c =VERR_INVALID_POINTER;236 return VERR_INVALID_POINTER; 244 237 } 245 238 break; … … 248 241 { 249 242 AssertMsgFailed(("Unknown HGCM type %u\n", paParmsSrc[i].type)); 250 rc = VERR_INVALID_PARAMETER; 251 break; 243 return VERR_INVALID_PARAMETER; 252 244 } 253 245 } 254 if (RT_FAILURE(rc)) 255 break; 256 } 257 return rc; 246 } 247 return VINF_SUCCESS; 258 248 } 259 249 … … 266 256 * @param aParms Array of parameters to set. 267 257 */ 268 int Message::initData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) 269 { 258 int Message::initData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) RT_NOEXCEPT 259 { 260 /** @todo r=bird: There is a define for the max number of HGCM parameters, 261 * it's way smaller than 256, something like 61 IIRC. */ 270 262 AssertReturn(cParms < 256, VERR_INVALID_PARAMETER); 271 263 AssertPtrNullReturn(aParms, VERR_INVALID_PARAMETER);
Note:
See TracChangeset
for help on using the changeset viewer.

