VirtualBox

source: vbox/trunk/src/VBox/GuestHost/DragAndDrop/DnDURIObject.cpp@ 69474

Last change on this file since 69474 was 62816, checked in by vboxsync, 8 years ago

GuestHost/DragAndDrop: warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1/* $Id: DnDURIObject.cpp 62816 2016-08-01 13:02:02Z vboxsync $ */
2/** @file
3 * DnD: URI object class. For handling creation/reading/writing to files and directories
4 * on host or guest side.
5 */
6
7/*
8 * Copyright (C) 2014-2016 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19
20/*********************************************************************************************************************************
21* Header Files *
22*********************************************************************************************************************************/
23
24#include <iprt/dir.h>
25#include <iprt/file.h>
26#include <iprt/fs.h>
27#include <iprt/path.h>
28#include <iprt/uri.h>
29
30#ifdef LOG_GROUP
31 #undef LOG_GROUP
32#endif
33#define LOG_GROUP LOG_GROUP_GUEST_DND
34#include <VBox/log.h>
35
36#include <VBox/GuestHost/DragAndDrop.h>
37
38DnDURIObject::DnDURIObject(void)
39 : m_Type(Unknown)
40 , m_fOpen(false)
41 , m_fMode(0)
42 , m_cbSize(0)
43 , m_cbProcessed(0)
44{
45 RT_ZERO(u);
46}
47
48DnDURIObject::DnDURIObject(Type type,
49 const RTCString &strSrcPath /* = 0 */,
50 const RTCString &strDstPath /* = 0 */,
51 uint32_t fMode /* = 0 */, uint64_t cbSize /* = 0 */)
52 : m_Type(type)
53 , m_strSrcPath(strSrcPath)
54 , m_strTgtPath(strDstPath)
55 , m_fOpen(false)
56 , m_fMode(fMode)
57 , m_cbSize(cbSize)
58 , m_cbProcessed(0)
59{
60}
61
62DnDURIObject::~DnDURIObject(void)
63{
64 closeInternal();
65}
66
67void DnDURIObject::closeInternal(void)
68{
69 LogFlowThisFuncEnter();
70
71 if (!m_fOpen)
72 return;
73
74 switch (m_Type)
75 {
76 case File:
77 {
78 RTFileClose(u.m_hFile);
79 u.m_hFile = NIL_RTFILE;
80 break;
81 }
82
83 case Directory:
84 break;
85
86 default:
87 break;
88 }
89
90 m_fOpen = false;
91}
92
93void DnDURIObject::Close(void)
94{
95 closeInternal();
96}
97
98bool DnDURIObject::IsComplete(void) const
99{
100 bool fComplete;
101
102 switch (m_Type)
103 {
104 case File:
105 Assert(m_cbProcessed <= m_cbSize);
106 fComplete = m_cbProcessed == m_cbSize;
107 break;
108
109 case Directory:
110 fComplete = true;
111 break;
112
113 default:
114 fComplete = true;
115 break;
116 }
117
118 return fComplete;
119}
120
121bool DnDURIObject::IsOpen(void) const
122{
123 return m_fOpen;
124}
125
126int DnDURIObject::Open(Dest enmDest, uint64_t fOpen /* = 0 */, uint32_t fMode /* = 0 */)
127{
128 return OpenEx( enmDest == Source
129 ? m_strSrcPath : m_strTgtPath
130 , m_Type, enmDest, fOpen, fMode, 0 /* fFlags */);
131}
132
133int DnDURIObject::OpenEx(const RTCString &strPath, Type enmType, Dest enmDest,
134 uint64_t fOpen /* = 0 */, uint32_t fMode /* = 0 */, uint32_t fFlags /* = 0 */)
135{
136 Assert(fFlags == 0); RT_NOREF1(fFlags);
137 int rc = VINF_SUCCESS;
138
139 switch (enmDest)
140 {
141 case Source:
142 m_strSrcPath = strPath;
143 break;
144
145 case Target:
146 m_strTgtPath = strPath;
147 break;
148
149 default:
150 rc = VERR_NOT_IMPLEMENTED;
151 break;
152 }
153
154 if ( RT_SUCCESS(rc)
155 && fOpen) /* Opening mode specified? */
156 {
157 LogFlowThisFunc(("enmType=%RU32, strPath=%s, fOpen=0x%x, enmType=%RU32, enmDest=%RU32\n",
158 enmType, strPath.c_str(), fOpen, enmType, enmDest));
159 switch (enmType)
160 {
161 case File:
162 {
163 if (!m_fOpen)
164 {
165 /*
166 * Open files on the source with RTFILE_O_DENY_WRITE to prevent races
167 * where the OS writes to the file while the destination side transfers
168 * it over.
169 */
170 LogFlowThisFunc(("Opening ...\n"));
171 rc = RTFileOpen(&u.m_hFile, strPath.c_str(), fOpen);
172 if (RT_SUCCESS(rc))
173 rc = RTFileGetSize(u.m_hFile, &m_cbSize);
174
175 if (RT_SUCCESS(rc))
176 {
177 if ( (fOpen & RTFILE_O_WRITE) /* Only set the file mode on write. */
178 && fMode /* Some file mode to set specified? */)
179 {
180 rc = RTFileSetMode(u.m_hFile, fMode);
181 if (RT_SUCCESS(rc))
182 m_fMode = fMode;
183 }
184 else if (fOpen & RTFILE_O_READ)
185 {
186#if 0 /** @todo Enable this as soon as RTFileGetMode is implemented. */
187 rc = RTFileGetMode(u.m_hFile, &m_fMode);
188#else
189 RTFSOBJINFO ObjInfo;
190 rc = RTFileQueryInfo(u.m_hFile, &ObjInfo, RTFSOBJATTRADD_NOTHING);
191 if (RT_SUCCESS(rc))
192 m_fMode = ObjInfo.Attr.fMode;
193#endif
194 }
195 }
196
197 if (RT_SUCCESS(rc))
198 {
199 LogFlowThisFunc(("cbSize=%RU64, fMode=0x%x\n", m_cbSize, m_fMode));
200 m_cbProcessed = 0;
201 }
202 }
203 else
204 rc = VINF_SUCCESS;
205
206 break;
207 }
208
209 case Directory:
210 rc = VINF_SUCCESS;
211 break;
212
213 default:
214 rc = VERR_NOT_IMPLEMENTED;
215 break;
216 }
217 }
218
219 if (RT_SUCCESS(rc))
220 {
221 m_Type = enmType;
222 m_fOpen = true;
223 }
224
225 LogFlowFuncLeaveRC(rc);
226 return rc;
227}
228
229/* static */
230/** @todo Put this into an own class like DnDURIPath : public RTCString? */
231int DnDURIObject::RebaseURIPath(RTCString &strPath,
232 const RTCString &strBaseOld /* = "" */,
233 const RTCString &strBaseNew /* = "" */)
234{
235 char *pszPath = RTUriFilePath(strPath.c_str());
236 if (!pszPath) /* No URI? */
237 pszPath = RTStrDup(strPath.c_str());
238
239 int rc;
240
241 if (pszPath)
242 {
243 const char *pszPathStart = pszPath;
244 const char *pszBaseOld = strBaseOld.c_str();
245 if ( pszBaseOld
246 && RTPathStartsWith(pszPath, pszBaseOld))
247 {
248 pszPathStart += strlen(pszBaseOld);
249 }
250
251 rc = VINF_SUCCESS;
252
253 if (RT_SUCCESS(rc))
254 {
255 char *pszPathNew = RTPathJoinA(strBaseNew.c_str(), pszPathStart);
256 if (pszPathNew)
257 {
258 char *pszPathURI = RTUriCreate("file" /* pszScheme */, "/" /* pszAuthority */,
259 pszPathNew /* pszPath */,
260 NULL /* pszQuery */, NULL /* pszFragment */);
261 if (pszPathURI)
262 {
263 LogFlowFunc(("Rebasing \"%s\" to \"%s\"\n", strPath.c_str(), pszPathURI));
264
265 strPath = RTCString(pszPathURI) + "\r\n";
266 RTStrFree(pszPathURI);
267 }
268 else
269 rc = VERR_INVALID_PARAMETER;
270
271 RTStrFree(pszPathNew);
272 }
273 else
274 rc = VERR_NO_MEMORY;
275 }
276
277 RTStrFree(pszPath);
278 }
279 else
280 rc = VERR_NO_MEMORY;
281
282 return rc;
283}
284
285int DnDURIObject::Read(void *pvBuf, size_t cbBuf, uint32_t *pcbRead)
286{
287 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
288 AssertReturn(cbBuf, VERR_INVALID_PARAMETER);
289 /* pcbRead is optional. */
290
291 size_t cbRead = 0;
292
293 int rc;
294 switch (m_Type)
295 {
296 case File:
297 {
298 rc = OpenEx(m_strSrcPath, File, Source,
299 /* Use some sensible defaults. */
300 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE, 0 /* fFlags */);
301 if (RT_SUCCESS(rc))
302 {
303 rc = RTFileRead(u.m_hFile, pvBuf, cbBuf, &cbRead);
304 if (RT_SUCCESS(rc))
305 {
306 m_cbProcessed += cbRead;
307 Assert(m_cbProcessed <= m_cbSize);
308
309 /* End of file reached or error occurred? */
310 if ( m_cbSize
311 && m_cbProcessed == m_cbSize)
312 {
313 rc = VINF_EOF;
314 }
315 }
316 }
317
318 break;
319 }
320
321 case Directory:
322 {
323 rc = VINF_SUCCESS;
324 break;
325 }
326
327 default:
328 rc = VERR_NOT_IMPLEMENTED;
329 break;
330 }
331
332 if (RT_SUCCESS(rc))
333 {
334 if (pcbRead)
335 *pcbRead = (uint32_t)cbRead;
336 }
337
338 LogFlowFunc(("Returning strSourcePath=%s, cbRead=%zu, rc=%Rrc\n", m_strSrcPath.c_str(), cbRead, rc));
339 return rc;
340}
341
342void DnDURIObject::Reset(void)
343{
344 LogFlowThisFuncEnter();
345
346 Close();
347
348 m_Type = Unknown;
349 m_strSrcPath = "";
350 m_strTgtPath = "";
351 m_fMode = 0;
352 m_cbSize = 0;
353 m_cbProcessed = 0;
354}
355
356int DnDURIObject::Write(const void *pvBuf, size_t cbBuf, uint32_t *pcbWritten)
357{
358 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
359 AssertReturn(cbBuf, VERR_INVALID_PARAMETER);
360 /* pcbWritten is optional. */
361
362 size_t cbWritten = 0;
363
364 int rc;
365 switch (m_Type)
366 {
367 case File:
368 {
369 rc = OpenEx(m_strTgtPath, File, Target,
370 /* Use some sensible defaults. */
371 RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE | RTFILE_O_WRITE, 0 /* fFlags */);
372 if (RT_SUCCESS(rc))
373 {
374 rc = RTFileWrite(u.m_hFile, pvBuf, cbBuf, &cbWritten);
375 if (RT_SUCCESS(rc))
376 m_cbProcessed += cbWritten;
377 }
378 break;
379 }
380
381 case Directory:
382 {
383 rc = VINF_SUCCESS;
384 break;
385 }
386
387 default:
388 rc = VERR_NOT_IMPLEMENTED;
389 break;
390 }
391
392 if (RT_SUCCESS(rc))
393 {
394 if (pcbWritten)
395 *pcbWritten = (uint32_t)cbWritten;
396 }
397
398 LogFlowThisFunc(("Returning strSourcePath=%s, cbWritten=%zu, rc=%Rrc\n", m_strSrcPath.c_str(), cbWritten, rc));
399 return rc;
400}
401
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