VirtualBox

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

Last change on this file since 56906 was 56906, checked in by vboxsync, 9 years ago

Logging.

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