summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/os_win/os_winerr.c
blob: cef80d8ad21bcac5f48c504ce96bc98a1d452f56 (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
/*-
 * 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");
}