1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "com/sun/star/beans/PropertyValue.hpp"
25 #include "com/sun/star/task/XInteractionRequest.hpp"
26 #include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
27 
28 #include "ids.hrc"
29 
30 #include "iahndl.hxx"
31 
32 using namespace com::sun::star;
33 
34 namespace {
35 
36 bool
getStringRequestArgument(uno::Sequence<uno::Any> const & rArguments,rtl::OUString const & rKey,rtl::OUString * pValue)37 getStringRequestArgument(uno::Sequence< uno::Any > const & rArguments,
38                          rtl::OUString const & rKey,
39                          rtl::OUString * pValue)
40     SAL_THROW(())
41 {
42     for (sal_Int32 i = 0; i < rArguments.getLength(); ++i)
43     {
44         beans::PropertyValue aProperty;
45         if ((rArguments[i] >>= aProperty) && aProperty.Name == rKey)
46         {
47             rtl::OUString aValue;
48             if (aProperty.Value >>= aValue)
49             {
50                 if (pValue)
51                     *pValue = aValue;
52                 return true;
53             }
54         }
55     }
56     return false;
57 }
58 
59 bool
getBoolRequestArgument(uno::Sequence<uno::Any> const & rArguments,rtl::OUString const & rKey,bool * pValue)60 getBoolRequestArgument(uno::Sequence< uno::Any > const & rArguments,
61                        rtl::OUString const & rKey,
62                        bool * pValue)
63     SAL_THROW(())
64 {
65     for (sal_Int32 i = 0; i < rArguments.getLength(); ++i)
66     {
67         beans::PropertyValue aProperty;
68         if ((rArguments[i] >>= aProperty) && aProperty.Name == rKey)
69         {
70             sal_Bool bValue = sal_Bool();
71             if (aProperty.Value >>= bValue)
72             {
73                 if (pValue)
74                     *pValue = bValue;
75                 return true;
76             }
77         }
78     }
79     return false;
80 }
81 
82 bool
getResourceNameRequestArgument(uno::Sequence<uno::Any> const & rArguments,rtl::OUString * pValue)83 getResourceNameRequestArgument(uno::Sequence< uno::Any > const & rArguments,
84                                rtl::OUString * pValue)
85     SAL_THROW(())
86 {
87     if (!getStringRequestArgument(rArguments,
88                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
89                                       "Uri")),
90                                   pValue))
91         return false;
92     // Use the resource name only for file URLs, to avoid confusion:
93     //TODO! work with ucp locality concept instead of hardcoded "file"?
94     if (pValue
95         && pValue->matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(
96                                                   "file:")))
97         getStringRequestArgument(rArguments,
98                                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
99                                                    "ResourceName")),
100                                  pValue);
101     return true;
102 }
103 
104 } // namespace
105 
106 bool
handleInteractiveIOException(uno::Reference<task::XInteractionRequest> const & rRequest,bool bObtainErrorStringOnly,bool & bHasErrorString,rtl::OUString & rErrorString)107 UUIInteractionHelper::handleInteractiveIOException(
108         uno::Reference< task::XInteractionRequest > const & rRequest,
109         bool bObtainErrorStringOnly,
110         bool & bHasErrorString,
111         rtl::OUString & rErrorString)
112     SAL_THROW((uno::RuntimeException))
113 {
114     uno::Any aAnyRequest(rRequest->getRequest());
115     bHasErrorString = false;
116 
117     ucb::InteractiveIOException aIoException;
118     if (aAnyRequest >>= aIoException)
119     {
120         uno::Sequence< uno::Any > aRequestArguments;
121         ucb::InteractiveAugmentedIOException aAugmentedIoException;
122         if (aAnyRequest >>= aAugmentedIoException)
123             aRequestArguments = aAugmentedIoException.Arguments;
124 
125         ErrCode nErrorCode;
126         std::vector< rtl::OUString > aArguments;
127         static ErrCode const
128             aErrorCode[ucb::IOErrorCode_WRONG_VERSION + 1][2]
129             = { { ERRCODE_IO_ABORT, ERRCODE_UUI_IO_ABORT }, // ABORT
130                 { ERRCODE_IO_ACCESSDENIED, ERRCODE_UUI_IO_ACCESSDENIED },
131                 // ACCESS_DENIED
132                 { ERRCODE_IO_ALREADYEXISTS,
133                   ERRCODE_UUI_IO_ALREADYEXISTS }, // ALREADY_EXISTING
134                 { ERRCODE_IO_BADCRC, ERRCODE_UUI_IO_BADCRC }, // BAD_CRC
135                 { ERRCODE_IO_CANTCREATE, ERRCODE_UUI_IO_CANTCREATE },
136                 // CANT_CREATE
137                 { ERRCODE_IO_CANTREAD, ERRCODE_UUI_IO_CANTREAD },
138                 // CANT_READ
139                 { ERRCODE_IO_CANTSEEK, ERRCODE_UUI_IO_CANTSEEK },
140                 // CANT_SEEK
141                 { ERRCODE_IO_CANTTELL, ERRCODE_UUI_IO_CANTTELL },
142                 // CANT_TELL
143                 { ERRCODE_IO_CANTWRITE, ERRCODE_UUI_IO_CANTWRITE },
144                 // CANT_WRITE
145                 { ERRCODE_IO_CURRENTDIR, ERRCODE_UUI_IO_CURRENTDIR },
146                 // CURRENT_DIRECTORY
147                 { ERRCODE_IO_DEVICENOTREADY, ERRCODE_UUI_IO_NOTREADY },
148                 // DEVICE_NOT_READY
149                 { ERRCODE_IO_NOTSAMEDEVICE,
150                   ERRCODE_UUI_IO_NOTSAMEDEVICE }, // DIFFERENT_DEVICES
151                 { ERRCODE_IO_GENERAL, ERRCODE_UUI_IO_GENERAL }, // GENERAL
152                 { ERRCODE_IO_INVALIDACCESS,
153                   ERRCODE_UUI_IO_INVALIDACCESS }, // INVALID_ACCESS
154                 { ERRCODE_IO_INVALIDCHAR, ERRCODE_UUI_IO_INVALIDCHAR },
155                 // INVALID_CHARACTER
156                 { ERRCODE_IO_INVALIDDEVICE,
157                   ERRCODE_UUI_IO_INVALIDDEVICE }, // INVALID_DEVICE
158                 { ERRCODE_IO_INVALIDLENGTH,
159                   ERRCODE_UUI_IO_INVALIDLENGTH }, // INVALID_LENGTH
160                 { ERRCODE_IO_INVALIDPARAMETER,
161                   ERRCODE_UUI_IO_INVALIDPARAMETER }, // INVALID_PARAMETER
162                 { ERRCODE_IO_ISWILDCARD, ERRCODE_UUI_IO_ISWILDCARD },
163                 // IS_WILDCARD
164                 { ERRCODE_IO_LOCKVIOLATION,
165                   ERRCODE_UUI_IO_LOCKVIOLATION }, // LOCKING_VIOLATION
166                 { ERRCODE_IO_MISPLACEDCHAR,
167                   ERRCODE_UUI_IO_MISPLACEDCHAR }, // MISPLACED_CHARACTER
168                 { ERRCODE_IO_NAMETOOLONG, ERRCODE_UUI_IO_NAMETOOLONG },
169                 // NAME_TOO_LONG
170                 { ERRCODE_IO_NOTEXISTS, ERRCODE_UUI_IO_NOTEXISTS },
171                 // NOT_EXISTING
172                 { ERRCODE_IO_NOTEXISTSPATH,
173                   ERRCODE_UUI_IO_NOTEXISTSPATH }, // NOT_EXISTING_PATH
174                 { ERRCODE_IO_NOTSUPPORTED, ERRCODE_UUI_IO_NOTSUPPORTED },
175                 // NOT_SUPPORTED
176                 { ERRCODE_IO_NOTADIRECTORY,
177                   ERRCODE_UUI_IO_NOTADIRECTORY }, // NO_DIRECTORY
178                 { ERRCODE_IO_NOTAFILE, ERRCODE_UUI_IO_NOTAFILE },
179                 // NO_FILE
180                 { ERRCODE_IO_OUTOFSPACE, ERRCODE_UUI_IO_OUTOFSPACE },
181                 // OUT_OF_DISK_SPACE
182                 { ERRCODE_IO_TOOMANYOPENFILES,
183                   ERRCODE_UUI_IO_TOOMANYOPENFILES },
184                 // OUT_OF_FILE_HANDLES
185                 { ERRCODE_IO_OUTOFMEMORY, ERRCODE_UUI_IO_OUTOFMEMORY },
186                 // OUT_OF_MEMORY
187                 { ERRCODE_IO_PENDING, ERRCODE_UUI_IO_PENDING }, // PENDING
188                 { ERRCODE_IO_RECURSIVE, ERRCODE_UUI_IO_RECURSIVE },
189                 // RECURSIVE
190                 { ERRCODE_IO_UNKNOWN, ERRCODE_UUI_IO_UNKNOWN }, // UNKNOWN
191                 { ERRCODE_IO_WRITEPROTECTED,
192                   ERRCODE_UUI_IO_WRITEPROTECTED }, // WRITE_PROTECTED
193                 { ERRCODE_IO_WRONGFORMAT, ERRCODE_UUI_IO_WRONGFORMAT },
194                 // WRONG_FORMAT
195                 { ERRCODE_IO_WRONGVERSION,
196                   ERRCODE_UUI_IO_WRONGVERSION } }; // WRONG_VERSION
197         switch (aIoException.Code)
198         {
199         case ucb::IOErrorCode_CANT_CREATE:
200             {
201                 rtl::OUString aArgFolder;
202                 if (getStringRequestArgument(
203                         aRequestArguments,
204                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
205                                           "Folder")),
206                         &aArgFolder))
207                 {
208                     rtl::OUString aArgUri;
209                     if (getResourceNameRequestArgument(aRequestArguments,
210                                                        &aArgUri))
211                     {
212                         nErrorCode = ERRCODE_UUI_IO_CANTCREATE;
213                         aArguments.reserve(2);
214                         aArguments.push_back(aArgUri);
215                         aArguments.push_back(aArgFolder);
216                     }
217                     else
218                     {
219                         nErrorCode = ERRCODE_UUI_IO_CANTCREATE_NONAME;
220                         aArguments.push_back(aArgFolder);
221                     }
222                 }
223                 else
224                     nErrorCode = aErrorCode[aIoException.Code][0];
225                 break;
226             }
227 
228         case ucb::IOErrorCode_DEVICE_NOT_READY:
229             {
230                 rtl::OUString aArgUri;
231                 if (getResourceNameRequestArgument(aRequestArguments,
232                                                    &aArgUri))
233                 {
234                     rtl::OUString aResourceType;
235                     getStringRequestArgument(
236                         aRequestArguments,
237                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
238                                           "ResourceType")),
239                         &aResourceType);
240                     bool bRemovable = false;
241                     getBoolRequestArgument(aRequestArguments,
242                                            rtl::OUString(
243                                                RTL_CONSTASCII_USTRINGPARAM(
244                                                    "Removable")),
245                                            &bRemovable);
246                     nErrorCode
247                         = aResourceType.equalsAsciiL(
248                             RTL_CONSTASCII_STRINGPARAM("volume"))
249                         ? (bRemovable
250                            ? ERRCODE_UUI_IO_NOTREADY_VOLUME_REMOVABLE
251                            : ERRCODE_UUI_IO_NOTREADY_VOLUME)
252                         : (bRemovable
253                            ? ERRCODE_UUI_IO_NOTREADY_REMOVABLE
254                            : ERRCODE_UUI_IO_NOTREADY);
255                     aArguments.push_back(aArgUri);
256                 }
257                 else
258             nErrorCode = aErrorCode[aIoException.Code][0];
259                 break;
260             }
261 
262         case ucb::IOErrorCode_DIFFERENT_DEVICES:
263             {
264                 rtl::OUString aArgVolume;
265                 rtl::OUString aArgOtherVolume;
266                 if (getStringRequestArgument(
267                         aRequestArguments,
268                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
269                                           "Volume")),
270                         &aArgVolume)
271                     && getStringRequestArgument(
272                         aRequestArguments,
273                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
274                                           "OtherVolume")),
275                         &aArgOtherVolume))
276                 {
277                     nErrorCode = aErrorCode[aIoException.Code][1];
278                     aArguments.reserve(2);
279                     aArguments.push_back(aArgVolume);
280                     aArguments.push_back(aArgOtherVolume);
281                 }
282                 else
283                     nErrorCode = aErrorCode[aIoException.Code][0];
284                 break;
285         }
286 
287         case ucb::IOErrorCode_NOT_EXISTING:
288             {
289                 rtl::OUString aArgUri;
290                 if (getResourceNameRequestArgument(aRequestArguments,
291                            &aArgUri))
292                 {
293                     rtl::OUString aResourceType;
294                     getStringRequestArgument(
295                         aRequestArguments,
296                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
297                                           "ResourceType")),
298                         &aResourceType);
299                     nErrorCode
300                         = aResourceType.equalsAsciiL(
301                             RTL_CONSTASCII_STRINGPARAM("volume"))
302                         ? ERRCODE_UUI_IO_NOTEXISTS_VOLUME
303                         : (aResourceType.equalsAsciiL(
304                                RTL_CONSTASCII_STRINGPARAM("folder"))
305                            ? ERRCODE_UUI_IO_NOTEXISTS_FOLDER
306                            : ERRCODE_UUI_IO_NOTEXISTS);
307                     aArguments.push_back(aArgUri);
308                 }
309                 else
310                     nErrorCode = aErrorCode[aIoException.Code][0];
311                 break;
312             }
313 
314         default:
315             {
316                 rtl::OUString aArgUri;
317                 if (getResourceNameRequestArgument(aRequestArguments,
318                                                    &aArgUri))
319                 {
320                     nErrorCode = aErrorCode[aIoException.Code][1];
321                     aArguments.push_back(aArgUri);
322                 }
323                 else
324                     nErrorCode = aErrorCode[aIoException.Code][0];
325                 break;
326             }
327         }
328 
329         handleErrorHandlerRequest(aIoException.Classification,
330                                   nErrorCode,
331                                   aArguments,
332                                   rRequest->getContinuations(),
333                                   bObtainErrorStringOnly,
334                                   bHasErrorString,
335                                   rErrorString);
336         return true;
337     }
338     return false;
339 }
340