1*04e0dc4aSTimo Kreuzer //
2*04e0dc4aSTimo Kreuzer // waccess.cpp
3*04e0dc4aSTimo Kreuzer //
4*04e0dc4aSTimo Kreuzer // Copyright (c) Microsoft Corporation. All rights reserved.
5*04e0dc4aSTimo Kreuzer //
6*04e0dc4aSTimo Kreuzer // The _waccess() and _waccess_s() functions, which test file accessibility.
7*04e0dc4aSTimo Kreuzer //
8*04e0dc4aSTimo Kreuzer #include <corecrt_internal.h>
9*04e0dc4aSTimo Kreuzer #include <io.h>
10*04e0dc4aSTimo Kreuzer
11*04e0dc4aSTimo Kreuzer
12*04e0dc4aSTimo Kreuzer
13*04e0dc4aSTimo Kreuzer // Tests whether the specified file can be accessed with the specified mode. The
14*04e0dc4aSTimo Kreuzer // access_mode must be one of: 0 (exist only), 2 (write), 4 (read), 6 (read and
15*04e0dc4aSTimo Kreuzer // write). Returns zero if the file can be accessed with the given mode; returns
16*04e0dc4aSTimo Kreuzer // an error code otherwise or if an error occurs.
_waccess_s(wchar_t const * const path,int const access_mode)17*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _waccess_s(wchar_t const* const path, int const access_mode)
18*04e0dc4aSTimo Kreuzer {
19*04e0dc4aSTimo Kreuzer _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(path != nullptr, EINVAL);
20*04e0dc4aSTimo Kreuzer _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE((access_mode & (~6)) == 0, EINVAL);
21*04e0dc4aSTimo Kreuzer
22*04e0dc4aSTimo Kreuzer WIN32_FILE_ATTRIBUTE_DATA attributes;
23*04e0dc4aSTimo Kreuzer if (!GetFileAttributesExW(path, GetFileExInfoStandard, &attributes))
24*04e0dc4aSTimo Kreuzer {
25*04e0dc4aSTimo Kreuzer __acrt_errno_map_os_error(GetLastError());
26*04e0dc4aSTimo Kreuzer return errno;
27*04e0dc4aSTimo Kreuzer }
28*04e0dc4aSTimo Kreuzer
29*04e0dc4aSTimo Kreuzer // All directories have both read and write access:
30*04e0dc4aSTimo Kreuzer if (attributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
31*04e0dc4aSTimo Kreuzer return 0;
32*04e0dc4aSTimo Kreuzer
33*04e0dc4aSTimo Kreuzer // If we require write access, make sure the read only flag is not set:
34*04e0dc4aSTimo Kreuzer bool const file_is_read_only = (attributes.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0;
35*04e0dc4aSTimo Kreuzer bool const mode_requires_write = (access_mode & 2) != 0;
36*04e0dc4aSTimo Kreuzer
37*04e0dc4aSTimo Kreuzer if (file_is_read_only && mode_requires_write)
38*04e0dc4aSTimo Kreuzer {
39*04e0dc4aSTimo Kreuzer _doserrno = ERROR_ACCESS_DENIED;
40*04e0dc4aSTimo Kreuzer errno = EACCES;
41*04e0dc4aSTimo Kreuzer return errno;
42*04e0dc4aSTimo Kreuzer }
43*04e0dc4aSTimo Kreuzer
44*04e0dc4aSTimo Kreuzer // Otherwise, the file is accessible:
45*04e0dc4aSTimo Kreuzer return 0;
46*04e0dc4aSTimo Kreuzer
47*04e0dc4aSTimo Kreuzer }
48*04e0dc4aSTimo Kreuzer
49*04e0dc4aSTimo Kreuzer
50*04e0dc4aSTimo Kreuzer
51*04e0dc4aSTimo Kreuzer // The same as _waccess_s, but transforms all errors into a -1 return value.
_waccess(wchar_t const * const path,int const access_mode)52*04e0dc4aSTimo Kreuzer extern "C" int __cdecl _waccess(wchar_t const* const path, int const access_mode)
53*04e0dc4aSTimo Kreuzer {
54*04e0dc4aSTimo Kreuzer return _waccess_s(path, access_mode) == 0 ? 0 : -1;
55*04e0dc4aSTimo Kreuzer }
56