Changeset 42171 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jul 16, 2012 8:28:47 PM (13 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r42160 r42171 48 48 typedef std::vector <LONG> ProcessAffinity; 49 49 typedef std::vector <Utf8Str> ProcessArguments; 50 typedef std::map <Utf8Str, Utf8Str> ProcessEnvironmentMap;51 50 52 51 … … 108 107 }; 109 108 109 typedef std::vector <Utf8Str> GuestEnvironmentArray; 110 class GuestEnvironment 111 { 112 public: 113 114 int BuildEnvironmentBlock(void **ppvEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars); 115 116 void Clear(void); 117 118 int CopyFrom(const GuestEnvironmentArray &environment); 119 120 int CopyTo(GuestEnvironmentArray &environment); 121 122 static void FreeEnvironmentBlock(void *pvEnv); 123 124 Utf8Str Get(size_t nPos); 125 126 bool Has(const Utf8Str &strKey); 127 128 int Set(const Utf8Str &strKey, const Utf8Str &strValue); 129 130 int Set(const Utf8Str &strPair); 131 132 size_t Size(void); 133 134 int Unset(const Utf8Str &strKey); 135 136 public: 137 138 GuestEnvironment& operator=(const GuestEnvironmentArray &that); 139 140 GuestEnvironment& operator=(const GuestEnvironment &that); 141 142 protected: 143 144 int appendToEnvBlock(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars); 145 146 protected: 147 148 std::map <Utf8Str, Utf8Str> mEnvironment; 149 }; 150 151 110 152 /** 111 153 * Structure for keeping all the relevant process … … 116 158 Utf8Str mCommand; 117 159 ProcessArguments mArguments; 118 ProcessEnvironmentMapmEnvironment;160 GuestEnvironment mEnvironment; 119 161 uint32_t mFlags; 120 162 ULONG mTimeoutMS; -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r42160 r42171 108 108 /** @} */ 109 109 110 private: 111 112 typedef std::vector <ComObjPtr<GuestDirectory> > SessionDirectories; 113 typedef std::vector <ComObjPtr<GuestFile> > SessionFiles; 114 typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses; 115 110 116 public: 111 117 /** @name Public internal methods. … … 114 120 int fileClose(ComObjPtr<GuestFile> pFile); 115 121 const GuestCredentials &getCredentials(void); 122 const GuestEnvironment &getEnvironment(void); 116 123 int processClose(ComObjPtr<GuestProcess> pProcess); 117 124 int processCreateExInteral(GuestProcessInfo &aProcInfo, IGuestProcess **aProcess); … … 120 127 121 128 private: 122 123 typedef std::map <Utf8Str, Utf8Str> SessionEnvironment;124 125 typedef std::vector <ComObjPtr<GuestDirectory> > SessionDirectories;126 typedef std::vector <ComObjPtr<GuestFile> > SessionFiles;127 typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;128 129 129 130 struct Data … … 142 143 /** The session timeout. Default is 30s. */ 143 144 ULONG mTimeout; 144 SessionEnvironmentmEnvironment;145 GuestEnvironment mEnvironment; 145 146 SessionDirectories mDirectories; 146 147 SessionFiles mFiles; -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r42160 r42171 2760 2760 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2761 2761 2762 2762 int rc = sessionCreate(aUser, aPassword, aDomain, aSessionName, aGuestSession); 2763 return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR; 2763 2764 #endif /* VBOX_WITH_GUEST_CONTROL */ 2764 2765 } -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r42160 r42171 125 125 Assert(mEventSem != NIL_RTSEMEVENT); 126 126 return RTSemEventWait(mEventSem, timeoutMS); 127 } 128 129 /////////////////////////////////////////////////////////////////////////////// 130 131 int GuestEnvironment::BuildEnvironmentBlock(void **ppvEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars) 132 { 133 AssertPtrReturn(ppvEnv, VERR_INVALID_POINTER); 134 /* Rest is optional. */ 135 136 uint32_t cbEnv = 0; 137 uint32_t cEnvVars = 0; 138 139 int rc = VINF_SUCCESS; 140 141 size_t cEnv = mEnvironment.size(); 142 if (cEnv) 143 { 144 std::map<Utf8Str, Utf8Str>::const_iterator itEnv = mEnvironment.begin(); 145 for (; itEnv != mEnvironment.end() && RT_SUCCESS(rc); itEnv++) 146 { 147 char *pszEnv; 148 if (!RTStrAPrintf(&pszEnv, "%s=%s", itEnv->first.c_str(), itEnv->second.c_str())) 149 { 150 rc = VERR_NO_MEMORY; 151 break; 152 } 153 AssertPtr(pszEnv); 154 rc = appendToEnvBlock(pszEnv, ppvEnv, &cbEnv, &cEnvVars); 155 RTStrFree(pszEnv); 156 } 157 Assert(cEnv == cEnvVars); 158 } 159 160 if (pcbEnv) 161 *pcbEnv = cbEnv; 162 if (pcEnvVars) 163 *pcEnvVars = cEnvVars; 164 165 return rc; 166 } 167 168 void GuestEnvironment::Clear(void) 169 { 170 mEnvironment.clear(); 171 } 172 173 int GuestEnvironment::CopyFrom(const GuestEnvironmentArray &environment) 174 { 175 int rc = VINF_SUCCESS; 176 177 for (GuestEnvironmentArray::const_iterator it = environment.begin(); 178 it != environment.end() && RT_SUCCESS(rc); 179 ++it) 180 { 181 rc = Set((*it)); 182 } 183 184 return rc; 185 } 186 187 int GuestEnvironment::CopyTo(GuestEnvironmentArray &environment) 188 { 189 size_t s = 0; 190 for (std::map<Utf8Str, Utf8Str>::const_iterator it = mEnvironment.begin(); 191 it != mEnvironment.end(); 192 ++it, ++s) 193 { 194 environment[s] = Bstr(it->first + "=" + it->second).raw(); 195 } 196 197 return VINF_SUCCESS; 198 } 199 200 /* static */ 201 void GuestEnvironment::FreeEnvironmentBlock(void *pvEnv) 202 { 203 if (pvEnv) 204 RTMemFree(pvEnv); 205 } 206 207 Utf8Str GuestEnvironment::Get(size_t nPos) 208 { 209 size_t curPos = 0; 210 std::map<Utf8Str, Utf8Str>::const_iterator it = mEnvironment.begin(); 211 for (; it != mEnvironment.end() && curPos < nPos; 212 ++it) { } 213 214 if (it != mEnvironment.end()) 215 return Utf8Str(it->first + "=" + it->second); 216 217 return Utf8Str(""); 218 } 219 220 bool GuestEnvironment::Has(const Utf8Str &strKey) 221 { 222 std::map <Utf8Str, Utf8Str>::const_iterator itEnv = mEnvironment.find(strKey); 223 return (itEnv != mEnvironment.end()); 224 } 225 226 int GuestEnvironment::Set(const Utf8Str &strKey, const Utf8Str &strValue) 227 { 228 mEnvironment[strValue] = strValue; 229 return VINF_SUCCESS; 230 } 231 232 int GuestEnvironment::Set(const Utf8Str &strPair) 233 { 234 RTCList<RTCString> listPair = strPair.split("=", RTCString::KeepEmptyParts); 235 size_t p = 0; 236 while(p < listPair.size()) 237 { 238 Utf8Str strKey = listPair.at(p++); 239 if (strKey.isEmpty()) /* Skip pairs with empty keys (e.g. "=FOO"). */ 240 { 241 p++; 242 continue; 243 } 244 Utf8Str strValue; 245 if (p < listPair.size()) 246 strValue = listPair.at(p++); 247 mEnvironment[strKey] = strValue; 248 } 249 250 return VINF_SUCCESS; 251 } 252 253 size_t GuestEnvironment::Size(void) 254 { 255 return mEnvironment.size(); 256 } 257 258 int GuestEnvironment::Unset(const Utf8Str &strKey) 259 { 260 std::map <Utf8Str, Utf8Str>::iterator itEnv = mEnvironment.find(strKey); 261 if (itEnv != mEnvironment.end()) 262 { 263 mEnvironment.erase(itEnv); 264 return VINF_SUCCESS; 265 } 266 267 return VERR_NOT_FOUND; 268 } 269 270 GuestEnvironment& GuestEnvironment::operator=(const GuestEnvironmentArray &that) 271 { 272 CopyFrom(that); 273 return *this; 274 } 275 276 GuestEnvironment& GuestEnvironment::operator=(const GuestEnvironment &that) 277 { 278 for (std::map<Utf8Str, Utf8Str>::const_iterator it = that.mEnvironment.begin(); 279 it != that.mEnvironment.end(); 280 ++it) 281 { 282 mEnvironment[it->first] = it->second; 283 } 284 285 return *this; 286 } 287 288 /** 289 * Appends environment variables to the environment block. 290 * 291 * Each var=value pair is separated by the null character ('\\0'). The whole 292 * block will be stored in one blob and disassembled on the guest side later to 293 * fit into the HGCM param structure. 294 * 295 * @returns VBox status code. 296 * 297 * @param pszEnvVar The environment variable=value to append to the 298 * environment block. 299 * @param ppvList This is actually a pointer to a char pointer 300 * variable which keeps track of the environment block 301 * that we're constructing. 302 * @param pcbList Pointer to the variable holding the current size of 303 * the environment block. (List is a misnomer, go 304 * ahead a be confused.) 305 * @param pcEnvVars Pointer to the variable holding count of variables 306 * stored in the environment block. 307 */ 308 int GuestEnvironment::appendToEnvBlock(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars) 309 { 310 int rc = VINF_SUCCESS; 311 uint32_t cchEnv = strlen(pszEnv); Assert(cchEnv >= 2); 312 if (*ppvList) 313 { 314 uint32_t cbNewLen = *pcbList + cchEnv + 1; /* Include zero termination. */ 315 char *pvTmp = (char *)RTMemRealloc(*ppvList, cbNewLen); 316 if (pvTmp == NULL) 317 rc = VERR_NO_MEMORY; 318 else 319 { 320 memcpy(pvTmp + *pcbList, pszEnv, cchEnv); 321 pvTmp[cbNewLen - 1] = '\0'; /* Add zero termination. */ 322 *ppvList = (void **)pvTmp; 323 } 324 } 325 else 326 { 327 char *pszTmp; 328 if (RTStrAPrintf(&pszTmp, "%s", pszEnv) >= 0) 329 { 330 *ppvList = (void **)pszTmp; 331 /* Reset counters. */ 332 *pcEnvVars = 0; 333 *pcbList = 0; 334 } 335 } 336 if (RT_SUCCESS(rc)) 337 { 338 *pcbList += cchEnv + 1; /* Include zero termination. */ 339 *pcEnvVars += 1; /* Increase env variable count. */ 340 } 341 return rc; 127 342 } 128 343 -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r42162 r42171 184 184 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 185 185 186 com::SafeArray<BSTR> collection(mData.mProcess.mEnvironment.size()); 187 size_t s = 0; 188 for (ProcessEnvironmentMap::const_iterator it = mData.mProcess.mEnvironment.begin(); 189 it != mData.mProcess.mEnvironment.end(); 190 it++, s++) 191 { 192 Bstr strEnv = it->first + Utf8Str("=") + it->second; 193 collection[s] = strEnv.raw(); 194 } 195 196 collection.detachTo(ComSafeArrayOutArg(aEnvironment)); 186 com::SafeArray<BSTR> arguments(mData.mProcess.mEnvironment.Size()); 187 for (size_t i = 0; i < arguments.size(); i++) 188 arguments[i] = Bstr(mData.mProcess.mEnvironment.Get(i)).raw(); 189 arguments.detachTo(ComSafeArrayOutArg(aEnvironment)); 197 190 198 191 return S_OK; … … 347 340 } 348 341 349 /**350 * Appends environment variables to the environment block.351 *352 * Each var=value pair is separated by the null character ('\\0'). The whole353 * block will be stored in one blob and disassembled on the guest side later to354 * fit into the HGCM param structure.355 *356 * @returns VBox status code.357 *358 * @param pszEnvVar The environment variable=value to append to the359 * environment block.360 * @param ppvList This is actually a pointer to a char pointer361 * variable which keeps track of the environment block362 * that we're constructing.363 * @param pcbList Pointer to the variable holding the current size of364 * the environment block. (List is a misnomer, go365 * ahead a be confused.)366 * @param pcEnvVars Pointer to the variable holding count of variables367 * stored in the environment block.368 */369 int GuestProcess::prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars)370 {371 int rc = VINF_SUCCESS;372 uint32_t cchEnv = strlen(pszEnv); Assert(cchEnv >= 2);373 if (*ppvList)374 {375 uint32_t cbNewLen = *pcbList + cchEnv + 1; /* Include zero termination. */376 char *pvTmp = (char *)RTMemRealloc(*ppvList, cbNewLen);377 if (pvTmp == NULL)378 rc = VERR_NO_MEMORY;379 else380 {381 memcpy(pvTmp + *pcbList, pszEnv, cchEnv);382 pvTmp[cbNewLen - 1] = '\0'; /* Add zero termination. */383 *ppvList = (void **)pvTmp;384 }385 }386 else387 {388 char *pszTmp;389 if (RTStrAPrintf(&pszTmp, "%s", pszEnv) >= 0)390 {391 *ppvList = (void **)pszTmp;392 /* Reset counters. */393 *pcEnvVars = 0;394 *pcbList = 0;395 }396 }397 if (RT_SUCCESS(rc))398 {399 *pcbList += cchEnv + 1; /* Include zero termination. */400 *pcEnvVars += 1; /* Increase env variable count. */401 }402 return rc;403 }404 405 342 int GuestProcess::readData(ULONG aHandle, ULONG aSize, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData)) 406 343 { … … 460 397 /* Prepare environment. */ 461 398 void *pvEnv = NULL; 462 size_t cEnv = mData.mProcess.mEnvironment.size();463 399 uint32_t cbEnv = 0; 464 if ( RT_SUCCESS(rc) 465 && cEnv) 466 { 467 uint32_t cEnvBuild = 0; 468 ProcessEnvironmentMap::const_iterator itEnv = mData.mProcess.mEnvironment.begin(); 469 for (; itEnv != mData.mProcess.mEnvironment.end() && RT_SUCCESS(rc); itEnv++) 470 { 471 char *pszEnv; 472 if (!RTStrAPrintf(&pszEnv, "%s=%s", itEnv->first.c_str(), itEnv->second.c_str())) 473 { 474 rc = VERR_NO_MEMORY; 475 break; 476 } 477 AssertPtr(pszEnv); 478 rc = prepareExecuteEnv(pszEnv, &pvEnv, &cbEnv, &cEnvBuild); 479 RTStrFree(pszEnv); 480 } 481 Assert(cEnv == cEnvBuild); 482 } 400 rc = mData.mProcess.mEnvironment.BuildEnvironmentBlock(&pvEnv, &cbEnv, NULL /* cEnv */); 483 401 484 402 if (RT_SUCCESS(rc)) … … 493 411 paParms[i++].setUInt32(mData.mProcess.mArguments.size()); 494 412 paParms[i++].setPointer((void*)pszArgs, cbArgs); 495 paParms[i++].setUInt32(mData.mProcess.mEnvironment. size());413 paParms[i++].setUInt32(mData.mProcess.mEnvironment.Size()); 496 414 paParms[i++].setUInt32(cbEnv); 497 415 paParms[i++].setPointer((void*)pvEnv, cbEnv); … … 529 447 } 530 448 531 if (pvEnv) 532 RTMemFree(pvEnv); 449 GuestEnvironment::FreeEnvironmentBlock(pvEnv); 533 450 if (pszArgs) 534 451 RTStrFree(pszArgs); -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r42160 r42171 28 28 #include "Logging.h" 29 29 30 #include <iprt/env.h> 31 30 32 #include <VBox/com/array.h> 31 33 … … 223 225 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 224 226 225 com::SafeArray<BSTR> collection(mData.mEnvironment.size()); 226 size_t s = 0; 227 for (SessionEnvironment::const_iterator it = mData.mEnvironment.begin(); 228 it != mData.mEnvironment.end(); 229 ++it, ++s) 230 { 231 collection[s] = Bstr(it->first + "=" + it->second).raw(); 232 } 233 234 collection.detachTo(ComSafeArrayOutArg(aEnvironment)); 227 com::SafeArray<BSTR> arguments(mData.mEnvironment.Size()); 228 for (size_t i = 0; i < arguments.size(); i++) 229 arguments[i] = Bstr(mData.mEnvironment.Get(i)).raw(); 230 arguments.detachTo(ComSafeArrayOutArg(aEnvironment)); 235 231 236 232 return S_OK; … … 335 331 { 336 332 return mData.mCredentials; 333 } 334 335 const GuestEnvironment& GuestSession::getEnvironment(void) 336 { 337 return mData.mEnvironment; 337 338 } 338 339 … … 589 590 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 590 591 591 ReturnComNotImplemented(); 592 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 593 594 mData.mEnvironment.Clear(); 595 596 return S_OK; 592 597 #endif /* VBOX_WITH_GUEST_CONTROL */ 593 598 } … … 601 606 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 602 607 603 ReturnComNotImplemented(); 608 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 609 610 mData.mEnvironment.Set(Utf8Str(aName), Utf8Str(aValue)); 611 612 return S_OK; 604 613 #endif /* VBOX_WITH_GUEST_CONTROL */ 605 614 } … … 613 622 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 614 623 615 ReturnComNotImplemented(); 624 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 625 626 com::SafeArray<IN_BSTR> environment(ComSafeArrayInArg(aValues)); 627 628 int rc = VINF_SUCCESS; 629 for (size_t i = 0; i < environment.size() && RT_SUCCESS(rc); i++) 630 rc = mData.mEnvironment.Set(Utf8Str(environment[i])); 631 632 return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR; 616 633 #endif /* VBOX_WITH_GUEST_CONTROL */ 617 634 } … … 625 642 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 626 643 627 ReturnComNotImplemented(); 644 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 645 646 mData.mEnvironment.Unset(Utf8Str(aName)); 647 648 return S_OK; 628 649 #endif /* VBOX_WITH_GUEST_CONTROL */ 629 650 } … … 761 782 procInfo.mArguments[i] = Utf8Str(Bstr(arguments[i])); 762 783 784 int rc = VINF_SUCCESS; 785 786 /* Create the process environment: 787 * - Apply the session environment in a first step, and 788 * - Apply environment variables specified by this call to 789 * have the chance of overwriting/deleting session entries. 790 */ 791 procInfo.mEnvironment = mData.mEnvironment; 763 792 com::SafeArray<IN_BSTR> environment(ComSafeArrayInArg(aEnvironment)); 764 for (size_t i = 0; i < environment.size(); i++) 765 { 766 Utf8Str strEnv = Bstr(environment[i]); 767 RTCList<RTCString> listPair = strEnv.split("=", RTCString::KeepEmptyParts); 768 size_t p = 0; 769 while(p < listPair.size()) 770 { 771 Utf8Str strKey = listPair.at(p++); 772 if (strKey.isEmpty()) /* Skip pairs with empty keys (e.g. "=FOO"). */ 773 { 774 p++; 775 continue; 776 } 777 Utf8Str strValue; 778 if (p < listPair.size()) 779 strValue = listPair.at(p++); 780 procInfo.mEnvironment[strKey] = strValue; 781 } 782 } 783 784 com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags)); 785 for (size_t i = 0; i < flags.size(); i++) 786 procInfo.mFlags |= flags[i]; 787 788 procInfo.mTimeoutMS = aTimeoutMS; 789 790 com::SafeArray<LONG> affinity(ComSafeArrayInArg(aAffinity)); 791 procInfo.mAffinity.reserve(affinity.size()); 792 for (size_t i = 0; i < affinity.size(); i++) 793 procInfo.mAffinity[i] = affinity[i]; /** @todo Really necessary? Later. */ 794 795 procInfo.mPriority = aPriority; 796 797 int rc = processCreateExInteral(procInfo, aProcess); 793 for (size_t i = 0; i < environment.size() && RT_SUCCESS(rc); i++) 794 rc = mData.mEnvironment.Set(Utf8Str(environment[i])); 795 796 if (RT_SUCCESS(rc)) 797 { 798 799 com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags)); 800 for (size_t i = 0; i < flags.size(); i++) 801 procInfo.mFlags |= flags[i]; 802 803 procInfo.mTimeoutMS = aTimeoutMS; 804 805 com::SafeArray<LONG> affinity(ComSafeArrayInArg(aAffinity)); 806 procInfo.mAffinity.reserve(affinity.size()); 807 for (size_t i = 0; i < affinity.size(); i++) 808 procInfo.mAffinity[i] = affinity[i]; /** @todo Really necessary? Later. */ 809 810 procInfo.mPriority = aPriority; 811 812 rc = processCreateExInteral(procInfo, aProcess); 813 } 798 814 return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR; 799 815 #endif /* VBOX_WITH_GUEST_CONTROL */
Note:
See TracChangeset
for help on using the changeset viewer.