VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/GuestCtrlImplFile.cpp@ 42699

Last change on this file since 42699 was 40685, checked in by vboxsync, 13 years ago

Main/GuestCtrl: Introduced host<->guest PID mapping for immediate returns of executeProcess(); bugfixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
1/* $Id: */
2/** @file
3 * VirtualBox Guest Control - Guest file handling.
4 */
5
6/*
7 * Copyright (C) 2011 Oracle Corporation
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "GuestImpl.h"
19#include "GuestCtrlImplPrivate.h"
20
21#include "Global.h"
22#include "ConsoleImpl.h"
23#include "ProgressImpl.h"
24#include "VMMDev.h"
25
26#include "AutoCaller.h"
27#include "Logging.h"
28
29#include <VBox/VMMDev.h>
30#ifdef VBOX_WITH_GUEST_CONTROL
31# include <VBox/com/array.h>
32# include <VBox/com/ErrorInfo.h>
33#endif
34
35STDMETHODIMP Guest::FileExists(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR aPassword, BOOL *aExists)
36{
37#ifndef VBOX_WITH_GUEST_CONTROL
38 ReturnComNotImplemented();
39#else /* VBOX_WITH_GUEST_CONTROL */
40 using namespace guestControl;
41
42 CheckComArgStrNotEmptyOrNull(aFile);
43
44 /* Do not allow anonymous executions (with system rights). */
45 if (RT_UNLIKELY((aUsername) == NULL || *(aUsername) == '\0'))
46 return setError(E_INVALIDARG, tr("No user name specified"));
47
48 /* If filename ends with a slash or backslash we assume it's a directory and
49 * call the appropriate function instead the regular one just for files. */
50 Utf8Str Utf8File(aFile);
51 if ( Utf8File.endsWith("/")
52 || Utf8File.endsWith("\\"))
53 {
54 return directoryExistsInternal(aFile, aUsername, aPassword, aExists);
55 }
56 return fileExistsInternal(aFile,
57 aUsername, aPassword, aExists);
58#endif
59}
60
61#ifdef VBOX_WITH_GUEST_CONTROL
62HRESULT Guest::fileExistsInternal(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR aPassword, BOOL *aExists)
63{
64 using namespace guestControl;
65
66 CheckComArgStrNotEmptyOrNull(aFile);
67
68 AutoCaller autoCaller(this);
69 if (FAILED(autoCaller.rc())) return autoCaller.rc();
70
71 int rc;
72 HRESULT hr = fileQueryInfoInternal(aFile,
73 aUsername, aPassword,
74 NULL /* No RTFSOBJINFO needed */,
75 RTFSOBJATTRADD_NOTHING, &rc);
76 if (SUCCEEDED(hr))
77 {
78 switch (rc)
79 {
80 case VINF_SUCCESS:
81 *aExists = TRUE;
82 break;
83
84 case VERR_FILE_NOT_FOUND:
85 *aExists = FALSE;
86 break;
87
88 default:
89 hr = setError(VBOX_E_IPRT_ERROR,
90 Guest::tr("Unable to query file existence (%Rrc)"), rc);
91 break;
92 }
93 }
94 return hr;
95}
96
97HRESULT Guest::fileQueryInfoInternal(IN_BSTR aFile,
98 IN_BSTR aUsername, IN_BSTR aPassword,
99 PRTFSOBJINFO aObjInfo, RTFSOBJATTRADD enmAddAttribs,
100 int *pRC)
101{
102 using namespace guestControl;
103
104 /* aUsername is optional. */
105 /* aPassword is optional. */
106 /* aObjInfo is optional. */
107
108 HRESULT hr;
109 try
110 {
111 Utf8Str Utf8File(aFile);
112 Utf8Str Utf8Username(aUsername);
113 Utf8Str Utf8Password(aPassword);
114
115 com::SafeArray<IN_BSTR> args;
116 com::SafeArray<IN_BSTR> env;
117
118 /*
119 * Prepare tool command line.
120 */
121
122 /* We need to get output which is machine-readable in form
123 * of "key=value\0..key=value\0\0". */
124 args.push_back(Bstr("--machinereadable").raw());
125
126 /* Only the actual file name to chekc is needed for now. */
127 args.push_back(Bstr(Utf8File).raw());
128
129 /*
130 * Execute guest process.
131 */
132 ULONG uPID;
133 GuestCtrlStreamObjects stdOut;
134 ComPtr<IProgress> pProgress;
135 hr = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_STAT).raw(), Bstr("Querying file information").raw(),
136 ComSafeArrayAsInParam(args),
137 ComSafeArrayAsInParam(env),
138 aUsername, aPassword,
139 ExecuteProcessFlag_WaitForStdOut,
140 &stdOut, NULL,
141 pProgress.asOutParam(), &uPID);
142 if (SUCCEEDED(hr))
143 {
144 hr = setErrorFromProgress(pProgress);
145 if (SUCCEEDED(hr))
146 {
147 int rc = VINF_SUCCESS;
148 if (stdOut.size())
149 {
150#if 0
151 /* Dump the parsed stream contents to Log(). */
152 stdOut[0].Dump();
153#endif
154 const char *pszFsType = stdOut[0].GetString("ftype");
155 if (!pszFsType) /* Was an object found at all? */
156 rc = VERR_FILE_NOT_FOUND;
157 if ( RT_SUCCESS(rc)
158 && strcmp(pszFsType, "-")) /* Regular file? */
159 {
160 rc = VERR_FILE_NOT_FOUND;
161 /* This is not critical for Main, so don't set hr --
162 * we will take care of rc then. */
163 }
164 if ( RT_SUCCESS(rc)
165 && aObjInfo) /* Do we want object details? */
166 {
167 rc = executeStreamQueryFsObjInfo(aFile, stdOut[0],
168 aObjInfo, enmAddAttribs);
169 }
170 }
171 else
172 rc = VERR_NO_DATA;
173
174 if (pRC)
175 *pRC = rc;
176 }
177
178 pProgress.setNull();
179 }
180 }
181 catch (std::bad_alloc &)
182 {
183 hr = E_OUTOFMEMORY;
184 }
185
186 return hr;
187}
188#endif /* VBOX_WITH_GUEST_CONTROL */
189
190STDMETHODIMP Guest::FileQuerySize(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR aPassword, LONG64 *aSize)
191{
192#ifndef VBOX_WITH_GUEST_CONTROL
193 ReturnComNotImplemented();
194#else /* VBOX_WITH_GUEST_CONTROL */
195 using namespace guestControl;
196
197 CheckComArgStrNotEmptyOrNull(aFile);
198
199 /* Do not allow anonymous executions (with system rights). */
200 if (RT_UNLIKELY((aUsername) == NULL || *(aUsername) == '\0'))
201 return setError(E_INVALIDARG, tr("No user name specified"));
202
203 AutoCaller autoCaller(this);
204 if (FAILED(autoCaller.rc())) return autoCaller.rc();
205
206 return fileQuerySizeInternal(aFile,
207 aUsername, aPassword, aSize);
208#endif
209}
210
211#ifdef VBOX_WITH_GUEST_CONTROL
212HRESULT Guest::fileQuerySizeInternal(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR aPassword, LONG64 *aSize)
213{
214 using namespace guestControl;
215
216 CheckComArgStrNotEmptyOrNull(aFile);
217
218 int rc;
219 RTFSOBJINFO objInfo;
220 HRESULT hr = fileQueryInfoInternal(aFile,
221 aUsername, aPassword,
222 &objInfo, RTFSOBJATTRADD_NOTHING, &rc);
223 if (SUCCEEDED(hr))
224 {
225 switch (rc)
226 {
227 case VINF_SUCCESS:
228 *aSize = objInfo.cbObject;
229 break;
230
231 case VERR_FILE_NOT_FOUND:
232 hr = setError(VBOX_E_IPRT_ERROR,
233 Guest::tr("File not found"));
234 break;
235
236 default:
237 hr = setError(VBOX_E_IPRT_ERROR,
238 Guest::tr("Unable to query file size (%Rrc)"), rc);
239 break;
240 }
241 }
242
243 return hr;
244}
245#endif /* VBOX_WITH_GUEST_CONTROL */
246
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