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