1/*
2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.nio.fs;
27
28import java.nio.file.*;
29import java.io.IOException;
30
31import static sun.nio.fs.WindowsConstants.*;
32
33/**
34 * Internal exception thrown when a Win32 calls fails.
35 */
36
37class WindowsException extends Exception {
38    static final long serialVersionUID = 2765039493083748820L;
39
40    private int lastError;
41    private String msg;
42
43    WindowsException(int lastError) {
44        this.lastError = lastError;
45        this.msg = null;
46    }
47
48    WindowsException(String msg) {
49        this.lastError = 0;
50        this.msg = msg;
51    }
52
53    int lastError() {
54        return lastError;
55    }
56
57    String errorString() {
58        if (msg == null) {
59            msg = WindowsNativeDispatcher.FormatMessage(lastError);
60            if (msg == null) {
61                msg = "Unknown error: 0x" + Integer.toHexString(lastError);
62            }
63        }
64        return msg;
65    }
66
67    @Override
68    public String getMessage() {
69        return errorString();
70    }
71
72    @Override
73    public Throwable fillInStackTrace() {
74        // This is an internal exception; the stack trace is irrelevant.
75        return this;
76    }
77
78    private IOException translateToIOException(String file, String other) {
79        // not created with last error
80        if (lastError() == 0)
81            return new IOException(errorString());
82
83        // handle specific cases
84        if (lastError() == ERROR_FILE_NOT_FOUND || lastError() == ERROR_PATH_NOT_FOUND)
85            return new NoSuchFileException(file, other, null);
86        if (lastError() == ERROR_FILE_EXISTS || lastError() == ERROR_ALREADY_EXISTS)
87            return new FileAlreadyExistsException(file, other, null);
88        if (lastError() == ERROR_ACCESS_DENIED)
89            return new AccessDeniedException(file, other, null);
90
91        // fallback to the more general exception
92        return new FileSystemException(file, other, errorString());
93    }
94
95    void rethrowAsIOException(String file) throws IOException {
96        IOException x = translateToIOException(file, null);
97        throw x;
98    }
99
100    void rethrowAsIOException(WindowsPath file, WindowsPath other) throws IOException {
101        String a = (file == null) ? null : file.getPathForExceptionMessage();
102        String b = (other == null) ? null : other.getPathForExceptionMessage();
103        IOException x = translateToIOException(a, b);
104        throw x;
105    }
106
107    void rethrowAsIOException(WindowsPath file) throws IOException {
108        rethrowAsIOException(file, null);
109    }
110
111    IOException asIOException(WindowsPath file) {
112        return translateToIOException(file.getPathForExceptionMessage(), null);
113    }
114
115}
116