VirtualBox

source: vbox/trunk/src/VBox/GuestHost/DragAndDrop/DnDDroppedFiles.cpp@ 58139

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

DnD: Renamed DNDDIRDROPPEDFILES to DnDDroppedFiles and restructured it for being a class.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* $Id: DnDDroppedFiles.cpp 57776 2015-09-16 09:40:54Z 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/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22
23#include <iprt/assert.h>
24#include <iprt/dir.h>
25#include <iprt/path.h>
26#include <iprt/string.h>
27
28#include <VBox/GuestHost/DragAndDrop.h>
29
30DnDDroppedFiles::DnDDroppedFiles(void)
31 : hDir(NULL)
32 , fOpen(false) { }
33
34DnDDroppedFiles::DnDDroppedFiles(const char *pszPath, uint32_t fFlags)
35 : hDir(NULL)
36 , fOpen(false)
37{
38 OpenEx(pszPath, fFlags);
39}
40
41DnDDroppedFiles::~DnDDroppedFiles(void)
42{
43 Reset(true /* fRemoveDropDir */);
44}
45
46int DnDDroppedFiles::AddFile(const char *pszFile)
47{
48 AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
49
50 if (!this->lstFiles.contains(pszFile))
51 this->lstFiles.append(pszFile);
52 return VINF_SUCCESS;
53}
54
55int DnDDroppedFiles::AddDir(const char *pszDir)
56{
57 AssertPtrReturn(pszDir, VERR_INVALID_POINTER);
58
59 if (!this->lstDirs.contains(pszDir))
60 this->lstDirs.append(pszDir);
61 return VINF_SUCCESS;
62}
63
64const char *DnDDroppedFiles::GetDirAbs(void) const
65{
66 return this->strPathAbs.c_str();
67}
68
69bool DnDDroppedFiles::IsOpen(void) const
70{
71 return this->fOpen;
72}
73
74int DnDDroppedFiles::OpenEx(const char *pszPath, uint32_t fFlags)
75{
76 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
77 AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER); /* Flags not supported yet. */
78
79 int rc;
80
81 do
82 {
83 char pszDropDir[RTPATH_MAX];
84 size_t cchDropDir = RTStrPrintf(pszDropDir, sizeof(pszDropDir), "%s", pszPath);
85
86 /** @todo On Windows we also could use the registry to override
87 * this path, on Posix a dotfile and/or a guest property
88 * can be used. */
89
90 /* Append our base drop directory. */
91 rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), "VirtualBox Dropped Files"); /** @todo Make this tag configurable? */
92 if (RT_FAILURE(rc))
93 break;
94
95 /* Create it when necessary. */
96 if (!RTDirExists(pszDropDir))
97 {
98 rc = RTDirCreateFullPath(pszDropDir, RTFS_UNIX_IRWXU);
99 if (RT_FAILURE(rc))
100 break;
101 }
102
103 /* The actually drop directory consist of the current time stamp and a
104 * unique number when necessary. */
105 char pszTime[64];
106 RTTIMESPEC time;
107 if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime)))
108 {
109 rc = VERR_BUFFER_OVERFLOW;
110 break;
111 }
112
113 rc = DnDPathSanitizeFilename(pszTime, sizeof(pszTime));
114 if (RT_FAILURE(rc))
115 break;
116
117 rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), pszTime);
118 if (RT_FAILURE(rc))
119 break;
120
121 /* Create it (only accessible by the current user) */
122 rc = RTDirCreateUniqueNumbered(pszDropDir, sizeof(pszDropDir), RTFS_UNIX_IRWXU, 3, '-');
123 if (RT_SUCCESS(rc))
124 {
125 PRTDIR phDir;
126 rc = RTDirOpen(&phDir, pszDropDir);
127 if (RT_SUCCESS(rc))
128 {
129 this->hDir = phDir;
130 this->strPathAbs = pszDropDir;
131 this->fOpen = true;
132 }
133 }
134
135 } while (0);
136
137 return rc;
138}
139
140int DnDDroppedFiles::OpenTemp(uint32_t fFlags)
141{
142 AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER); /* Flags not supported yet. */
143
144 /*
145 * Get the user's temp directory. Don't use the user's root directory (or
146 * something inside it) because we don't know for how long/if the data will
147 * be kept after the guest OS used it.
148 */
149 char szTemp[RTPATH_MAX];
150 int rc = RTPathTemp(szTemp, sizeof(szTemp));
151 if (RT_SUCCESS(rc))
152 rc = OpenEx(szTemp, fFlags);
153
154 return rc;
155}
156
157int DnDDroppedFiles::Reset(bool fRemoveDropDir)
158{
159 int rc = VINF_SUCCESS;
160 if (this->fOpen)
161 {
162 rc = RTDirClose(this->hDir);
163 if (RT_SUCCESS(rc))
164 {
165 this->fOpen = false;
166 this->hDir = NULL;
167 }
168 }
169 if (RT_SUCCESS(rc))
170 {
171 this->lstDirs.clear();
172 this->lstFiles.clear();
173
174 if ( fRemoveDropDir
175 && this->strPathAbs.isNotEmpty())
176 {
177 /* Try removing the (empty) drop directory in any case. */
178 rc = RTDirRemove(this->strPathAbs.c_str());
179 if (RT_SUCCESS(rc)) /* Only clear if successfully removed. */
180 this->strPathAbs = "";
181 }
182 }
183
184 return rc;
185}
186
187int DnDDroppedFiles::Rollback(void)
188{
189 if (this->strPathAbs.isEmpty())
190 return VINF_SUCCESS;
191
192 Assert(this->fOpen);
193 Assert(this->hDir != NULL);
194
195 int rc = VINF_SUCCESS;
196 int rc2;
197
198 /* Rollback by removing any stuff created.
199 * Note: Only remove empty directories, never ever delete
200 * anything recursive here! Steam (tm) knows best ... :-) */
201 for (size_t i = 0; i < this->lstFiles.size(); i++)
202 {
203 rc2 = RTFileDelete(this->lstFiles.at(i).c_str());
204 if (RT_SUCCESS(rc))
205 rc = rc2;
206 }
207
208 for (size_t i = 0; i < this->lstDirs.size(); i++)
209 {
210 rc2 = RTDirRemove(this->lstDirs.at(i).c_str());
211 if (RT_SUCCESS(rc))
212 rc = rc2;
213 }
214
215 /* Try to remove the empty root dropped files directory as well. */
216 rc2 = RTDirRemove(this->strPathAbs.c_str());
217 if (RT_SUCCESS(rc))
218 rc = rc2;
219
220 return rc;
221}
222
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