xref: /core/uui/source/iahndl-ioexceptions.cxx (revision bb06f513)
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 <com/sun/star/beans/PropertyValue.hpp>
21 #include <com/sun/star/task/XInteractionRequest.hpp>
22 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
23 #include <comphelper/fileurl.hxx>
24 
25 #include <ids.hxx>
26 
27 #include "iahndl.hxx"
28 
29 using namespace com::sun::star;
30 
31 namespace {
32 
33 template<class T>
34 bool
getRequestArgument(uno::Sequence<uno::Any> const & rArguments,std::u16string_view rKey,T * pValue)35 getRequestArgument(uno::Sequence< uno::Any > const & rArguments,
36                    std::u16string_view rKey,
37                    T * pValue)
38 {
39     for (const auto& rArgument : rArguments)
40     {
41         beans::PropertyValue aProperty;
42         if ((rArgument >>= aProperty) && aProperty.Name == rKey)
43         {
44             T aValue;
45             if (aProperty.Value >>= aValue)
46             {
47                 if (pValue)
48                     *pValue = aValue;
49                 return true;
50             }
51         }
52     }
53     return false;
54 }
55 
56 bool
getResourceNameRequestArgument(uno::Sequence<uno::Any> const & rArguments,OUString * pValue)57 getResourceNameRequestArgument(uno::Sequence< uno::Any > const & rArguments,
58                                OUString * pValue)
59 {
60     if (!getRequestArgument(rArguments, u"Uri",  pValue))
61         return false;
62     // Use the resource name only for file URLs, to avoid confusion:
63     if (pValue && comphelper::isFileUrl(*pValue))
64         getRequestArgument(rArguments, u"ResourceName", pValue);
65     return true;
66 }
67 
68 } // namespace
69 
70 bool
handleInteractiveIOException(uno::Reference<task::XInteractionRequest> const & rRequest,bool bObtainErrorStringOnly,bool & bHasErrorString,OUString & rErrorString)71 UUIInteractionHelper::handleInteractiveIOException(
72         uno::Reference< task::XInteractionRequest > const & rRequest,
73         bool bObtainErrorStringOnly,
74         bool & bHasErrorString,
75         OUString & rErrorString)
76 {
77     uno::Any aAnyRequest(rRequest->getRequest());
78     bHasErrorString = false;
79 
80     ucb::InteractiveIOException aIoException;
81     if (aAnyRequest >>= aIoException)
82     {
83         uno::Sequence< uno::Any > aRequestArguments;
84         ucb::InteractiveAugmentedIOException aAugmentedIoException;
85         if (aAnyRequest >>= aAugmentedIoException)
86             aRequestArguments = aAugmentedIoException.Arguments;
87 
88         ErrCode nErrorCode;
89         std::vector< OUString > aArguments;
90         static ErrCode const
91             aErrorCode[sal_Int32(ucb::IOErrorCode_WRONG_VERSION) + 1][2]
92             = { { ERRCODE_IO_ABORT, ERRCODE_UUI_IO_ABORT }, // ABORT
93                 { ERRCODE_IO_ACCESSDENIED, ERRCODE_UUI_IO_ACCESSDENIED },
94                 // ACCESS_DENIED
95                 { ERRCODE_IO_ALREADYEXISTS,
96                   ERRCODE_UUI_IO_ALREADYEXISTS }, // ALREADY_EXISTING
97                 { ERRCODE_IO_BADCRC, ERRCODE_UUI_IO_BADCRC }, // BAD_CRC
98                 { ERRCODE_IO_CANTCREATE, ERRCODE_UUI_IO_CANTCREATE },
99                 // CANT_CREATE
100                 { ERRCODE_IO_CANTREAD, ERRCODE_UUI_IO_CANTREAD },
101                 // CANT_READ
102                 { ERRCODE_IO_CANTSEEK, ERRCODE_UUI_IO_CANTSEEK },
103                 // CANT_SEEK
104                 { ERRCODE_IO_CANTTELL, ERRCODE_UUI_IO_CANTTELL },
105                 // CANT_TELL
106                 { ERRCODE_IO_CANTWRITE, ERRCODE_UUI_IO_CANTWRITE },
107                 // CANT_WRITE
108                 { ERRCODE_IO_CURRENTDIR, ERRCODE_UUI_IO_CURRENTDIR },
109                 // CURRENT_DIRECTORY
110                 { ERRCODE_IO_DEVICENOTREADY, ERRCODE_UUI_IO_NOTREADY },
111                 // DEVICE_NOT_READY
112                 { ERRCODE_IO_NOTSAMEDEVICE,
113                   ERRCODE_UUI_IO_NOTSAMEDEVICE }, // DIFFERENT_DEVICES
114                 { ERRCODE_IO_GENERAL, ERRCODE_UUI_IO_GENERAL }, // GENERAL
115                 { ERRCODE_IO_INVALIDACCESS,
116                   ERRCODE_UUI_IO_INVALIDACCESS }, // INVALID_ACCESS
117                 { ERRCODE_IO_INVALIDCHAR, ERRCODE_UUI_IO_INVALIDCHAR },
118                 // INVALID_CHARACTER
119                 { ERRCODE_IO_INVALIDDEVICE,
120                   ERRCODE_UUI_IO_INVALIDDEVICE }, // INVALID_DEVICE
121                 { ERRCODE_IO_INVALIDLENGTH,
122                   ERRCODE_UUI_IO_INVALIDLENGTH }, // INVALID_LENGTH
123                 { ERRCODE_IO_INVALIDPARAMETER,
124                   ERRCODE_UUI_IO_INVALIDPARAMETER }, // INVALID_PARAMETER
125                 { ERRCODE_IO_ISWILDCARD, ERRCODE_UUI_IO_ISWILDCARD },
126                 // IS_WILDCARD
127                 { ERRCODE_IO_LOCKVIOLATION,
128                   ERRCODE_UUI_IO_LOCKVIOLATION }, // LOCKING_VIOLATION
129                 { ERRCODE_IO_MISPLACEDCHAR,
130                   ERRCODE_UUI_IO_MISPLACEDCHAR }, // MISPLACED_CHARACTER
131                 { ERRCODE_IO_NAMETOOLONG, ERRCODE_UUI_IO_NAMETOOLONG },
132                 // NAME_TOO_LONG
133                 { ERRCODE_IO_NOTEXISTS, ERRCODE_UUI_IO_NOTEXISTS },
134                 // NOT_EXISTING
135                 { ERRCODE_IO_NOTEXISTSPATH,
136                   ERRCODE_UUI_IO_NOTEXISTSPATH }, // NOT_EXISTING_PATH
137                 { ERRCODE_IO_NOTSUPPORTED, ERRCODE_UUI_IO_NOTSUPPORTED },
138                 // NOT_SUPPORTED
139                 { ERRCODE_IO_NOTADIRECTORY,
140                   ERRCODE_UUI_IO_NOTADIRECTORY }, // NO_DIRECTORY
141                 { ERRCODE_IO_NOTAFILE, ERRCODE_UUI_IO_NOTAFILE },
142                 // NO_FILE
143                 { ERRCODE_IO_OUTOFSPACE, ERRCODE_UUI_IO_OUTOFSPACE },
144                 // OUT_OF_DISK_SPACE
145                 { ERRCODE_IO_TOOMANYOPENFILES,
146                   ERRCODE_UUI_IO_TOOMANYOPENFILES },
147                 // OUT_OF_FILE_HANDLES
148                 { ERRCODE_IO_OUTOFMEMORY, ERRCODE_UUI_IO_OUTOFMEMORY },
149                 // OUT_OF_MEMORY
150                 { ERRCODE_IO_PENDING, ERRCODE_UUI_IO_PENDING }, // PENDING
151                 { ERRCODE_IO_RECURSIVE, ERRCODE_UUI_IO_RECURSIVE },
152                 // RECURSIVE
153                 { ERRCODE_IO_UNKNOWN, ERRCODE_UUI_IO_UNKNOWN }, // UNKNOWN
154                 { ERRCODE_IO_WRITEPROTECTED,
155                   ERRCODE_UUI_IO_WRITEPROTECTED }, // WRITE_PROTECTED
156                 { ERRCODE_IO_WRONGFORMAT, ERRCODE_UUI_IO_WRONGFORMAT },
157                 // WRONG_FORMAT
158                 { ERRCODE_IO_WRONGVERSION,
159                   ERRCODE_UUI_IO_WRONGVERSION } }; // WRONG_VERSION
160         switch (aIoException.Code)
161         {
162         case ucb::IOErrorCode_CANT_CREATE:
163             {
164                 OUString aArgFolder;
165                 if (getRequestArgument(aRequestArguments, u"Folder", &aArgFolder))
166                 {
167                     OUString aArgUri;
168                     if (getResourceNameRequestArgument(aRequestArguments,
169                                                        &aArgUri))
170                     {
171                         nErrorCode = ERRCODE_UUI_IO_CANTCREATE;
172                         aArguments.reserve(2);
173                         aArguments.push_back(aArgUri);
174                         aArguments.push_back(aArgFolder);
175                     }
176                     else
177                     {
178                         nErrorCode = ERRCODE_UUI_IO_CANTCREATE_NONAME;
179                         aArguments.push_back(aArgFolder);
180                     }
181                 }
182                 else
183                     nErrorCode = aErrorCode[static_cast<sal_Int32>(aIoException.Code)][0];
184                 break;
185             }
186 
187         case ucb::IOErrorCode_DEVICE_NOT_READY:
188             {
189                 OUString aArgUri;
190                 if (getResourceNameRequestArgument(aRequestArguments,
191                                                    &aArgUri))
192                 {
193                     OUString aResourceType;
194                     getRequestArgument(aRequestArguments, u"ResourceType", &aResourceType);
195                     bool bRemovable = false;
196                     getRequestArgument(aRequestArguments, u"Removable", &bRemovable);
197                     nErrorCode = aResourceType == "volume"
198                         ? (bRemovable
199                            ? ERRCODE_UUI_IO_NOTREADY_VOLUME_REMOVABLE
200                            : ERRCODE_UUI_IO_NOTREADY_VOLUME)
201                         : (bRemovable
202                            ? ERRCODE_UUI_IO_NOTREADY_REMOVABLE
203                            : ERRCODE_UUI_IO_NOTREADY);
204                     aArguments.push_back(aArgUri);
205                 }
206                 else
207                     nErrorCode = aErrorCode[static_cast<sal_Int32>(aIoException.Code)][0];
208                 break;
209             }
210 
211         case ucb::IOErrorCode_DIFFERENT_DEVICES:
212             {
213                 OUString aArgVolume;
214                 OUString aArgOtherVolume;
215                 if (getRequestArgument(aRequestArguments, u"Volume", &aArgVolume)
216                     && getRequestArgument(aRequestArguments, u"OtherVolume",
217                         &aArgOtherVolume))
218                 {
219                     nErrorCode = aErrorCode[static_cast<sal_Int32>(aIoException.Code)][1];
220                     aArguments.reserve(2);
221                     aArguments.push_back(aArgVolume);
222                     aArguments.push_back(aArgOtherVolume);
223                 }
224                 else
225                     nErrorCode = aErrorCode[static_cast<sal_Int32>(aIoException.Code)][0];
226                 break;
227         }
228 
229         case ucb::IOErrorCode_NOT_EXISTING:
230             {
231                 OUString aArgUri;
232                 if (getResourceNameRequestArgument(aRequestArguments,
233                            &aArgUri))
234                 {
235                     OUString aResourceType;
236                     getRequestArgument(aRequestArguments, u"ResourceType",
237                                             &aResourceType);
238                     nErrorCode = aResourceType == "volume"
239                         ? ERRCODE_UUI_IO_NOTEXISTS_VOLUME
240                         : (aResourceType == "folder"
241                            ? ERRCODE_UUI_IO_NOTEXISTS_FOLDER
242                            : ERRCODE_UUI_IO_NOTEXISTS);
243                     aArguments.push_back(aArgUri);
244                 }
245                 else
246                     nErrorCode = aErrorCode[static_cast<sal_Int32>(aIoException.Code)][0];
247                 break;
248             }
249 
250         default:
251             {
252                 OUString aArgUri;
253                 if (getResourceNameRequestArgument(aRequestArguments,
254                                                    &aArgUri))
255                 {
256                     nErrorCode = aErrorCode[static_cast<sal_Int32>(aIoException.Code)][1];
257                     aArguments.push_back(aArgUri);
258                 }
259                 else
260                     nErrorCode = aErrorCode[static_cast<sal_Int32>(aIoException.Code)][0];
261                 break;
262             }
263         }
264 
265         handleErrorHandlerRequest(aIoException.Classification,
266                                   nErrorCode,
267                                   aArguments,
268                                   rRequest->getContinuations(),
269                                   bObtainErrorStringOnly,
270                                   bHasErrorString,
271                                   rErrorString);
272         return true;
273     }
274     return false;
275 }
276 
277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
278