/src/libreoffice/ucb/source/ucp/file/filglob.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <sal/config.h> |
21 | | |
22 | | #include <string_view> |
23 | | |
24 | | #include "filglob.hxx" |
25 | | #include "filerror.hxx" |
26 | | #include "bc.hxx" |
27 | | #include <osl/file.hxx> |
28 | | #include <ucbhelper/cancelcommandexecution.hxx> |
29 | | #include <com/sun/star/ucb/UnsupportedCommandException.hpp> |
30 | | #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp> |
31 | | #include <com/sun/star/lang/IllegalArgumentException.hpp> |
32 | | #include <com/sun/star/ucb/IOErrorCode.hpp> |
33 | | #include <com/sun/star/ucb/MissingPropertiesException.hpp> |
34 | | #include <com/sun/star/ucb/MissingInputStreamException.hpp> |
35 | | #include <com/sun/star/ucb/NameClashException.hpp> |
36 | | #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> |
37 | | #include <com/sun/star/ucb/UnsupportedNameClashException.hpp> |
38 | | #include <com/sun/star/beans/PropertyState.hpp> |
39 | | #include <com/sun/star/beans/PropertyValue.hpp> |
40 | | #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> |
41 | | #include <com/sun/star/uno/Any.hxx> |
42 | | #include <com/sun/star/uno/Sequence.hxx> |
43 | | #include <o3tl/string_view.hxx> |
44 | | #include <o3tl/underlyingenumvalue.hxx> |
45 | | #include <osl/diagnose.h> |
46 | | #include <rtl/uri.hxx> |
47 | | #include <rtl/ustring.hxx> |
48 | | #include <sal/types.h> |
49 | | |
50 | | using namespace ucbhelper; |
51 | | using namespace osl; |
52 | | using namespace ::com::sun::star; |
53 | | using namespace com::sun::star::task; |
54 | | using namespace com::sun::star::beans; |
55 | | using namespace com::sun::star::lang; |
56 | | using namespace com::sun::star::uno; |
57 | | using namespace com::sun::star::ucb; |
58 | | |
59 | | namespace { |
60 | | |
61 | | Sequence< Any > generateErrorArguments( |
62 | | OUString const & rPhysicalUrl) |
63 | 0 | { |
64 | 0 | OUString aResourceName; |
65 | 0 | OUString aResourceType; |
66 | 0 | bool bRemovable = false; |
67 | 0 | bool bResourceName = false; |
68 | 0 | bool bResourceType = false; |
69 | 0 | bool bRemoveProperty = false; |
70 | |
|
71 | 0 | if (osl::FileBase::getSystemPathFromFileURL( |
72 | 0 | rPhysicalUrl, |
73 | 0 | aResourceName) |
74 | 0 | == osl::FileBase::E_None) |
75 | 0 | bResourceName = true; |
76 | | |
77 | | // The resource types "folder" (i.e., directory) and |
78 | | // "volume" seem to be |
79 | | // the most interesting when producing meaningful error messages: |
80 | 0 | osl::DirectoryItem aItem; |
81 | 0 | if (osl::DirectoryItem::get(rPhysicalUrl, aItem) == |
82 | 0 | osl::FileBase::E_None) |
83 | 0 | { |
84 | 0 | osl::FileStatus aStatus( osl_FileStatus_Mask_Type ); |
85 | 0 | if (aItem.getFileStatus(aStatus) == osl::FileBase::E_None) |
86 | 0 | switch (aStatus.getFileType()) |
87 | 0 | { |
88 | 0 | case osl::FileStatus::Directory: |
89 | 0 | aResourceType = "folder"; |
90 | 0 | bResourceType = true; |
91 | 0 | break; |
92 | | |
93 | 0 | case osl::FileStatus::Volume: |
94 | 0 | { |
95 | 0 | aResourceType = "volume"; |
96 | 0 | bResourceType = true; |
97 | 0 | osl::VolumeInfo aVolumeInfo( |
98 | 0 | osl_VolumeInfo_Mask_Attributes ); |
99 | 0 | if( osl::Directory::getVolumeInfo( |
100 | 0 | rPhysicalUrl,aVolumeInfo ) == |
101 | 0 | osl::FileBase::E_None ) |
102 | 0 | { |
103 | 0 | bRemovable = aVolumeInfo.getRemoveableFlag(); |
104 | 0 | bRemoveProperty = true; |
105 | 0 | } |
106 | 0 | } |
107 | 0 | break; |
108 | 0 | case osl::FileStatus::Regular: |
109 | 0 | case osl::FileStatus::Fifo: |
110 | 0 | case osl::FileStatus::Socket: |
111 | 0 | case osl::FileStatus::Link: |
112 | 0 | case osl::FileStatus::Special: |
113 | 0 | case osl::FileStatus::Unknown: |
114 | | // do nothing for now |
115 | 0 | break; |
116 | 0 | } |
117 | 0 | } |
118 | | |
119 | 0 | Sequence< Any > aArguments( 1 + |
120 | 0 | (bResourceName ? 1 : 0) + |
121 | 0 | (bResourceType ? 1 : 0) + |
122 | 0 | (bRemoveProperty ? 1 : 0) ); |
123 | 0 | auto pArguments = aArguments.getArray(); |
124 | 0 | sal_Int32 i = 0; |
125 | 0 | pArguments[i++] |
126 | 0 | <<= PropertyValue(u"Uri"_ustr, |
127 | 0 | -1, |
128 | 0 | Any(rPhysicalUrl), |
129 | 0 | PropertyState_DIRECT_VALUE); |
130 | 0 | if (bResourceName) |
131 | 0 | pArguments[i++] |
132 | 0 | <<= PropertyValue(u"ResourceName"_ustr, |
133 | 0 | -1, |
134 | 0 | Any(aResourceName), |
135 | 0 | PropertyState_DIRECT_VALUE); |
136 | 0 | if (bResourceType) |
137 | 0 | pArguments[i++] |
138 | 0 | <<= PropertyValue(u"ResourceType"_ustr, |
139 | 0 | -1, |
140 | 0 | Any(aResourceType), |
141 | 0 | PropertyState_DIRECT_VALUE); |
142 | 0 | if (bRemoveProperty) |
143 | 0 | pArguments[i++] |
144 | 0 | <<= PropertyValue(u"Removable"_ustr, |
145 | 0 | -1, |
146 | 0 | Any(bRemovable), |
147 | 0 | PropertyState_DIRECT_VALUE); |
148 | |
|
149 | 0 | return aArguments; |
150 | 0 | } |
151 | | } |
152 | | |
153 | | |
154 | | namespace fileaccess { |
155 | | |
156 | | |
157 | | bool isChild( std::u16string_view srcUnqPath, |
158 | | std::u16string_view dstUnqPath ) |
159 | 0 | { |
160 | 0 | static const sal_Unicode slash = '/'; |
161 | | // Simple lexical comparison |
162 | 0 | size_t srcL = srcUnqPath.size(); |
163 | 0 | size_t dstL = dstUnqPath.size(); |
164 | |
|
165 | 0 | return ( |
166 | 0 | ( srcUnqPath == dstUnqPath ) |
167 | 0 | || |
168 | 0 | ( ( dstL > srcL ) |
169 | 0 | && |
170 | 0 | o3tl::starts_with(dstUnqPath, srcUnqPath) |
171 | 0 | && |
172 | 0 | ( dstUnqPath[ srcL ] == slash ) ) |
173 | 0 | ); |
174 | 0 | } |
175 | | |
176 | | |
177 | | OUString newName( |
178 | | std::u16string_view aNewPrefix, |
179 | | std::u16string_view aOldPrefix, |
180 | | std::u16string_view old_Name ) |
181 | 0 | { |
182 | 0 | size_t srcL = aOldPrefix.size(); |
183 | |
|
184 | 0 | return OUString::Concat(aNewPrefix) + old_Name.substr( srcL ); |
185 | 0 | } |
186 | | |
187 | | |
188 | | std::u16string_view getTitle( std::u16string_view aPath ) |
189 | 0 | { |
190 | 0 | size_t lastIndex = aPath.rfind( '/' ); |
191 | 0 | return aPath.substr((lastIndex != std::u16string_view::npos) ? lastIndex + 1 : 0); |
192 | 0 | } |
193 | | |
194 | | |
195 | | OUString getParentName( std::u16string_view aFileName ) |
196 | 0 | { |
197 | 0 | size_t lastIndex = aFileName.rfind( '/' ); |
198 | 0 | OUString aParent( aFileName.substr( 0,lastIndex ) ); |
199 | |
|
200 | 0 | if( aParent.endsWith(":") && aParent.getLength() == 6 ) |
201 | 0 | aParent += "/"; |
202 | |
|
203 | 0 | if ( aParent == "file://" ) |
204 | 0 | aParent = "file:///"; |
205 | |
|
206 | 0 | return aParent; |
207 | 0 | } |
208 | | |
209 | | |
210 | | osl::FileBase::RC osl_File_copy( const OUString& strPath, |
211 | | const OUString& strDestPath, |
212 | | bool test ) |
213 | 0 | { |
214 | 0 | if( test ) |
215 | 0 | { |
216 | 0 | osl::DirectoryItem aItem; |
217 | 0 | if( osl::DirectoryItem::get( strDestPath,aItem ) != osl::FileBase:: E_NOENT ) |
218 | 0 | return osl::FileBase::E_EXIST; |
219 | 0 | } |
220 | | |
221 | 0 | return osl::File::copy( strPath,strDestPath ); |
222 | 0 | } |
223 | | |
224 | | |
225 | | osl::FileBase::RC osl_File_move( const OUString& strPath, |
226 | | const OUString& strDestPath, |
227 | | bool test ) |
228 | 0 | { |
229 | 0 | if( test ) |
230 | 0 | { |
231 | 0 | osl::DirectoryItem aItem; |
232 | 0 | if( osl::DirectoryItem::get( strDestPath,aItem ) != osl::FileBase:: E_NOENT ) |
233 | 0 | return osl::FileBase::E_EXIST; |
234 | 0 | } |
235 | | |
236 | 0 | return osl::File::move( strPath,strDestPath ); |
237 | 0 | } |
238 | | |
239 | | void throw_handler( |
240 | | TaskHandlerErr errorCode, |
241 | | sal_Int32 minorCode, |
242 | | const Reference< XCommandEnvironment >& xEnv, |
243 | | const OUString& aUncPath, |
244 | | BaseContent* pContent, |
245 | | bool isHandled ) |
246 | 0 | { |
247 | 0 | Reference<XCommandProcessor> xComProc(pContent); |
248 | 0 | Any aAny; |
249 | 0 | IOErrorCode ioErrorCode; |
250 | |
|
251 | 0 | if( errorCode == TaskHandlerErr::UNSUPPORTED_COMMAND ) |
252 | 0 | { |
253 | 0 | aAny <<= UnsupportedCommandException( u"" OSL_LOG_PREFIX ""_ustr ); |
254 | 0 | cancelCommandExecution( aAny,xEnv ); |
255 | 0 | } |
256 | 0 | else if( errorCode == TaskHandlerErr::WRONG_SETPROPERTYVALUES_ARGUMENT || |
257 | 0 | errorCode == TaskHandlerErr::WRONG_GETPROPERTYVALUES_ARGUMENT || |
258 | 0 | errorCode == TaskHandlerErr::WRONG_OPEN_ARGUMENT || |
259 | 0 | errorCode == TaskHandlerErr::WRONG_DELETE_ARGUMENT || |
260 | 0 | errorCode == TaskHandlerErr::WRONG_TRANSFER_ARGUMENT || |
261 | 0 | errorCode == TaskHandlerErr::WRONG_INSERT_ARGUMENT || |
262 | 0 | errorCode == TaskHandlerErr::WRONG_CREATENEWCONTENT_ARGUMENT ) |
263 | 0 | { |
264 | 0 | IllegalArgumentException excep; |
265 | 0 | excep.ArgumentPosition = 0; |
266 | 0 | cancelCommandExecution(Any(excep), xEnv); |
267 | 0 | } |
268 | 0 | else if( errorCode == TaskHandlerErr::UNSUPPORTED_OPEN_MODE ) |
269 | 0 | { |
270 | 0 | UnsupportedOpenModeException excep; |
271 | 0 | excep.Mode = sal::static_int_cast< sal_Int16 >(minorCode); |
272 | 0 | cancelCommandExecution( Any(excep),xEnv ); |
273 | 0 | } |
274 | 0 | else if(errorCode == TaskHandlerErr::DELETED_STATE_IN_OPEN_COMMAND || |
275 | 0 | errorCode == TaskHandlerErr::INSERTED_STATE_IN_OPEN_COMMAND || |
276 | 0 | errorCode == TaskHandlerErr::NOFRESHINSERT_IN_INSERT_COMMAND ) |
277 | 0 | { |
278 | | // What to do here? |
279 | 0 | } |
280 | 0 | else if( |
281 | | // error in opening file |
282 | 0 | errorCode == TaskHandlerErr::NO_OPEN_FILE_FOR_OVERWRITE || |
283 | | // error in opening file |
284 | 0 | errorCode == TaskHandlerErr::NO_OPEN_FILE_FOR_WRITE || |
285 | | // error in opening file |
286 | 0 | errorCode == TaskHandlerErr::OPEN_FOR_STREAM || |
287 | | // error in opening file |
288 | 0 | errorCode == TaskHandlerErr::OPEN_FOR_INPUTSTREAM || |
289 | | // error in opening file |
290 | 0 | errorCode == TaskHandlerErr::OPEN_FILE_FOR_PAGING ) |
291 | 0 | { |
292 | 0 | switch( minorCode ) |
293 | 0 | { |
294 | 0 | case FileBase::E_NAMETOOLONG: |
295 | | // pathname was too long |
296 | 0 | ioErrorCode = IOErrorCode_NAME_TOO_LONG; |
297 | 0 | break; |
298 | 0 | case FileBase::E_NXIO: |
299 | | // No such device or address |
300 | 0 | case FileBase::E_NODEV: |
301 | | // No such device |
302 | 0 | ioErrorCode = IOErrorCode_INVALID_DEVICE; |
303 | 0 | break; |
304 | 0 | case FileBase::E_NOTDIR: |
305 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING_PATH; |
306 | 0 | break; |
307 | 0 | case FileBase::E_NOENT: |
308 | | // No such file or directory |
309 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING; |
310 | 0 | break; |
311 | 0 | case FileBase::E_ROFS: |
312 | | // #i4735# handle ROFS transparently as ACCESS_DENIED |
313 | 0 | case FileBase::E_ACCES: |
314 | 0 | case FileBase::E_PERM: |
315 | | // permission denied<P> |
316 | 0 | ioErrorCode = IOErrorCode_ACCESS_DENIED; |
317 | 0 | break; |
318 | 0 | case FileBase::E_ISDIR: |
319 | | // Is a directory<p> |
320 | 0 | ioErrorCode = IOErrorCode_NO_FILE; |
321 | 0 | break; |
322 | 0 | case FileBase::E_NOTREADY: |
323 | 0 | ioErrorCode = IOErrorCode_DEVICE_NOT_READY; |
324 | 0 | break; |
325 | 0 | case FileBase::E_MFILE: |
326 | | // too many open files used by the process |
327 | 0 | case FileBase::E_NFILE: |
328 | | // too many open files in the system |
329 | 0 | ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES; |
330 | 0 | break; |
331 | 0 | case FileBase::E_INVAL: |
332 | | // the format of the parameters was not valid |
333 | 0 | ioErrorCode = IOErrorCode_INVALID_PARAMETER; |
334 | 0 | break; |
335 | 0 | case FileBase::E_NOMEM: |
336 | | // not enough memory for allocating structures |
337 | 0 | ioErrorCode = IOErrorCode_OUT_OF_MEMORY; |
338 | 0 | break; |
339 | 0 | case FileBase::E_BUSY: // Text file busy |
340 | 0 | case FileBase::E_AGAIN: // Operation would block |
341 | 0 | case FileBase::E_NOLCK: // No record locks available |
342 | 0 | ioErrorCode = IOErrorCode_LOCKING_VIOLATION; |
343 | 0 | break; |
344 | 0 | case FileBase::E_NOSYS: |
345 | 0 | ioErrorCode = IOErrorCode_NOT_SUPPORTED; |
346 | 0 | break; |
347 | 0 | case FileBase::E_FAULT: // Bad address |
348 | 0 | case FileBase::E_LOOP: // Too many symbolic links encountered |
349 | 0 | case FileBase::E_NOSPC: // No space left on device |
350 | 0 | case FileBase::E_INTR: // function call was interrupted |
351 | 0 | case FileBase::E_IO: // I/O error |
352 | 0 | case FileBase::E_MULTIHOP: // Multihop attempted |
353 | 0 | case FileBase::E_NOLINK: // Link has been severed |
354 | 0 | default: |
355 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
356 | 0 | break; |
357 | 0 | } |
358 | | |
359 | 0 | cancelCommandExecution( |
360 | 0 | ioErrorCode, |
361 | 0 | generateErrorArguments(aUncPath), |
362 | 0 | xEnv, |
363 | 0 | "an error occurred during file opening (" |
364 | 0 | + OUString::number(o3tl::to_underlying(errorCode)) + "/" |
365 | 0 | + OUString::number(minorCode) + ")", |
366 | 0 | xComProc); |
367 | 0 | } |
368 | 0 | else if( errorCode == TaskHandlerErr::OPEN_FOR_DIRECTORYLISTING || |
369 | 0 | errorCode == TaskHandlerErr::OPENDIRECTORY_FOR_REMOVE ) |
370 | 0 | { |
371 | 0 | switch( minorCode ) |
372 | 0 | { |
373 | 0 | case FileBase::E_INVAL: |
374 | | // the format of the parameters was not valid |
375 | 0 | ioErrorCode = IOErrorCode_INVALID_PARAMETER; |
376 | 0 | break; |
377 | 0 | case FileBase::E_NOENT: |
378 | | // the specified path doesn't exist |
379 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING; |
380 | 0 | break; |
381 | 0 | case FileBase::E_NOTDIR: |
382 | | // the specified path is not a directory |
383 | 0 | ioErrorCode = IOErrorCode_NO_DIRECTORY; |
384 | 0 | break; |
385 | 0 | case FileBase::E_NOMEM: |
386 | | // not enough memory for allocating structures |
387 | 0 | ioErrorCode = IOErrorCode_OUT_OF_MEMORY; |
388 | 0 | break; |
389 | 0 | case FileBase::E_ROFS: |
390 | | // #i4735# handle ROFS transparently as ACCESS_DENIED |
391 | 0 | case FileBase::E_ACCES: // permission denied |
392 | 0 | ioErrorCode = IOErrorCode_ACCESS_DENIED; |
393 | 0 | break; |
394 | 0 | case FileBase::E_NOTREADY: |
395 | 0 | ioErrorCode = IOErrorCode_DEVICE_NOT_READY; |
396 | 0 | break; |
397 | 0 | case FileBase::E_MFILE: |
398 | | // too many open files used by the process |
399 | 0 | case FileBase::E_NFILE: |
400 | | // too many open files in the system |
401 | 0 | ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES; |
402 | 0 | break; |
403 | 0 | case FileBase::E_NAMETOOLONG: |
404 | | // File name too long |
405 | 0 | ioErrorCode = IOErrorCode_NAME_TOO_LONG; |
406 | 0 | break; |
407 | 0 | case FileBase::E_LOOP: |
408 | | // Too many symbolic links encountered<p> |
409 | 0 | default: |
410 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
411 | 0 | break; |
412 | 0 | } |
413 | | |
414 | 0 | cancelCommandExecution( |
415 | 0 | ioErrorCode, |
416 | 0 | generateErrorArguments(aUncPath), |
417 | 0 | xEnv, |
418 | 0 | u"an error occurred during opening a directory"_ustr, |
419 | 0 | xComProc); |
420 | 0 | } |
421 | 0 | else if( errorCode == TaskHandlerErr::NOTCONNECTED_FOR_WRITE || |
422 | 0 | errorCode == TaskHandlerErr::BUFFERSIZEEXCEEDED_FOR_WRITE || |
423 | 0 | errorCode == TaskHandlerErr::IOEXCEPTION_FOR_WRITE || |
424 | 0 | errorCode == TaskHandlerErr::NOTCONNECTED_FOR_PAGING || |
425 | 0 | errorCode == TaskHandlerErr::BUFFERSIZEEXCEEDED_FOR_PAGING || |
426 | 0 | errorCode == TaskHandlerErr::IOEXCEPTION_FOR_PAGING ) |
427 | 0 | { |
428 | 0 | ioErrorCode = IOErrorCode_UNKNOWN; |
429 | 0 | cancelCommandExecution( |
430 | 0 | ioErrorCode, |
431 | 0 | generateErrorArguments(aUncPath), |
432 | 0 | xEnv, |
433 | 0 | u"an error occurred writing or reading from a file"_ustr, |
434 | 0 | xComProc ); |
435 | 0 | } |
436 | 0 | else if( errorCode == TaskHandlerErr::FILEIOERROR_FOR_NO_SPACE ) |
437 | 0 | { |
438 | 0 | ioErrorCode = IOErrorCode_OUT_OF_DISK_SPACE; |
439 | 0 | cancelCommandExecution( |
440 | 0 | ioErrorCode, |
441 | 0 | generateErrorArguments(aUncPath), |
442 | 0 | xEnv, |
443 | 0 | u"device full"_ustr, |
444 | 0 | xComProc); |
445 | 0 | } |
446 | 0 | else if( errorCode == TaskHandlerErr::FILEIOERROR_FOR_WRITE || |
447 | 0 | errorCode == TaskHandlerErr::READING_FILE_FOR_PAGING ) |
448 | 0 | { |
449 | 0 | switch( minorCode ) |
450 | 0 | { |
451 | 0 | case FileBase::E_INVAL: |
452 | | // the format of the parameters was not valid |
453 | 0 | ioErrorCode = IOErrorCode_INVALID_PARAMETER; |
454 | 0 | break; |
455 | 0 | case FileBase::E_FBIG: |
456 | | // File too large |
457 | 0 | ioErrorCode = IOErrorCode_CANT_WRITE; |
458 | 0 | break; |
459 | 0 | case FileBase::E_NOSPC: |
460 | | // No space left on device |
461 | 0 | ioErrorCode = IOErrorCode_OUT_OF_DISK_SPACE; |
462 | 0 | break; |
463 | 0 | case FileBase::E_NXIO: |
464 | | // No such device or address |
465 | 0 | ioErrorCode = IOErrorCode_INVALID_DEVICE; |
466 | 0 | break; |
467 | 0 | case FileBase::E_NOLINK: |
468 | | // Link has been severed |
469 | 0 | case FileBase::E_ISDIR: |
470 | | // Is a directory |
471 | 0 | ioErrorCode = IOErrorCode_NO_FILE; |
472 | 0 | break; |
473 | 0 | case FileBase::E_AGAIN: // Operation would block |
474 | 0 | case FileBase::E_NOLCK: // No record locks available |
475 | 0 | ioErrorCode = IOErrorCode_LOCKING_VIOLATION; |
476 | 0 | break; |
477 | 0 | case FileBase::E_TIMEDOUT: |
478 | 0 | ioErrorCode = IOErrorCode_DEVICE_NOT_READY; |
479 | 0 | break; |
480 | 0 | case FileBase::E_IO: // I/O error |
481 | 0 | case FileBase::E_BADF: // Bad file |
482 | 0 | case FileBase::E_FAULT: // Bad address |
483 | 0 | case FileBase::E_INTR: // function call was interrupted |
484 | 0 | default: |
485 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
486 | 0 | break; |
487 | 0 | } |
488 | 0 | cancelCommandExecution( |
489 | 0 | ioErrorCode, |
490 | 0 | generateErrorArguments(aUncPath), |
491 | 0 | xEnv, |
492 | 0 | u"an error occurred during opening a file"_ustr, |
493 | 0 | xComProc); |
494 | 0 | } |
495 | 0 | else if( errorCode == TaskHandlerErr::NONAMESET_INSERT_COMMAND || |
496 | 0 | errorCode == TaskHandlerErr::NOCONTENTTYPE_INSERT_COMMAND ) |
497 | 0 | { |
498 | 0 | static constexpr OUString sTitle = u"Title"_ustr; |
499 | 0 | static constexpr OUString sContentType = u"ContentType"_ustr; |
500 | 0 | Sequence< OUString > aSeq{ (errorCode == TaskHandlerErr::NONAMESET_INSERT_COMMAND) |
501 | 0 | ? sTitle |
502 | 0 | : sContentType }; |
503 | |
|
504 | 0 | aAny <<= MissingPropertiesException( |
505 | 0 | u"a property is missing, necessary to create a content"_ustr, |
506 | 0 | xComProc, |
507 | 0 | aSeq); |
508 | 0 | cancelCommandExecution(aAny,xEnv); |
509 | 0 | } |
510 | 0 | else if( errorCode == TaskHandlerErr::FILESIZE_FOR_WRITE ) |
511 | 0 | { |
512 | 0 | switch( minorCode ) |
513 | 0 | { |
514 | 0 | case FileBase::E_INVAL: |
515 | | // the format of the parameters was not valid |
516 | 0 | case FileBase::E_OVERFLOW: |
517 | | // The resulting file offset would be a value which cannot |
518 | | // be represented correctly for regular files |
519 | 0 | ioErrorCode = IOErrorCode_INVALID_PARAMETER; |
520 | 0 | break; |
521 | 0 | default: |
522 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
523 | 0 | break; |
524 | 0 | } |
525 | 0 | cancelCommandExecution( |
526 | 0 | ioErrorCode, |
527 | 0 | generateErrorArguments(aUncPath), |
528 | 0 | xEnv, |
529 | 0 | u"there were problems with the filesize"_ustr, |
530 | 0 | xComProc); |
531 | 0 | } |
532 | 0 | else if(errorCode == TaskHandlerErr::INPUTSTREAM_FOR_WRITE) |
533 | 0 | { |
534 | 0 | aAny <<= |
535 | 0 | MissingInputStreamException( |
536 | 0 | u"the inputstream is missing, necessary to create a content"_ustr, |
537 | 0 | xComProc); |
538 | 0 | cancelCommandExecution(aAny,xEnv); |
539 | 0 | } |
540 | 0 | else if( errorCode == TaskHandlerErr::NOREPLACE_FOR_WRITE ) |
541 | | // Overwrite = false and file exists |
542 | 0 | { |
543 | 0 | NameClashException excep(u"file exists and overwrite forbidden"_ustr, |
544 | 0 | Reference<XInterface>(xComProc, UNO_QUERY), |
545 | 0 | InteractionClassification_ERROR, OUString(getTitle(aUncPath))); |
546 | 0 | cancelCommandExecution( Any(excep), xEnv ); |
547 | 0 | } |
548 | 0 | else if( errorCode == TaskHandlerErr::INVALID_NAME_MKDIR ) |
549 | 0 | { |
550 | 0 | PropertyValue prop; |
551 | 0 | prop.Name = "ResourceName"; |
552 | 0 | prop.Handle = -1; |
553 | 0 | OUString aClashingName( |
554 | 0 | rtl::Uri::decode( |
555 | 0 | OUString(getTitle(aUncPath)), |
556 | 0 | rtl_UriDecodeWithCharset, |
557 | 0 | RTL_TEXTENCODING_UTF8)); |
558 | 0 | prop.Value <<= aClashingName; |
559 | 0 | InteractiveAugmentedIOException excep( |
560 | 0 | u"the name contained invalid characters"_ustr, Reference<XInterface>(xComProc, UNO_QUERY), |
561 | 0 | InteractionClassification_ERROR, IOErrorCode_INVALID_CHARACTER, { Any(prop) }); |
562 | 0 | if(isHandled) |
563 | 0 | throw excep; |
564 | 0 | cancelCommandExecution( Any(excep), xEnv ); |
565 | | // ioErrorCode = IOErrorCode_INVALID_CHARACTER; |
566 | | // cancelCommandExecution( |
567 | | // ioErrorCode, |
568 | | // generateErrorArguments(aUncPath), |
569 | | // xEnv, |
570 | | // OUString( "the name contained invalid characters"), |
571 | | // xComProc ); |
572 | 0 | } |
573 | 0 | else if( errorCode == TaskHandlerErr::FOLDER_EXISTS_MKDIR ) |
574 | 0 | { |
575 | 0 | NameClashException excep(u"folder exists and overwrite forbidden"_ustr, xComProc, |
576 | 0 | InteractionClassification_ERROR, OUString(getTitle(aUncPath))); |
577 | 0 | if(isHandled) |
578 | 0 | throw excep; |
579 | 0 | cancelCommandExecution( Any(excep), xEnv ); |
580 | | // ioErrorCode = IOErrorCode_ALREADY_EXISTING; |
581 | | // cancelCommandExecution( |
582 | | // ioErrorCode, |
583 | | // generateErrorArguments(aUncPath), |
584 | | // xEnv, |
585 | | // OUString( "the folder exists"), |
586 | | // xComProc ); |
587 | 0 | } |
588 | 0 | else if( errorCode == TaskHandlerErr::ENSUREDIR_FOR_WRITE || |
589 | 0 | errorCode == TaskHandlerErr::CREATEDIRECTORY_MKDIR ) |
590 | 0 | { |
591 | 0 | switch( minorCode ) |
592 | 0 | { |
593 | 0 | case FileBase::E_ACCES: |
594 | 0 | ioErrorCode = IOErrorCode_ACCESS_DENIED; |
595 | 0 | break; |
596 | 0 | case FileBase::E_ROFS: |
597 | 0 | ioErrorCode = IOErrorCode_WRITE_PROTECTED; |
598 | 0 | break; |
599 | 0 | case FileBase::E_NAMETOOLONG: |
600 | 0 | ioErrorCode = IOErrorCode_NAME_TOO_LONG; |
601 | 0 | break; |
602 | 0 | default: |
603 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING_PATH; |
604 | 0 | break; |
605 | 0 | } |
606 | 0 | cancelCommandExecution( |
607 | 0 | ioErrorCode, |
608 | 0 | generateErrorArguments(getParentName(aUncPath)), |
609 | | //TODO! ok to supply physical URL to getParentName()? |
610 | 0 | xEnv, |
611 | 0 | u"a folder could not be created"_ustr, |
612 | 0 | xComProc ); |
613 | 0 | } |
614 | 0 | else if( errorCode == TaskHandlerErr::VALIDFILESTATUSWHILE_FOR_REMOVE || |
615 | 0 | errorCode == TaskHandlerErr::VALIDFILESTATUS_FOR_REMOVE || |
616 | 0 | errorCode == TaskHandlerErr::NOSUCHFILEORDIR_FOR_REMOVE ) |
617 | 0 | { |
618 | 0 | switch( minorCode ) |
619 | 0 | { |
620 | 0 | case FileBase::E_INVAL: // the format of the parameters was not valid |
621 | 0 | ioErrorCode = IOErrorCode_INVALID_PARAMETER; |
622 | 0 | break; |
623 | 0 | case FileBase::E_NOMEM: // not enough memory for allocating structures |
624 | 0 | ioErrorCode = IOErrorCode_OUT_OF_MEMORY; |
625 | 0 | break; |
626 | 0 | case FileBase::E_ROFS: // #i4735# handle ROFS transparently as ACCESS_DENIED |
627 | 0 | case FileBase::E_ACCES: // permission denied |
628 | 0 | ioErrorCode = IOErrorCode_ACCESS_DENIED; |
629 | 0 | break; |
630 | 0 | case FileBase::E_MFILE: // too many open files used by the process |
631 | 0 | case FileBase::E_NFILE: // too many open files in the system |
632 | 0 | ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES; |
633 | 0 | break; |
634 | 0 | case FileBase::E_NOLINK: // Link has been severed |
635 | 0 | case FileBase::E_NOENT: // No such file or directory |
636 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING; |
637 | 0 | break; |
638 | 0 | case FileBase::E_NAMETOOLONG: // File name too long |
639 | 0 | ioErrorCode = IOErrorCode_NAME_TOO_LONG; |
640 | 0 | break; |
641 | 0 | case FileBase::E_NOTDIR: // A component of the path prefix of path is not a directory |
642 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING_PATH; |
643 | 0 | break; |
644 | 0 | case FileBase::E_LOOP: // Too many symbolic links encountered |
645 | 0 | case FileBase::E_IO: // I/O error |
646 | 0 | case FileBase::E_MULTIHOP: // Multihop attempted |
647 | 0 | case FileBase::E_FAULT: // Bad address |
648 | 0 | case FileBase::E_INTR: // function call was interrupted |
649 | 0 | case FileBase::E_NOSYS: // Function not implemented |
650 | 0 | case FileBase::E_NOSPC: // No space left on device |
651 | 0 | case FileBase::E_NXIO: // No such device or address |
652 | 0 | case FileBase::E_OVERFLOW: // Value too large for defined data type |
653 | 0 | case FileBase::E_BADF: // Invalid oslDirectoryItem parameter |
654 | 0 | default: |
655 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
656 | 0 | break; |
657 | 0 | } |
658 | 0 | cancelCommandExecution( |
659 | 0 | ioErrorCode, |
660 | 0 | generateErrorArguments(aUncPath), |
661 | 0 | xEnv, |
662 | 0 | u"a file status object could not be filled"_ustr, |
663 | 0 | xComProc ); |
664 | 0 | } |
665 | 0 | else if( errorCode == TaskHandlerErr::DELETEFILE_FOR_REMOVE || |
666 | 0 | errorCode == TaskHandlerErr::DELETEDIRECTORY_FOR_REMOVE ) |
667 | 0 | { |
668 | 0 | switch( minorCode ) |
669 | 0 | { |
670 | 0 | case FileBase::E_INVAL: // the format of the parameters was not valid |
671 | 0 | ioErrorCode = IOErrorCode_INVALID_PARAMETER; |
672 | 0 | break; |
673 | 0 | case FileBase::E_NOMEM: // not enough memory for allocating structures |
674 | 0 | ioErrorCode = IOErrorCode_OUT_OF_MEMORY; |
675 | 0 | break; |
676 | 0 | case FileBase::E_ACCES: // Permission denied |
677 | 0 | ioErrorCode = IOErrorCode_ACCESS_DENIED; |
678 | 0 | break; |
679 | 0 | case FileBase::E_PERM: // Operation not permitted |
680 | 0 | case FileBase::E_ISDIR: // Is a directory |
681 | 0 | case FileBase::E_ROFS: // Read-only file system |
682 | 0 | ioErrorCode = IOErrorCode_NOT_SUPPORTED; |
683 | 0 | break; |
684 | 0 | case FileBase::E_NAMETOOLONG: // File name too long |
685 | 0 | ioErrorCode = IOErrorCode_NAME_TOO_LONG; |
686 | 0 | break; |
687 | 0 | case FileBase::E_NOLINK: // Link has been severed |
688 | 0 | case FileBase::E_NOENT: // No such file or directory |
689 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING; |
690 | 0 | break; |
691 | 0 | case FileBase::E_BUSY: // Device or resource busy |
692 | 0 | ioErrorCode = IOErrorCode_LOCKING_VIOLATION; |
693 | 0 | break; |
694 | 0 | case FileBase::E_FAULT: // Bad address |
695 | 0 | case FileBase::E_LOOP: // Too many symbolic links encountered |
696 | 0 | case FileBase::E_IO: // I/O error |
697 | 0 | case FileBase::E_INTR: // function call was interrupted |
698 | 0 | case FileBase::E_MULTIHOP: // Multihop attempted |
699 | 0 | default: |
700 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
701 | 0 | break; |
702 | 0 | } |
703 | 0 | cancelCommandExecution( |
704 | 0 | ioErrorCode, |
705 | 0 | generateErrorArguments(aUncPath), |
706 | 0 | xEnv, |
707 | 0 | u"a file or directory could not be deleted"_ustr, |
708 | 0 | xComProc ); |
709 | 0 | } |
710 | 0 | else if( errorCode == TaskHandlerErr::TRANSFER_BY_COPY_SOURCE || |
711 | 0 | errorCode == TaskHandlerErr::TRANSFER_BY_COPY_SOURCESTAT || |
712 | 0 | errorCode == TaskHandlerErr::TRANSFER_BY_MOVE_SOURCE || |
713 | 0 | errorCode == TaskHandlerErr::TRANSFER_BY_MOVE_SOURCESTAT || |
714 | 0 | errorCode == TaskHandlerErr::TRANSFER_DESTFILETYPE || |
715 | 0 | errorCode == TaskHandlerErr::FILETYPE_FOR_REMOVE || |
716 | 0 | errorCode == TaskHandlerErr::DIRECTORYEXHAUSTED_FOR_REMOVE || |
717 | 0 | errorCode == TaskHandlerErr::TRANSFER_INVALIDURL ) |
718 | 0 | { |
719 | 0 | OUString aMsg; |
720 | 0 | switch( minorCode ) |
721 | 0 | { |
722 | 0 | case FileBase::E_NOENT: // No such file or directory |
723 | 0 | if ( errorCode == TaskHandlerErr::TRANSFER_BY_COPY_SOURCE || |
724 | 0 | errorCode == TaskHandlerErr::TRANSFER_BY_COPY_SOURCESTAT || |
725 | 0 | errorCode == TaskHandlerErr::TRANSFER_BY_MOVE_SOURCE || |
726 | 0 | errorCode == TaskHandlerErr::TRANSFER_BY_MOVE_SOURCESTAT ) |
727 | 0 | { |
728 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING; |
729 | 0 | aMsg = "source file/folder does not exist"; |
730 | 0 | break; |
731 | 0 | } |
732 | 0 | else |
733 | 0 | { |
734 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
735 | 0 | aMsg = "a general error during transfer command"; |
736 | 0 | break; |
737 | 0 | } |
738 | 0 | default: |
739 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
740 | 0 | aMsg = "a general error during transfer command"; |
741 | 0 | break; |
742 | 0 | } |
743 | 0 | cancelCommandExecution( |
744 | 0 | ioErrorCode, |
745 | 0 | generateErrorArguments(aUncPath), |
746 | 0 | xEnv, |
747 | 0 | aMsg, |
748 | 0 | xComProc ); |
749 | 0 | } |
750 | 0 | else if( errorCode == TaskHandlerErr::TRANSFER_INVALIDSCHEME ) |
751 | 0 | { |
752 | 0 | aAny <<= InteractiveBadTransferURLException( |
753 | 0 | u"bad transfer url"_ustr, |
754 | 0 | xComProc); |
755 | 0 | cancelCommandExecution( aAny,xEnv ); |
756 | 0 | } |
757 | 0 | else if( errorCode == TaskHandlerErr::OVERWRITE_FOR_MOVE || |
758 | 0 | errorCode == TaskHandlerErr::OVERWRITE_FOR_COPY || |
759 | 0 | errorCode == TaskHandlerErr::NAMECLASHMOVE_FOR_MOVE || |
760 | 0 | errorCode == TaskHandlerErr::NAMECLASHMOVE_FOR_COPY || |
761 | 0 | errorCode == TaskHandlerErr::KEEPERROR_FOR_MOVE || |
762 | 0 | errorCode == TaskHandlerErr::KEEPERROR_FOR_COPY || |
763 | 0 | errorCode == TaskHandlerErr::RENAME_FOR_MOVE || |
764 | 0 | errorCode == TaskHandlerErr::RENAME_FOR_COPY || |
765 | 0 | errorCode == TaskHandlerErr::RENAMEMOVE_FOR_MOVE || |
766 | 0 | errorCode == TaskHandlerErr::RENAMEMOVE_FOR_COPY ) |
767 | 0 | { |
768 | 0 | OUString aMsg( |
769 | 0 | u"general error during transfer"_ustr); |
770 | |
|
771 | 0 | switch( minorCode ) |
772 | 0 | { |
773 | 0 | case FileBase::E_EXIST: |
774 | 0 | ioErrorCode = IOErrorCode_ALREADY_EXISTING; |
775 | 0 | break; |
776 | 0 | case FileBase::E_INVAL: // the format of the parameters was not valid |
777 | 0 | ioErrorCode = IOErrorCode_INVALID_PARAMETER; |
778 | 0 | break; |
779 | 0 | case FileBase::E_NOMEM: // not enough memory for allocating structures |
780 | 0 | ioErrorCode = IOErrorCode_OUT_OF_MEMORY; |
781 | 0 | break; |
782 | 0 | case FileBase::E_ACCES: // Permission denied |
783 | 0 | ioErrorCode = IOErrorCode_ACCESS_DENIED; |
784 | 0 | break; |
785 | 0 | case FileBase::E_PERM: // Operation not permitted |
786 | 0 | ioErrorCode = IOErrorCode_NOT_SUPPORTED; |
787 | 0 | break; |
788 | 0 | case FileBase::E_NAMETOOLONG: // File name too long |
789 | 0 | ioErrorCode = IOErrorCode_NAME_TOO_LONG; |
790 | 0 | break; |
791 | 0 | case FileBase::E_NOENT: // No such file or directory |
792 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING; |
793 | 0 | aMsg = "file/folder does not exist"; |
794 | 0 | break; |
795 | 0 | case FileBase::E_ROFS: // Read-only file system<p> |
796 | 0 | ioErrorCode = IOErrorCode_NOT_EXISTING; |
797 | 0 | break; |
798 | 0 | default: |
799 | 0 | ioErrorCode = IOErrorCode_GENERAL; |
800 | 0 | break; |
801 | 0 | } |
802 | 0 | cancelCommandExecution( |
803 | 0 | ioErrorCode, |
804 | 0 | generateErrorArguments(aUncPath), |
805 | 0 | xEnv, |
806 | 0 | aMsg, |
807 | 0 | xComProc ); |
808 | 0 | } |
809 | 0 | else if( errorCode == TaskHandlerErr::NAMECLASH_FOR_COPY || |
810 | 0 | errorCode == TaskHandlerErr::NAMECLASH_FOR_MOVE ) |
811 | 0 | { |
812 | 0 | NameClashException excep(u"name clash during copy or move"_ustr, |
813 | 0 | Reference<XInterface>(xComProc, UNO_QUERY), |
814 | 0 | InteractionClassification_ERROR, OUString(getTitle(aUncPath))); |
815 | |
|
816 | 0 | cancelCommandExecution(Any(excep), xEnv); |
817 | 0 | } |
818 | 0 | else if( errorCode == TaskHandlerErr::NAMECLASHSUPPORT_FOR_MOVE || |
819 | 0 | errorCode == TaskHandlerErr::NAMECLASHSUPPORT_FOR_COPY ) |
820 | 0 | { |
821 | 0 | UnsupportedNameClashException excep( |
822 | 0 | u"name clash value not supported during copy or move"_ustr, |
823 | 0 | Reference<XInterface>(xComProc, UNO_QUERY), minorCode); |
824 | |
|
825 | 0 | cancelCommandExecution(Any(excep), xEnv); |
826 | 0 | } |
827 | 0 | else |
828 | 0 | { |
829 | | // case TaskHandlerErr::NO_ERROR: |
830 | 0 | return; |
831 | 0 | } |
832 | 0 | } |
833 | | |
834 | | |
835 | | } // end namespace fileaccess |
836 | | |
837 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |