VirtualBox

source: vbox/trunk/src/VBox/GuestHost/DragAndDrop/DnDDir.cpp@ 56533

Last change on this file since 56533 was 55640, checked in by vboxsync, 10 years ago

DnD:

  • Overhauled "dropped files" directory + general file handling: Keep the directories/files open when doing the actual transfers (only protocol >= 2)
  • Unified "dropped files" directory creation/rollback handling for guest/host parts.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 KB
Line 
1/* $Id: DnDDir.cpp 55640 2015-05-04 12:38:57Z vboxsync $ */
2/** @file
3 * DnD: Directory handling.
4 */
5
6/*
7 * Copyright (C) 2014-2015 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/******************************************************************************
19 * Header Files *
20 ******************************************************************************/
21
22#include <iprt/assert.h>
23#include <iprt/dir.h>
24#include <iprt/path.h>
25#include <iprt/string.h>
26
27#include <VBox/GuestHost/DragAndDrop.h>
28
29int DnDDirDroppedAddFile(PDNDDIRDROPPEDFILES pDir, const char *pszFile)
30{
31 AssertPtrReturn(pDir, VERR_INVALID_POINTER);
32 AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
33
34 if (!pDir->lstFiles.contains(pszFile))
35 pDir->lstFiles.append(pszFile);
36 return VINF_SUCCESS;
37}
38
39int DnDDirDroppedAddDir(PDNDDIRDROPPEDFILES pDir, const char *pszDir)
40{
41 AssertPtrReturn(pDir, VERR_INVALID_POINTER);
42 AssertPtrReturn(pszDir, VERR_INVALID_POINTER);
43
44 if (!pDir->lstDirs.contains(pszDir))
45 pDir->lstDirs.append(pszDir);
46 return VINF_SUCCESS;
47}
48
49int DnDDirDroppedFilesCreateAndOpenEx(const char *pszPath, PDNDDIRDROPPEDFILES pDir)
50{
51 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
52 AssertPtrReturn(pDir, VERR_INVALID_POINTER);
53
54 char pszDropDir[RTPATH_MAX];
55 if (RTStrPrintf(pszDropDir, sizeof(pszDropDir), "%s", pszPath) <= 0)
56 return VERR_NO_MEMORY;
57
58 /** @todo On Windows we also could use the registry to override
59 * this path, on Posix a dotfile and/or a guest property
60 * can be used. */
61
62 /* Append our base drop directory. */
63 int rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), "VirtualBox Dropped Files"); /** @todo Make this tag configurable? */
64 if (RT_FAILURE(rc))
65 return rc;
66
67 /* Create it when necessary. */
68 if (!RTDirExists(pszDropDir))
69 {
70 rc = RTDirCreateFullPath(pszDropDir, RTFS_UNIX_IRWXU);
71 if (RT_FAILURE(rc))
72 return rc;
73 }
74
75 /* The actually drop directory consist of the current time stamp and a
76 * unique number when necessary. */
77 char pszTime[64];
78 RTTIMESPEC time;
79 if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime)))
80 return VERR_BUFFER_OVERFLOW;
81 rc = DnDPathSanitizeFilename(pszTime, sizeof(pszTime));
82 if (RT_FAILURE(rc))
83 return rc;
84
85 rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), pszTime);
86 if (RT_FAILURE(rc))
87 return rc;
88
89 /* Create it (only accessible by the current user) */
90 rc = RTDirCreateUniqueNumbered(pszDropDir, sizeof(pszDropDir), RTFS_UNIX_IRWXU, 3, '-');
91 if (RT_SUCCESS(rc))
92 {
93 PRTDIR phDir;
94 rc = RTDirOpen(&phDir, pszDropDir);
95 if (RT_SUCCESS(rc))
96 {
97 pDir->hDir = phDir;
98 pDir->strPathAbs = pszDropDir;
99 }
100 }
101
102 return rc;
103}
104
105int DnDDirDroppedFilesCreateAndOpenTemp(PDNDDIRDROPPEDFILES pDir)
106{
107 AssertPtrReturn(pDir, VERR_INVALID_POINTER);
108
109 char szTemp[RTPATH_MAX];
110
111 /*
112 * Get the user's temp directory. Don't use the user's root directory (or
113 * something inside it) because we don't know for how long/if the data will
114 * be kept after the guest OS used it.
115 */
116 int rc = RTPathTemp(szTemp, sizeof(szTemp));
117 if (RT_FAILURE(rc))
118 return rc;
119
120 return DnDDirDroppedFilesCreateAndOpenEx(szTemp, pDir);
121}
122
123int DnDDirDroppedFilesClose(PDNDDIRDROPPEDFILES pDir, bool fRemove)
124{
125 AssertPtrReturn(pDir, VERR_INVALID_POINTER);
126
127 int rc = RTDirClose(pDir->hDir);
128 if (RT_SUCCESS(rc))
129 {
130 pDir->lstDirs.clear();
131 pDir->lstFiles.clear();
132
133 if (fRemove)
134 {
135 /* Try removing the (empty) drop directory in any case. */
136 rc = RTDirRemove(pDir->strPathAbs.c_str());
137 if (RT_SUCCESS(rc)) /* Only clear if successfully removed. */
138 pDir->strPathAbs = "";
139 }
140 }
141
142 return rc;
143}
144
145const char *DnDDirDroppedFilesGetDirAbs(PDNDDIRDROPPEDFILES pDir)
146{
147 AssertPtrReturn(pDir, NULL);
148 return pDir->strPathAbs.c_str();
149}
150
151int DnDDirDroppedFilesRollback(PDNDDIRDROPPEDFILES pDir)
152{
153 AssertPtrReturn(pDir, VERR_INVALID_POINTER);
154
155 if (pDir->strPathAbs.isEmpty())
156 return VINF_SUCCESS;
157
158 int rc = VINF_SUCCESS;
159 int rc2;
160
161 /* Rollback by removing any stuff created.
162 * Note: Only remove empty directories, never ever delete
163 * anything recursive here! Steam (tm) knows best ... :-) */
164 for (size_t i = 0; i < pDir->lstFiles.size(); i++)
165 {
166 rc2 = RTFileDelete(pDir->lstFiles.at(i).c_str());
167 if (RT_SUCCESS(rc))
168 rc = rc2;
169 }
170
171 for (size_t i = 0; i < pDir->lstDirs.size(); i++)
172 {
173 rc2 = RTDirRemove(pDir->lstDirs.at(i).c_str());
174 if (RT_SUCCESS(rc))
175 rc = rc2;
176 }
177
178 /* Try to remove the empty root dropped files directory as well. */
179 rc2 = RTDirRemove(pDir->strPathAbs.c_str());
180 if (RT_SUCCESS(rc))
181 rc = rc2;
182
183 return rc;
184}
185
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