VirtualBox

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

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

DnD: Moved allocation of DNDDIRDROPPEDFILES into DnDDirDroppedFilesCreateAndOpen(Temp|Ex). Untested.

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