summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/os_win/os_winerr.c
blob: 56869f0432b8feb73052ca56d277400e4dc3c39f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*-
 * Copyright (c) 2014-2020 MongoDB, Inc.
 * Copyright (c) 2008-2014 WiredTiger, Inc.
 *	All rights reserved.
 *
 * See the file LICENSE for redistribution information.
 */

#include "wt_internal.h"

/*
 * __wt_getlasterror --
 *     Return GetLastError, or a relatively generic Windows error if the system error code isn't
 *     set.
 */
DWORD
__wt_getlasterror(void)
{
    DWORD windows_error;

    /*
     * Check for ERROR_SUCCESS: It's easy to introduce a problem by calling the wrong error
     * function, for example, this function when the MSVC function set the C runtime error value.
     * Handle gracefully and always return an error.
     */
    windows_error = GetLastError();
    return (windows_error == ERROR_SUCCESS ? ERROR_INVALID_PARAMETER : windows_error);
}

/*
 * __wt_map_windows_error --
 *     Map Windows errors to POSIX/ANSI errors.
 */
int
__wt_map_windows_error(DWORD windows_error)
{
    static const struct {
        int windows_error;
        int posix_error;
    } list[] = {
      {ERROR_ACCESS_DENIED, EACCES},
      {ERROR_ALREADY_EXISTS, EEXIST},
      {ERROR_ARENA_TRASHED, EFAULT},
      {ERROR_BAD_COMMAND, EFAULT},
      {ERROR_BAD_ENVIRONMENT, EFAULT},
      {ERROR_BAD_FORMAT, EFAULT},
      {ERROR_BAD_NETPATH, ENOENT},
      {ERROR_BAD_NET_NAME, ENOENT},
      {ERROR_BAD_PATHNAME, ENOENT},
      {ERROR_BROKEN_PIPE, EPIPE},
      {ERROR_CANNOT_MAKE, EACCES},
      {ERROR_CHILD_NOT_COMPLETE, ECHILD},
      {ERROR_CURRENT_DIRECTORY, EACCES},
      {ERROR_DIRECT_ACCESS_HANDLE, EBADF},
      {ERROR_DIR_NOT_EMPTY, ENOTEMPTY},
      {ERROR_DISK_FULL, ENOSPC},
      {ERROR_DRIVE_LOCKED, EACCES},
      {ERROR_FAIL_I24, EACCES},
      {ERROR_FILENAME_EXCED_RANGE, ENOENT},
      {ERROR_FILE_EXISTS, EEXIST},
      {ERROR_FILE_NOT_FOUND, ENOENT},
      {ERROR_GEN_FAILURE, EFAULT},
      {ERROR_INVALID_ACCESS, EACCES},
      {ERROR_INVALID_BLOCK, EFAULT},
      {ERROR_INVALID_DATA, EFAULT},
      {ERROR_INVALID_DRIVE, ENOENT},
      {ERROR_INVALID_FUNCTION, EINVAL},
      {ERROR_INVALID_HANDLE, EBADF},
      {ERROR_INVALID_PARAMETER, EINVAL},
      {ERROR_INVALID_TARGET_HANDLE, EBADF},
      {ERROR_LOCK_FAILED, EBUSY},
      {ERROR_LOCK_VIOLATION, EBUSY},
      {ERROR_MAX_THRDS_REACHED, EAGAIN},
      {ERROR_NEGATIVE_SEEK, EINVAL},
      {ERROR_NESTING_NOT_ALLOWED, EAGAIN},
      {ERROR_NETWORK_ACCESS_DENIED, EACCES},
      {ERROR_NOT_ENOUGH_MEMORY, ENOMEM},
      {ERROR_NOT_ENOUGH_QUOTA, ENOMEM},
      {ERROR_NOT_LOCKED, EACCES},
      {ERROR_NOT_READY, EBUSY},
      {ERROR_NOT_SAME_DEVICE, EXDEV},
      {ERROR_NO_DATA, EPIPE},
      {ERROR_NO_MORE_FILES, EMFILE},
      {ERROR_NO_PROC_SLOTS, EAGAIN},
      {ERROR_PATH_NOT_FOUND, ENOENT},
      {ERROR_READ_FAULT, EFAULT},
      {ERROR_RETRY, EINTR},
      {ERROR_SEEK_ON_DEVICE, EACCES},
      {ERROR_SHARING_VIOLATION, EBUSY},
      {ERROR_TOO_MANY_OPEN_FILES, EMFILE},
      {ERROR_WAIT_NO_CHILDREN, ECHILD},
      {ERROR_WRITE_FAULT, EFAULT},
      {ERROR_WRITE_PROTECT, EACCES},
    };
    int i;

    for (i = 0; i < WT_ELEMENTS(list); ++i)
        if (windows_error == list[i].windows_error)
            return (list[i].posix_error);

    /* Untranslatable error, go generic. */
    return (WT_ERROR);
}

/*
 * __wt_formatmessage --
 *     Windows error formatting.
 */
const char *
__wt_formatmessage(WT_SESSION_IMPL *session, DWORD windows_error)
{
    /*
     * !!!
     * This function MUST handle a NULL session handle.
     *
     * Grow the session error buffer as necessary.
     */
    if (session != NULL && __wt_buf_initsize(session, &session->err, 512) == 0 &&
      FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
        windows_error, 0, /* Let system choose the correct LANGID. */
        session->err.mem, (DWORD)512, NULL) != 0)
        return (session->err.data);

    return ("Unable to format Windows error string");
}