VirtualBox

source: vbox/trunk/src/VBox/Main/SharedFolderImpl.cpp@ 4040

Last change on this file since 4040 was 4040, checked in by vboxsync, 17 years ago

Main: Converted SharedFolder class to the new locking scheme.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#include "SharedFolderImpl.h"
23#include "VirtualBoxImpl.h"
24#include "MachineImpl.h"
25#include "ConsoleImpl.h"
26
27#include "Logging.h"
28
29#include <iprt/param.h>
30#include <iprt/path.h>
31#include <iprt/cpputils.h>
32
33// constructor / destructor
34/////////////////////////////////////////////////////////////////////////////
35
36SharedFolder::SharedFolder()
37 : mParent (NULL)
38{
39}
40
41SharedFolder::~SharedFolder()
42{
43}
44
45HRESULT SharedFolder::FinalConstruct()
46{
47 return S_OK;
48}
49
50void SharedFolder::FinalRelease()
51{
52 uninit();
53}
54
55// public initializer/uninitializer for internal purposes only
56/////////////////////////////////////////////////////////////////////////////
57
58/**
59 * Initializes the shared folder object.
60 *
61 * @param aMachine parent Machine object
62 * @param aName logical name of the shared folder
63 * @param aHostPath full path to the shared folder on the host
64 *
65 * @return COM result indicator
66 */
67HRESULT SharedFolder::init (Machine *aMachine,
68 const BSTR aName, const BSTR aHostPath)
69{
70 /* Enclose the state transition NotReady->InInit->Ready */
71 AutoInitSpan autoInitSpan (this);
72 AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
73
74 unconst (mMachine) = aMachine;
75
76 HRESULT rc = protectedInit (aMachine, aName, aHostPath);
77
78 /* Confirm a successful initialization when it's the case */
79 if (SUCCEEDED (rc))
80 autoInitSpan.setSucceeded();
81
82 return rc;
83}
84
85/**
86 * Initializes the shared folder object given another object
87 * (a kind of copy constructor). This object makes a private copy of data
88 * of the original object passed as an argument.
89 *
90 * @param aMachine parent Machine object
91 * @param aThat shared folder object to copy
92 *
93 * @return COM result indicator
94 */
95HRESULT SharedFolder::initCopy (Machine *aMachine, SharedFolder *aThat)
96{
97 ComAssertRet (aThat, E_INVALIDARG);
98
99 /* Enclose the state transition NotReady->InInit->Ready */
100 AutoInitSpan autoInitSpan (this);
101 AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
102
103 unconst (mMachine) = aMachine;
104
105 HRESULT rc = protectedInit (aMachine, aThat->mData.mName,
106 aThat->mData.mHostPath);
107
108 /* Confirm a successful initialization when it's the case */
109 if (SUCCEEDED (rc))
110 autoInitSpan.setSucceeded();
111
112 return rc;
113}
114
115/**
116 * Initializes the shared folder object.
117 *
118 * @param aConsole Console parent object
119 * @param aName logical name of the shared folder
120 * @param aHostPath full path to the shared folder on the host
121 *
122 * @return COM result indicator
123 */
124HRESULT SharedFolder::init (Console *aConsole,
125 const BSTR aName, const BSTR aHostPath)
126{
127 /* Enclose the state transition NotReady->InInit->Ready */
128 AutoInitSpan autoInitSpan (this);
129 AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
130
131 unconst (mConsole) = aConsole;
132
133 HRESULT rc = protectedInit (aConsole, aName, aHostPath);
134
135 /* Confirm a successful initialization when it's the case */
136 if (SUCCEEDED (rc))
137 autoInitSpan.setSucceeded();
138
139 return rc;
140}
141
142/**
143 * Initializes the shared folder object.
144 *
145 * @param aVirtualBox VirtualBox parent object
146 * @param aName logical name of the shared folder
147 * @param aHostPath full path to the shared folder on the host
148 *
149 * @return COM result indicator
150 */
151HRESULT SharedFolder::init (VirtualBox *aVirtualBox,
152 const BSTR aName, const BSTR aHostPath)
153{
154 /* Enclose the state transition NotReady->InInit->Ready */
155 AutoInitSpan autoInitSpan (this);
156 AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
157
158 unconst (mVirtualBox) = aVirtualBox;
159
160 HRESULT rc = protectedInit (aVirtualBox, aName, aHostPath);
161
162 /* Confirm a successful initialization when it's the case */
163 if (SUCCEEDED (rc))
164 autoInitSpan.setSucceeded();
165
166 return rc;
167}
168
169/**
170 * Helper for init() methods.
171 *
172 * @note
173 * Must be called from under the object's lock!
174 */
175HRESULT SharedFolder::protectedInit (VirtualBoxBaseWithChildrenNEXT *aParent,
176 const BSTR aName, const BSTR aHostPath)
177{
178 LogFlowThisFunc (("aName={%ls}, aHostPath={%ls}\n", aName, aHostPath));
179
180 ComAssertRet (aParent && aName && aHostPath, E_INVALIDARG);
181
182 Utf8Str hostPath = Utf8Str (aHostPath);
183 size_t hostPathLen = hostPath.length();
184
185 /* Remove the trailng slash unless it's a root directory
186 * (otherwise the comparison with the RTPathAbs() result will fail at least
187 * on Linux). Note that this isn't really necessary for the shared folder
188 * itself, since adding a mapping eventually results into a
189 * RTDirOpenFiltered() call (see HostServices/SharedFolders) that seems to
190 * accept both the slashified paths and not. */
191#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
192 if (hostPathLen > 2 &&
193 RTPATH_IS_SEP (hostPath.raw()[hostPathLen - 1]) &&
194 RTPATH_IS_VOLSEP (hostPath.raw()[hostPathLen - 2]))
195 ;
196#else
197 if (hostPathLen == 1 && RTPATH_IS_SEP (hostPath[0]))
198 ;
199#endif
200 else
201 RTPathStripTrailingSlash (hostPath.mutableRaw());
202
203 /* Check whether the path is full (absolute) */
204 char hostPathFull [RTPATH_MAX];
205 int vrc = RTPathAbsEx (NULL, hostPath,
206 hostPathFull, sizeof (hostPathFull));
207 if (VBOX_FAILURE (vrc))
208 return setError (E_INVALIDARG,
209 tr ("Invalid shared folder path: '%s' (%Vrc)"), hostPath.raw(), vrc);
210
211 if (RTPathCompare (hostPath, hostPathFull) != 0)
212 return setError (E_INVALIDARG,
213 tr ("Shared folder path '%s' is not absolute"), hostPath.raw());
214
215 unconst (mParent) = aParent;
216
217 /* register with parent */
218 mParent->addDependentChild (this);
219
220 unconst (mData.mName) = aName;
221 unconst (mData.mHostPath) = hostPath;
222
223 return S_OK;
224}
225
226/**
227 * Uninitializes the instance and sets the ready flag to FALSE.
228 * Called either from FinalRelease() or by the parent when it gets destroyed.
229 */
230void SharedFolder::uninit()
231{
232 LogFlowThisFunc (("\n"));
233
234 /* Enclose the state transition Ready->InUninit->NotReady */
235 AutoUninitSpan autoUninitSpan (this);
236 if (autoUninitSpan.uninitDone())
237 return;
238
239 if (mParent)
240 mParent->removeDependentChild (this);
241
242 unconst (mParent) = NULL;
243
244 unconst (mMachine).setNull();
245 unconst (mConsole).setNull();
246 unconst (mVirtualBox).setNull();
247}
248
249// ISharedFolder properties
250/////////////////////////////////////////////////////////////////////////////
251
252STDMETHODIMP SharedFolder::COMGETTER(Name) (BSTR *aName)
253{
254 if (!aName)
255 return E_POINTER;
256
257 AutoCaller autoCaller (this);
258 CheckComRCReturnRC (autoCaller.rc());
259
260 /* mName is constant during life time, no need to lock */
261 mData.mName.cloneTo (aName);
262
263 return S_OK;
264}
265
266STDMETHODIMP SharedFolder::COMGETTER(HostPath) (BSTR *aHostPath)
267{
268 if (!aHostPath)
269 return E_POINTER;
270
271 AutoCaller autoCaller (this);
272 CheckComRCReturnRC (autoCaller.rc());
273
274 /* mHostPath is constant during life time, no need to lock */
275 mData.mHostPath.cloneTo (aHostPath);
276
277 return S_OK;
278}
279
280STDMETHODIMP SharedFolder::COMGETTER(Accessible) (BOOL *aAccessible)
281{
282 if (!aAccessible)
283 return E_POINTER;
284
285 AutoCaller autoCaller (this);
286 CheckComRCReturnRC (autoCaller.rc());
287
288 /* mName and mHostPath are constant during life time, no need to lock */
289
290 /* check whether the host path exists */
291 Utf8Str hostPath = Utf8Str (mData.mHostPath);
292 char hostPathFull [RTPATH_MAX];
293 int vrc = RTPathExists(hostPath) ? RTPathReal (hostPath, hostPathFull,
294 sizeof (hostPathFull))
295 : VERR_PATH_NOT_FOUND;
296 if (VBOX_SUCCESS (vrc))
297 {
298 *aAccessible = TRUE;
299 return S_OK;
300 }
301
302 HRESULT rc = S_OK;
303 if (vrc != VERR_PATH_NOT_FOUND)
304 rc = setError (E_FAIL,
305 tr ("Invalid shared folder path: '%s' (%Vrc)"), hostPath.raw(), vrc);
306
307 LogWarningThisFunc (("'%s' is not accessible (%Vrc)\n", hostPath.raw(), vrc));
308
309 *aAccessible = FALSE;
310 return S_OK;
311}
312
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette