- Timestamp:
- May 2, 2015 1:57:14 AM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 99964
- Location:
- trunk/src/VBox
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r55590 r55591 5158 5158 <link to="IConsole::powerUp"/>. 5159 5159 5160 <!-- TODO/r=bird: What about making @a environment into a smart array? Guess 5161 this predates our safe array support by a year or so... Dmitry wrote the text here, right? 5162 Just rename it to @a environmentChanges and shorten the documentation to say the string 5163 are applied onto the server environment putenv style, i.e. "VAR=VALUE" for setting/replacing 5164 and "VAR" for unsetting. --> 5160 5165 The @a environment argument is a string containing definitions of 5161 5166 environment variables in the following format: … … 10242 10247 </const> 10243 10248 <const name="ExpandArguments" value="64"> 10244 <desc>Expands environment variables in process arguments.</desc> 10249 <desc>Expands environment variables in process arguments. 10250 <note> 10251 This is not yet implemented and is currently silently ignored. 10252 We will document the protocolVersion number for this feature once it 10253 appears, so don't use it till then. 10254 </note> 10255 </desc> 10245 10256 </const> 10246 10257 <const name="UnquotedArguments" value="128"> … … 10783 10794 <interface 10784 10795 name="IGuestSession" extends="$unknown" 10785 uuid=" e1fa83fe-437d-3e3a-9278-4297f1ca95dd"10796 uuid="bb890975-4903-38f8-4bc2-f39341f95533" 10786 10797 wsmap="managed" 10787 10798 > … … 10795 10806 <!-- r=bird: Is the root session part of the maximum of 32?? Not really clear. --> 10796 10807 This root session is controlling all other guest sessions and also is 10797 responsible for actions which require system level privileges. Each 10798 guest session keeps track of its started guest processes, opened guest 10799 files or guest directories. To work on guest files or directories a 10800 guest session offers methods to open or create such objects (see 10801 <link to="IGuestSession::fileOpen"/> or 10802 <link to="IGuestSession::directoryOpen"/> for example). 10808 responsible for actions which require system level privileges. 10809 10810 Each guest session keeps track of the guest directories and files that 10811 it opened as well as guest processes it has created. To work on guest 10812 files or directories a guest session offers methods to open or create 10813 such objects (see <link to="IGuestSession::fileOpen"/> or 10814 <link to="IGuestSession::directoryOpen"/> for instance). Similarly, 10815 there a methods for creating guest processes. 10816 10817 There can be up to 2048 objects (guest processes, files and directories) 10818 a time per guest session. Exceeding the limit will result in an error. 10819 <!-- @todo r=bird: Add specific VBOX_E_XXX error for this and document it here! --> 10803 10820 10804 10821 When done with either of these objects, including the guest session itself, 10805 10822 use the appropriate close() method to let the object do its cleanup work. 10806 10823 10807 A set of environment variables changes is associated with each session. 10808 These are applied to the standard environment of the impersonated guest 10809 user when creating a new guest process. For additional flexibility the 10810 <link to="IGuestSession::processCreate"/> and 10811 <link to="IGuestSession::processCreateEx"/> methods allows you to specify 10812 individual environment changes for each process you create. 10824 Closing a session via <link to="IGuestSession::close" /> will try to close 10825 all the mentioned objects above unless these objects are still used by 10826 a client. 10827 10828 A set of environment variables changes is associated with each session 10829 (<link to="IGuestSession::environmentChanges"/>). These are applied to 10830 the base environment of the impersonated guest user when creating a new 10831 guest process. For additional flexibility the <link to="IGuestSession::processCreate"/> 10832 and <link to="IGuestSession::processCreateEx"/> methods allows you to 10833 specify individual environment changes for each process you create. 10834 With newer guest addition versions, the base environment is also made 10835 available via <link to="IGuestSession::environmentBase"/>. (One reason 10836 for why we record changes to a base environment instead of working 10837 directly on an environment block is that we need to be compatible 10838 with older guest additions. Another reason is that this way it is always 10839 possible to undo all the changes you've scheduled.) 10813 10840 </desc> 10814 10841 … … 10845 10872 <desc>Returns the current session status.</desc> 10846 10873 </attribute> 10847 <attribute name="environment" type="wstring" safearray="yes"> 10848 <!-- r=bird: Would probably be a great idea to rename this attribute as 10849 it is misleading and will cause worse confusion if we ever 10850 expose the default environment for session (which arguably 10851 would be useful in many ways). --> 10852 <desc> 10853 The set of environment changes. They are in putenv format, i.e. 10854 "NAME=VALUE" for setting and "NAME" for unsetting. 10874 <attribute name="environmentChanges" type="wstring" safearray="yes"> 10875 <desc> 10876 The set of scheduled environment changes to the base environment of the 10877 session. They are in putenv format, i.e. "VAR=VALUE" for setting and 10878 "VAR" for unsetting. One entry per variable (change). The changes are 10879 applied when creating new guest processes. 10880 10881 This is writable, so to undo all the scheduled changes, assign it an 10882 empty array. 10883 </desc> 10884 </attribute> 10885 <attribute name="environmentBase" type="wstring" safearray="yes" readonly="yes"> 10886 <desc> 10887 The base environment of the session. They are on the "VAR=VALUE" form, 10888 one array entry per variable. 10889 <!-- @todo/TODO/FIXME: This doesn't end up in the PDF. 10890 <result name="VBOX_E_NOT_SUPPORTED">If the guest additions does not 10891 support the session base environment feature. Support for this was 10892 introduced with protocol version XXX.</result> 10893 <result name="VBOX_E_INVALID_OBJECT_STATE">If the guest additions has 10894 yet to report the session base environment.</result> --> 10895 10896 Access fails with VBOX_E_NOT_SUPPORTED if the guest additions does not 10897 support the session base environment feature. Support for this was 10898 introduced with protocol version XXXX. 10899 10900 Access fails with VBOX_E_INVALID_OBJECT_STATE if the guest additions 10901 has yet to report the session base environment. 10855 10902 </desc> 10856 10903 </attribute> … … 11110 11157 </method> 11111 11158 11112 <method name="environmentS et">11159 <method name="environmentScheduleSet"> 11113 11160 <desc> 11114 11161 Schedules setting an environment variable when creating the next guest 11115 process. This affects the <link to="IGuestSession::environment"/> attribute. 11162 process. This affects the <link to="IGuestSession::environmentChanges"/> 11163 attribute. 11116 11164 </desc> 11117 11165 <param name="name" type="wstring" dir="in"> … … 11124 11172 </method> 11125 11173 11126 <method name="environment Unset">11174 <method name="environmentScheduleUnset"> 11127 11175 <desc> 11128 11176 Schedules unsetting (removing) an environment variable when creating 11129 the next guest process. This affects the <link to="IGuestSession::environment"/>11130 attribute.11177 the next guest process. This affects the 11178 <link to="IGuestSession::environmentChanges"/> attribute. 11131 11179 </desc> 11132 11180 <param name="name" type="wstring" dir="in"> 11133 11181 <desc>Name of the environment variable to unset. This cannot be empty 11134 11182 nor can it contain any equal signs.</desc> 11183 </param> 11184 </method> 11185 11186 <method name="environmentGetBaseVariable"> 11187 <desc> 11188 Gets an environment variable from the session's base environment 11189 (<link to="IGuestSession::environmentBase"/>). 11190 11191 <result name="VBOX_E_NOT_SUPPORTED">If the guest additions does not 11192 support the session base environment feature. Support for this was 11193 introduced with protocol version XXXX.</result> 11194 <result name="VBOX_E_INVALID_OBJECT_STATE">If the guest additions has 11195 yet to report the session base environment.</result> 11196 </desc> 11197 <param name="name" type="wstring" dir="in"> 11198 <desc>Name of the environment variable to get.This cannot be empty 11199 nor can it contain any equal signs.</desc> 11200 </param> 11201 <param name="value" type="wstring" dir="return"> 11202 <desc> 11203 The value of the variable. Empty if not found. To deal with 11204 variables that may have empty values, use 11205 <link to="IGuestSession::environmentDoesBaseVariableExist"/>. 11206 </desc> 11207 </param> 11208 </method> 11209 11210 <method name="environmentDoesBaseVariableExist"> 11211 <desc> 11212 Checks if the given environment variable exists in the session's base 11213 environment (<link to="IGuestSession::environmentBase"/>). 11214 11215 <result name="VBOX_E_NOT_SUPPORTED">If the guest additions does not 11216 support the session base environment feature. Support for this was 11217 introduced with protocol version XXXX.</result> 11218 <result name="VBOX_E_INVALID_OBJECT_STATE">If the guest additions has 11219 yet to report the session base environment.</result> 11220 </desc> 11221 <param name="name" type="wstring" dir="in"> 11222 <desc>Name of the environment variable to look for. This cannot be 11223 empty nor can it contain any equal signs.</desc> 11224 </param> 11225 <param name="exists" type="boolean" dir="return"> 11226 <desc>TRUE if the variable exists, FALSE if not.</desc> 11135 11227 </param> 11136 11228 </method> … … 11432 11524 </desc> 11433 11525 </param> 11434 <param name="environment " type="wstring" dir="in" safearray="yes">11526 <param name="environmentChanges" type="wstring" dir="in" safearray="yes"> 11435 11527 <desc> 11436 11528 Set of environment changes to complement 11437 <link to="IGuestSession::environment"/>. Takes precedence over 11438 the session ones. The changes are in putenv format, i.e. 11439 "NAME=VALUE" for setting and "NAME" for unsetting. 11440 11441 The changes are applied to the standard environment of the 11442 impersonated guest user when creating the process. 11529 <link to="IGuestSession::environmentChanges"/>. Takes precedence 11530 over the session ones. The changes are in putenv format, i.e. 11531 "VAR=VALUE" for setting and "VAR" for unsetting. 11532 11533 The changes are applied to the base environment of the impersonated 11534 guest user (<link to="IGuestSession::environmentBase"/>) when 11535 creating the process. (This is done on the guest side of things in 11536 order to be compatible with older guest additions. That is one of 11537 the motivations for not passing in the whole environment here.) 11443 11538 </desc> 11444 11539 </param> … … 11488 11583 </desc> 11489 11584 </param> 11490 <param name="environment " type="wstring" dir="in" safearray="yes">11585 <param name="environmentChanges" type="wstring" dir="in" safearray="yes"> 11491 11586 <desc> 11492 11587 Set of environment changes to complement 11493 <link to="IGuestSession::environment"/>. Takes precedence over 11494 the session ones. The changes are in putenv format, i.e. 11495 "NAME=VALUE" for setting and "NAME" for unsetting. 11496 11497 The changes are applied to the standard environment of the 11498 impersonated guest user when creating the process. 11588 <link to="IGuestSession::environmentChanges"/>. Takes precedence 11589 over the session ones. The changes are in putenv format, i.e. 11590 "VAR=VALUE" for setting and "VAR" for unsetting. 11591 11592 The changes are applied to the base environment of the impersonated 11593 guest user (<link to="IGuestSession::environmentBase"/>) when 11594 creating the process. (This is done on the guest side of things in 11595 order to be compatible with older guest additions. That is one of 11596 the motivations for not passing in the whole environment here.) 11499 11597 </desc> 11500 11598 </param> … … 11688 11786 <interface 11689 11787 name="IProcess" extends="$unknown" 11690 uuid=" 5a4fe06d-8cb1-40ff-ac9e-9676e32f706e"11788 uuid="064cf1ca-4c0f-50b5-8f8e-e8b4bfa76c33" 11691 11789 wsmap="managed" 11692 11790 > … … 11701 11799 </attribute> 11702 11800 <attribute name="environment" type="wstring" readonly="yes" safearray="yes"> 11703 <!-- r=bird: Would probably be a great idea to rename this attribute as 11704 it is misleading and will cause worse confusion if we ever 11705 expose the initial environment for processes. --> 11706 <desc> 11707 The set of environment changes appled to the default environment when 11708 starting the process. The format is putenv style, i.e. "NAME=VALUE" 11709 for variables that should be set and "NAME" for values that should be 11710 unset (removed). See also <link to="IGuestSession::environment"/>. 11801 <desc> 11802 The initial process environment. Not yet implemented. 11711 11803 </desc> 11712 11804 </attribute> … … 11883 11975 <interface 11884 11976 name="IGuestProcess" extends="IProcess" 11885 uuid=" dfa39a36-5d43-4840-a025-67ea956b3111"11977 uuid="1f3c2d60-4c09-d824-4ca1-579a2bda858f" 11886 11978 wsmap="managed" 11887 11979 > … … 12491 12583 the session object via <link to="IGuest::createSession"/>. Anonymous 12492 12584 sessions, that is, sessions without specifying a valid 12493 user account in the guest are not allowed due to security reasons. 12494 12495 There can be a maximum of 32 sessions at once per VM. Each session keeps 12496 track of its started guest processes, opened guest files or guest directories. 12497 To work on guest files or directories a guest session offers methods to open 12498 or create such objects (see <link to="IGuestSession::fileOpen"/> or 12499 <link to="IGuestSession::directoryOpen"/> for example). 12500 12501 There can be up to 2048 objects (guest processes, files or directories) 12502 a time per guest session. Exceeding the limit will result in an appropriate 12503 error message. 12504 12505 When done with either of these objects, including the guest session itself, 12506 use the appropriate close() method to let the object do its cleanup work. 12507 12508 Every guest session has its own environment variable block which gets 12509 automatically applied when starting a new guest process via 12510 <link to="IGuestSession::processCreate"/> or <link to="IGuestSession::processCreateEx"/>. 12511 To override (or unset) certain environment variables already set by the 12512 guest session, one can specify a per-process environment block when using 12513 one of the both above mentioned process creation calls. 12514 12515 Closing a session via <link to="IGuestSession::close" /> will try to close 12516 all the mentioned objects above unless these objects are still used by 12517 a client. 12585 user account in the guest are not allowed reasons of security. 12586 12587 There can be a maximum of 32 sessions at once per VM. An error will 12588 be returned if this has been reached. <!-- This should actually read: 12589 VBOX_E_IPRT_ERROR will be return if this limit has been reached. 12590 However, keep in mind that VBOX_E_IPRT_ERROR can be returned for about 12591 88 unrelated reasons, so you don't know what happend unless you parse 12592 the error text. (bird) --> 12593 <!-- @todo r=bird: Seriously, add an dedicated VBOX_E_MAX_GUEST_SESSIONS status 12594 for this condition. Do the same for all other maximums and things that could be 12595 useful to the API client. --> 12596 12597 For more information please consult <link to="IGuestSession"/> 12518 12598 </desc> 12519 12599 <param name="user" type="wstring" dir="in"> -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r55588 r55591 26 26 #include <iprt/env.h> 27 27 #include <iprt/semaphore.h> 28 #include <iprt/cpp/utils.h> 28 29 29 30 #include <VBox/com/com.h> … … 78 79 GuestEnvironmentBase(void) 79 80 : m_hEnv(NIL_RTENV) 81 , m_cRefs(1) 80 82 { } 81 83 … … 85 87 virtual ~GuestEnvironmentBase(void) 86 88 { 89 Assert(m_cRefs <= 1); 87 90 int rc = RTEnvDestroy(m_hEnv); AssertRC(rc); 88 91 m_hEnv = NIL_RTENV; … … 90 93 91 94 /** 92 * Initialize this as a normal environment block. 93 * @returns IPRT status code. 94 */ 95 int initNormal(void) 96 { 97 AssertReturn(m_hEnv == NIL_RTENV, VERR_WRONG_ORDER); 98 return RTEnvCreate(&m_hEnv); 95 * Retains a reference to this object. 96 * @returns New reference count. 97 * @remarks Sharing an object is currently only safe if no changes are made to 98 * it because RTENV does not yet implement any locking. For the only 99 * purpose we need this, implementing IGuestProcess::environment by 100 * using IGuestSession::environmentBase, that's fine as the session 101 * base environment is immutable. 102 */ 103 uint32_t retain(void) 104 { 105 uint32_t cRefs = ASMAtomicIncU32(&m_cRefs); 106 Assert(cRefs > 1); Assert(cRefs < _1M); 107 return cRefs; 108 109 } 110 /** Useful shortcut. */ 111 uint32_t retainConst(void) const { return unconst(this)->retain(); } 112 113 /** 114 * Releases a reference to this object, deleting the object when reaching zero. 115 * @returns New reference count. 116 */ 117 uint32_t release(void) 118 { 119 uint32_t cRefs = ASMAtomicDecU32(&m_cRefs); 120 Assert(cRefs < _1M); 121 if (cRefs == 0) 122 delete this; 123 return cRefs; 124 } 125 126 /** Useful shortcut. */ 127 uint32_t releaseConst(void) const { return unconst(this)->retain(); } 128 129 /** 130 * Checks if the environment has been successfully initialized or not. 131 * 132 * @returns @c true if initialized, @c false if not. 133 */ 134 bool isInitialized(void) const 135 { 136 return m_hEnv != NIL_RTENV; 99 137 } 100 138 … … 167 205 return VINF_SUCCESS; 168 206 } 207 208 /** 209 * Applies the changes from another environment to this. 210 * 211 * @returns IPRT status code. 212 * @param rChanges Reference to an environment which variables will be 213 * imported and, if it's a change record, schedule 214 * variable unsets will be applied. 215 * @sa RTEnvApplyChanges 216 */ 217 int applyChanges(const GuestEnvironmentBase &rChanges) 218 { 219 return RTEnvApplyChanges(m_hEnv, rChanges.m_hEnv); 220 } 221 169 222 170 223 /** … … 219 272 220 273 /** 274 * Checks if the given variable exists. 275 * 276 * @returns @c true if it exists, @c false if not or if it's an scheduled unset 277 * in a environment change record. 278 * @param rName The variable name. 279 * @sa RTEnvExistEx 280 */ 281 bool doesVariableExist(const com::Utf8Str &rName) const 282 { 283 return RTEnvExistEx(m_hEnv, rName.c_str()); 284 } 285 286 /** 221 287 * Set an environment variable. 222 288 * … … 243 309 } 244 310 245 #if 0 246 private: 247 /* No copy operator. */ 248 GuestEnvironmentBase(const GuestEnvironmentBase &) { throw E_FAIL; } 249 #else 311 protected: 250 312 /** 251 313 * Copy constructor. … … 259 321 throw (Global::vboxStatusCodeToCOM(rc)); 260 322 } 261 #endif 262 263 protected: 323 264 324 /** 265 325 * Common clone/copy method with type conversion abilities. … … 304 364 305 365 /** The environment change record. */ 306 RTENV m_hEnv; 307 }; 308 309 310 #if 0 /* Not currently used. */ 366 RTENV m_hEnv; 367 /** Reference counter. */ 368 uint32_t volatile m_cRefs; 369 }; 370 371 311 372 /** 312 373 * Wrapper around the RTEnv API for a normal environment. … … 364 425 } 365 426 }; 366 #endif /* unused */367 427 368 428 … … 548 608 ProcessArguments mArguments; 549 609 /** The process environment change record. */ 550 GuestEnvironmentChanges mEnvironment ;610 GuestEnvironmentChanges mEnvironmentChanges; 551 611 /** Process creation flags. */ 552 612 uint32_t mFlags; … … 980 1040 protected: 981 1041 982 /** 983 * Commom parameters for all derived objects, when then have 984 * an own mData structure to keep their specific data around. 985 */ 986 1042 /** @name Common parameters for all derived objects. They have their own 1043 * mData structure to keep their specific data around. 1044 * @{ */ 987 1045 /** Pointer to parent session. Per definition 988 1046 * this objects *always* lives shorter than the 989 * parent. */ 1047 * parent. 1048 * @todo r=bird: When wanting to use mSession in the 1049 * IGuestProcess::getEnvironment() implementation I wanted to access 1050 * GuestSession::mData::mpBaseEnvironment. Seeing the comment in 1051 * GuestProcess::terminate() saying: 1052 * "Now only API clients still can hold references to it." 1053 * and recalling seeing similar things in VirtualBox.xidl or some such place, 1054 * I'm wondering how this "per definition" behavior is enforced. Is there any 1055 * GuestProcess:uninit() call or similar magic that invalidates objects that 1056 * GuestSession loses track of in place like GuestProcess::terminate() that I've 1057 * failed to spot? 1058 * 1059 * Please enlighten me. 1060 */ 990 1061 GuestSession *mSession; 991 1062 /** The object ID -- must be unique for each guest … … 996 1067 * for guest files this is the internal file ID. */ 997 1068 uint32_t mObjectID; 998 }; 999 #endif // ____H_GUESTIMPLPRIVATE 1000 1069 /** @} */ 1070 }; 1071 #endif // !____H_GUESTIMPLPRIVATE 1072 -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r51321 r55591 22 22 #include "GuestProcessWrap.h" 23 23 24 #include <iprt/cpp/utils.h> 25 24 26 class Console; 25 27 class GuestSession; … … 37 39 DECLARE_EMPTY_CTOR_DTOR(GuestProcess) 38 40 39 int init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessStartupInfo &aProcInfo); 41 int init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, 42 const GuestProcessStartupInfo &aProcInfo, const GuestEnvironment *pBaseEnv); 40 43 void uninit(void); 41 44 HRESULT FinalConstruct(void); … … 137 140 /** The process startup information. */ 138 141 GuestProcessStartupInfo mProcess; 142 /** Reference to the immutable session base environment. NULL if the 143 * environment feature isn't supported. 144 * @remarks If there is proof that the uninit order of GuestSession and 145 * this class is what GuestObjectBase claims, then this isn't 146 * strictly necessary. */ 147 GuestEnvironment const *mpSessionBaseEnv; 139 148 /** Exit code if process has been terminated. */ 140 149 LONG mExitCode; … … 146 155 * returned from the guest side. */ 147 156 int mLastError; 157 158 Data(void) : mpSessionBaseEnv(NULL) 159 { } 160 ~Data(void) 161 { 162 if (mpSessionBaseEnv) 163 { 164 mpSessionBaseEnv->releaseConst(); 165 mpSessionBaseEnv = NULL; 166 } 167 } 148 168 } mData; 149 169 }; -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r55590 r55591 268 268 HRESULT getProtocolVersion(ULONG *aProtocolVersion); 269 269 HRESULT getStatus(GuestSessionStatus_T *aStatus); 270 HRESULT getEnvironment(std::vector<com::Utf8Str> &aEnvironment); 271 HRESULT setEnvironment(const std::vector<com::Utf8Str> &aEnvironment); 270 HRESULT getEnvironmentChanges(std::vector<com::Utf8Str> &aEnvironmentChanges); 271 HRESULT setEnvironmentChanges(const std::vector<com::Utf8Str> &aEnvironmentChanges); 272 HRESULT getEnvironmentBase(std::vector<com::Utf8Str> &aEnvironmentBase); 272 273 HRESULT getProcesses(std::vector<ComPtr<IGuestProcess> > &aProcesses); 273 274 HRESULT getDirectories(std::vector<ComPtr<IGuestDirectory> > &aDirectories); … … 312 313 HRESULT directorySetACL(const com::Utf8Str &aPath, 313 314 const com::Utf8Str &aAcl); 314 HRESULT environmentSet(const com::Utf8Str &aName, 315 const com::Utf8Str &aValue); 316 HRESULT environmentUnset(const com::Utf8Str &aName); 315 HRESULT environmentScheduleSet(const com::Utf8Str &aName, 316 const com::Utf8Str &aValue); 317 HRESULT environmentScheduleUnset(const com::Utf8Str &aName); 318 HRESULT environmentGetBaseVariable(const com::Utf8Str &aName, 319 com::Utf8Str &aValue); 320 HRESULT environmentDoesBaseVariableExist(const com::Utf8Str &aName, 321 BOOL *aExists); 317 322 HRESULT fileCreateTemp(const com::Utf8Str &aTemplateName, 318 323 ULONG aMode, … … 469 474 /** The set of environment changes for the session for use when 470 475 * creating new guest processes. */ 471 GuestEnvironmentChanges mEnvironment; 476 GuestEnvironmentChanges mEnvironmentChanges; 477 /** Pointer to the immutable base environment for the session. 478 * @note This is not allocated until the guest reports it to the host. It is 479 * also shared with child processes. */ 480 GuestEnvironment const *mpBaseEnvironment; 472 481 /** Directory objects bound to this session. */ 473 482 SessionDirectories mDirectories; … … 488 497 * returned from the guest side. */ 489 498 int mRC; 499 500 Data(void) 501 : mpBaseEnvironment(NULL) 502 { } 503 Data(const Data &rThat) 504 : mCredentials(rThat.mCredentials) 505 , mSession(rThat.mSession) 506 , mStatus(rThat.mStatus) 507 , mEnvironmentChanges(rThat.mEnvironmentChanges) 508 , mpBaseEnvironment(NULL) 509 , mDirectories(rThat.mDirectories) 510 , mFiles(rThat.mFiles) 511 , mProcesses(rThat.mProcesses) 512 , mProtocolVersion(rThat.mProtocolVersion) 513 , mTimeout(rThat.mTimeout) 514 , mNumObjects(rThat.mNumObjects) 515 , mRC(rThat.mRC) 516 { } 490 517 } mData; 491 518 }; -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r55588 r55591 162 162 ///////////////////////////////////////////////////////////////////////////// 163 163 164 int GuestProcess::init(Console *aConsole, GuestSession *aSession, 165 ULONG aProcessID, const GuestProcessStartupInfo &aProcInfo)166 { 167 LogFlowThisFunc(("aConsole=%p, aSession=%p, aProcessID=%RU32 \n",168 aConsole, aSession, aProcessID ));164 int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, 165 const GuestProcessStartupInfo &aProcInfo, const GuestEnvironment *pBaseEnv) 166 { 167 LogFlowThisFunc(("aConsole=%p, aSession=%p, aProcessID=%RU32 pBaseEnv=%p\n", 168 aConsole, aSession, aProcessID, pBaseEnv)); 169 169 170 170 AssertPtrReturn(aConsole, VERR_INVALID_POINTER); … … 237 237 { 238 238 mData.mProcess = aProcInfo; 239 mData.mpSessionBaseEnv = pBaseEnv; 240 if (pBaseEnv) 241 pBaseEnv->retainConst(); 239 242 mData.mExitCode = 0; 240 243 mData.mPID = 0; … … 274 277 * case of failure. */ 275 278 279 if (mData.mpSessionBaseEnv) 280 { 281 mData.mpSessionBaseEnv->releaseConst(); 282 mData.mpSessionBaseEnv = NULL; 283 } 284 276 285 baseUninit(); 277 286 … … 298 307 HRESULT GuestProcess::getEnvironment(std::vector<com::Utf8Str> &aEnvironment) 299 308 { 300 #ifndef VBOX_W ITH_GUEST_CONTROL309 #ifndef VBOX_WTIH_GUEST_CONTROL 301 310 ReturnComNotImplemented(); 302 311 #else 303 LogFlowThisFuncEnter(); 304 305 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 306 mData.mProcess.mEnvironment.queryPutEnvArray(&aEnvironment); 307 return S_OK; 308 #endif /* VBOX_WITH_GUEST_CONTROL */ 312 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); /* (Paranoia since both environment objects are immutable.) */ 313 HRESULT hrc; 314 if (mData.mpSessionBaseEnv) 315 { 316 int vrc; 317 if (mData.mProcess.mEnvironmentChanges.count() == 0) 318 vrc = mData.mpSessionBaseEnv->queryPutEnvArray(&aEnvironment); 319 else 320 { 321 GuestEnvironment TmpEnv; 322 vrc = TmpEnv.copy(*mData.mpSessionBaseEnv); 323 if (RT_SUCCESS(vrc)) 324 { 325 vrc = TmpEnv.applyChanges(mData.mProcess.mEnvironmentChanges); 326 if (RT_SUCCESS(rc)) 327 vrc = TmpEnv.queryPutEnvArray(&aEnvironment); 328 } 329 } 330 hrc = Global::vboxStatusCodeToCOM(vrc); 331 } 332 else 333 hrc = setError(VBOX_E_NOT_SUPPORTED, tr("The base environment feature is not supported by the guest additions")); 334 LogFlowThisFuncLeave(); 335 return hrc; 336 #endif 309 337 } 310 338 … … 1057 1085 char *pszzEnvBlock; 1058 1086 if (RT_SUCCESS(vrc)) 1059 vrc = mData.mProcess.mEnvironment .queryUtf8Block(&pszzEnvBlock, &cbEnvBlock);1087 vrc = mData.mProcess.mEnvironmentChanges.queryUtf8Block(&pszzEnvBlock, &cbEnvBlock); 1060 1088 1061 1089 if (RT_SUCCESS(vrc)) … … 1069 1097 paParms[i++].setUInt32((uint32_t)mData.mProcess.mArguments.size()); 1070 1098 paParms[i++].setPointer(pszArgs, (uint32_t)cbArgs); 1071 paParms[i++].setUInt32(mData.mProcess.mEnvironment .count());1099 paParms[i++].setUInt32(mData.mProcess.mEnvironmentChanges.count()); 1072 1100 paParms[i++].setUInt32((uint32_t)cbEnvBlock); 1073 1101 paParms[i++].setPointer(pszzEnvBlock, (uint32_t)cbEnvBlock); … … 1109 1137 } 1110 1138 1111 mData.mProcess.mEnvironment .freeUtf8Block(pszzEnvBlock);1139 mData.mProcess.mEnvironmentChanges.freeUtf8Block(pszzEnvBlock); 1112 1140 } 1113 1141 -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r55590 r55591 205 205 mData.mStatus = GuestSessionStatus_Undefined; 206 206 mData.mNumObjects = 0; 207 int rc = mData.mEnvironment.initNormal(); 207 mData.mpBaseEnvironment = NULL; 208 int rc = mData.mEnvironmentChanges.initChangeRecord(); 208 209 if (RT_SUCCESS(rc)) 209 210 { … … 320 321 mData.mProcesses.clear(); 321 322 322 mData.mEnvironment.reset(); 323 mData.mEnvironmentChanges.reset(); 324 325 if (mData.mpBaseEnvironment) 326 { 327 GuestEnvironment *pBaseEnv = unconst(mData.mpBaseEnvironment); 328 mData.mpBaseEnvironment = NULL; 329 pBaseEnv->release(); 330 } 323 331 324 332 AssertMsg(mData.mNumObjects == 0, … … 462 470 } 463 471 464 HRESULT GuestSession::getEnvironment (std::vector<com::Utf8Str> &aEnvironment)472 HRESULT GuestSession::getEnvironmentChanges(std::vector<com::Utf8Str> &aEnvironmentChanges) 465 473 { 466 474 #ifndef VBOX_WITH_GUEST_CONTROL … … 471 479 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 472 480 473 int vrc = mData.mEnvironment .queryPutEnvArray(&aEnvironment);481 int vrc = mData.mEnvironmentChanges.queryPutEnvArray(&aEnvironmentChanges); 474 482 475 483 LogFlowFuncLeaveRC(vrc); … … 478 486 } 479 487 480 HRESULT GuestSession::setEnvironment (const std::vector<com::Utf8Str> &aEnvironment)488 HRESULT GuestSession::setEnvironmentChanges(const std::vector<com::Utf8Str> &aEnvironmentChanges) 481 489 { 482 490 #ifndef VBOX_WITH_GUEST_CONTROL … … 487 495 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 488 496 489 mData.mEnvironment .reset();490 int vrc = mData.mEnvironment .applyPutEnvArray(aEnvironment);497 mData.mEnvironmentChanges.reset(); 498 int vrc = mData.mEnvironmentChanges.applyPutEnvArray(aEnvironmentChanges); 491 499 492 500 LogFlowFuncLeaveRC(vrc); 493 501 return Global::vboxStatusCodeToCOM(vrc); 502 #endif /* VBOX_WITH_GUEST_CONTROL */ 503 } 504 505 HRESULT GuestSession::getEnvironmentBase(std::vector<com::Utf8Str> &aEnvironmentBase) 506 { 507 #ifndef VBOX_WITH_GUEST_CONTROL 508 ReturnComNotImplemented(); 509 #else 510 LogFlowThisFuncEnter(); 511 512 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 513 HRESULT hrc; 514 if (mData.mpBaseEnvironment) 515 { 516 int vrc = mData.mpBaseEnvironment->queryPutEnvArray(&aEnvironmentBase); 517 hrc = Global::vboxStatusCodeToCOM(vrc); 518 } 519 else if (mData.mProtocolVersion < 99999) 520 hrc = setError(VBOX_E_NOT_SUPPORTED, tr("The base environment feature is not supported by the guest additions")); 521 else 522 hrc = setError(VBOX_E_INVALID_OBJECT_STATE, tr("The base environment has not yet been reported by the guest")); 523 524 LogFlowFuncLeave(); 525 return hrc; 494 526 #endif /* VBOX_WITH_GUEST_CONTROL */ 495 527 } … … 1917 1949 1918 1950 rc = pProcess->init(mParent->i_getConsole() /* Console */, this /* Session */, 1919 uNewProcessID, procInfo );1951 uNewProcessID, procInfo, mData.mpBaseEnvironment); 1920 1952 if (RT_FAILURE(rc)) 1921 1953 return rc; … … 2904 2936 } 2905 2937 2906 HRESULT GuestSession::environmentS et(const com::Utf8Str &aName, const com::Utf8Str &aValue)2938 HRESULT GuestSession::environmentScheduleSet(const com::Utf8Str &aName, const com::Utf8Str &aValue) 2907 2939 { 2908 2940 #ifndef VBOX_WITH_GUEST_CONTROL … … 2917 2949 { 2918 2950 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2919 int vrc = mData.mEnvironment .setVariable(aName, aValue);2951 int vrc = mData.mEnvironmentChanges.setVariable(aName, aValue); 2920 2952 if (RT_SUCCESS(vrc)) 2921 2953 hrc = S_OK; … … 2934 2966 } 2935 2967 2936 HRESULT GuestSession::environment Unset(const com::Utf8Str &aName)2968 HRESULT GuestSession::environmentScheduleUnset(const com::Utf8Str &aName) 2937 2969 { 2938 2970 #ifndef VBOX_WITH_GUEST_CONTROL … … 2946 2978 { 2947 2979 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2948 int vrc = mData.mEnvironment .unsetVariable(aName);2980 int vrc = mData.mEnvironmentChanges.unsetVariable(aName); 2949 2981 if (RT_SUCCESS(vrc)) 2950 2982 hrc = S_OK; 2951 2983 else 2952 2984 hrc = setErrorVrc(vrc); 2985 } 2986 else 2987 hrc = setError(E_INVALIDARG, tr("The equal char is not allowed in environment variable names")); 2988 } 2989 else 2990 hrc = setError(E_INVALIDARG, tr("No variable name specified")); 2991 2992 LogFlowThisFuncLeave(); 2993 return hrc; 2994 #endif /* VBOX_WITH_GUEST_CONTROL */ 2995 } 2996 2997 HRESULT GuestSession::environmentGetBaseVariable(const com::Utf8Str &aName, com::Utf8Str &aValue) 2998 { 2999 #ifndef VBOX_WITH_GUEST_CONTROL 3000 ReturnComNotImplemented(); 3001 #else 3002 LogFlowThisFuncEnter(); 3003 HRESULT hrc; 3004 if (RT_LIKELY(aName.isNotEmpty())) 3005 { 3006 if (RT_LIKELY(strchr(aName.c_str(), '=') == NULL)) 3007 { 3008 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 3009 if (mData.mpBaseEnvironment) 3010 { 3011 int vrc = mData.mpBaseEnvironment->getVariable(aName, &aValue); 3012 if (RT_SUCCESS(vrc)) 3013 hrc = S_OK; 3014 else 3015 hrc = setErrorVrc(vrc); 3016 } 3017 else if (mData.mProtocolVersion < 99999) 3018 hrc = setError(VBOX_E_NOT_SUPPORTED, tr("The base environment feature is not supported by the guest additions")); 3019 else 3020 hrc = setError(VBOX_E_INVALID_OBJECT_STATE, tr("The base environment has not yet been reported by the guest")); 3021 } 3022 else 3023 hrc = setError(E_INVALIDARG, tr("The equal char is not allowed in environment variable names")); 3024 } 3025 else 3026 hrc = setError(E_INVALIDARG, tr("No variable name specified")); 3027 3028 LogFlowThisFuncLeave(); 3029 return hrc; 3030 #endif /* VBOX_WITH_GUEST_CONTROL */ 3031 } 3032 3033 HRESULT GuestSession::environmentDoesBaseVariableExist(const com::Utf8Str &aName, BOOL *aExists) 3034 { 3035 #ifndef VBOX_WITH_GUEST_CONTROL 3036 ReturnComNotImplemented(); 3037 #else 3038 LogFlowThisFuncEnter(); 3039 *aExists = FALSE; 3040 HRESULT hrc; 3041 if (RT_LIKELY(aName.isNotEmpty())) 3042 { 3043 if (RT_LIKELY(strchr(aName.c_str(), '=') == NULL)) 3044 { 3045 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 3046 if (mData.mpBaseEnvironment) 3047 { 3048 hrc = S_OK; 3049 *aExists = mData.mpBaseEnvironment->doesVariableExist(aName); 3050 } 3051 else if (mData.mProtocolVersion < 99999) 3052 hrc = setError(VBOX_E_NOT_SUPPORTED, tr("The base environment feature is not supported by the guest additions")); 3053 else 3054 hrc = setError(VBOX_E_INVALID_OBJECT_STATE, tr("The base environment has not yet been reported by the guest")); 2953 3055 } 2954 3056 else … … 3345 3447 the caller, giving priority to the latter. The changes are putenv style 3346 3448 and will be applied to the standard environment for the guest user. */ 3347 int vrc = procInfo.mEnvironment .copy(mData.mEnvironment);3449 int vrc = procInfo.mEnvironmentChanges.copy(mData.mEnvironmentChanges); 3348 3450 if (RT_SUCCESS(vrc)) 3349 vrc = procInfo.mEnvironment .applyPutEnvArray(aEnvironment);3451 vrc = procInfo.mEnvironmentChanges.applyPutEnvArray(aEnvironment); 3350 3452 if (RT_SUCCESS(vrc)) 3351 3453 { -
trunk/src/VBox/ValidationKit/tests/additions/tdAddGuestCtrl.py
r55590 r55591 1070 1070 def testGuestCtrlSessionEnvironment(self, oSession, oTxsSession, oTestVm): # pylint: disable=R0914 1071 1071 """ 1072 Tests the guest session environment .1072 Tests the guest session environment changes. 1073 1073 """ 1074 1074 … … 1112 1112 ]; 1113 1113 1114 # The IGuestSession::environment attribute changed late in 5.0 development. 1115 sEnvironmentChangesAttr = 'environmentChanges' if self.oTstDrv.fpApiVer >= 5.0 else 'environment'; 1116 1114 1117 # Parameters. 1115 1118 fRc = True; … … 1127 1130 break; 1128 1131 # Make sure environment is empty. 1129 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, 'environment');1132 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr); 1130 1133 reporter.log2('Test #%d: Environment initially has %d elements' % (i, len(curEnv))); 1131 1134 if len(curEnv) != 0: … … 1145 1148 % (i, strKey, strValue, len(aElems))); 1146 1149 try: 1147 curGuestSession.environmentSet(strKey, strValue); # No return (e.g. boolean) value available thru wrapper. 1150 if self.oTstDrv.fpApiVer >= 5.0: 1151 curGuestSession.environmentScheduleSet(strKey, strValue); 1152 else: 1153 curGuestSession.environmentSet(strKey, strValue); 1148 1154 except: 1149 1155 # Setting environment variables might fail (e.g. if empty name specified). Check. 1150 1156 reporter.logXcpt('Test #%d failed: Setting environment variable failed:' % (i,)); 1151 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, 'environment');1157 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr); 1152 1158 if len(curEnv) is not curRes.cNumVars: 1153 1159 reporter.error('Test #%d failed: Session environment has %d vars, expected %d' \ … … 1158 1164 reporter.log('Test #%d: API reported an error (single), good' % (i,)); 1159 1165 ## @todo environmentGet() has been removed in 5.0 because it's not up to the task of returning all the 1160 ## putenv strings forms and gives the impression that the env rionment is something it isn't. This test1166 ## putenv strings forms and gives the impression that the environment is something it isn't. This test 1161 1167 ## should be rewritten using the attribute. What's more, there should be an Unset test here, shouldn't 1162 1168 ## there? … … 1197 1203 except: 1198 1204 # Setting environment variables might fail (e.g. if empty name specified). Check. 1199 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, 'environment');1205 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr); 1200 1206 if len(curEnv) is not curRes.cNumVars: 1201 1207 reporter.error('Test #%d failed: Session environment has %d vars, expected %d (array)' \ … … 1207 1213 ## @todo Get current system environment and add it to curRes.cNumVars before comparing! 1208 1214 reporter.log('Test #%d: Environment size' % (i,)); 1209 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, 'environment');1215 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr); 1210 1216 reporter.log2('Test #%d: Environment (%d) -> %s' % (i, len(curEnv), curEnv)); 1211 1217 if len(curEnv) != curRes.cNumVars: … … 1215 1221 break; 1216 1222 1217 self.oTstDrv.oVBoxMgr.setArray(curGuestSession, 'environment', []);1218 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, 'environment');1223 self.oTstDrv.oVBoxMgr.setArray(curGuestSession, sEnvironmentChangesAttr, []); 1224 curEnv = self.oTstDrv.oVBoxMgr.getArray(curGuestSession, sEnvironmentChangesAttr); 1219 1225 if len(curEnv) is not 0: 1220 1226 reporter.error('Test #%d failed: Session environment has %d vars, expected 0');
Note:
See TracChangeset
for help on using the changeset viewer.