Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 38 additions & 41 deletions stl/inc/experimental/filesystem
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ You can define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING to suppress

#pragma warning(disable : 4365) // conversion from 'type_1' to 'type_2', signed/unsigned mismatch (/Wall)

#ifndef _FS_DLL
#define _FS_DLL extern "C" _CRTIMP2_PURE
#endif // !defined(_FS_DLL)

#define _MAX_FILESYS_NAME 260 // longest Windows or Posix filename + 1

#define _FS_BEGIN \
Expand All @@ -50,7 +46,6 @@ You can define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING to suppress
#define _FSPFX _STD experimental::filesystem::v1::

_FS_BEGIN
using _Pchar = wchar_t; // UTF16
#define _FS_ISSEP(x) ((x) == L'/' || (x) == L'\\')
#define _FS_PREF L'\\'

Expand Down Expand Up @@ -161,34 +156,36 @@ struct space_info { // space information for a file
};

// wide filenames
_FS_DLL void* __CLRCALL_PURE_OR_CDECL _Open_dir(
extern "C" _CRTIMP2_PURE void* __CLRCALL_PURE_OR_CDECL _Open_dir(
wchar_t (&)[_MAX_FILESYS_NAME], const wchar_t*, int&, file_type&) noexcept;
_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Read_dir(wchar_t (&)[_MAX_FILESYS_NAME], void*, file_type&) noexcept;
_FS_DLL void __CLRCALL_PURE_OR_CDECL _Close_dir(void*) noexcept;
_FS_DLL bool __CLRCALL_PURE_OR_CDECL _Current_get(wchar_t (&)[_MAX_FILESYS_NAME]) noexcept;
_FS_DLL bool __CLRCALL_PURE_OR_CDECL _Current_set(const wchar_t*) noexcept;
_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Symlink_get(wchar_t (&)[_MAX_FILESYS_NAME], const wchar_t*) noexcept;
_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Temp_get(wchar_t (&)[_MAX_FILESYS_NAME]) noexcept;

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Make_dir(const wchar_t*, const wchar_t*) noexcept;
_FS_DLL bool __CLRCALL_PURE_OR_CDECL _Remove_dir(const wchar_t*) noexcept;

_FS_DLL file_type __CLRCALL_PURE_OR_CDECL _Stat(const wchar_t*, perms*) noexcept;
_FS_DLL file_type __CLRCALL_PURE_OR_CDECL _Lstat(const wchar_t*, perms*) noexcept;
_FS_DLL uintmax_t __CLRCALL_PURE_OR_CDECL _File_size(const wchar_t*) noexcept;
_FS_DLL uintmax_t __CLRCALL_PURE_OR_CDECL _Hard_links(const wchar_t*) noexcept;
_FS_DLL int64_t __CLRCALL_PURE_OR_CDECL _Last_write_time(const wchar_t*) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _Set_last_write_time(const wchar_t*, int64_t) noexcept;
_FS_DLL space_info __CLRCALL_PURE_OR_CDECL _Statvfs(const wchar_t*) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _Equivalent(const wchar_t*, const wchar_t*) noexcept;

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Link(const wchar_t*, const wchar_t*) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _Symlink(const wchar_t*, const wchar_t*) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _Rename(const wchar_t*, const wchar_t*) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _Resize(const wchar_t*, uintmax_t) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _Unlink(const wchar_t*) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _Copy_file(const wchar_t*, const wchar_t*) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _Chmod(const wchar_t*, perms) noexcept;
extern "C" _CRTIMP2_PURE wchar_t* __CLRCALL_PURE_OR_CDECL _Read_dir(
wchar_t (&)[_MAX_FILESYS_NAME], void*, file_type&) noexcept;
extern "C" _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Close_dir(void*) noexcept;
extern "C" _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL _Current_get(wchar_t (&)[_MAX_FILESYS_NAME]) noexcept;
extern "C" _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL _Current_set(const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE wchar_t* __CLRCALL_PURE_OR_CDECL _Symlink_get(
wchar_t (&)[_MAX_FILESYS_NAME], const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE wchar_t* __CLRCALL_PURE_OR_CDECL _Temp_get(wchar_t (&)[_MAX_FILESYS_NAME]) noexcept;

extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Make_dir(const wchar_t*, const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL _Remove_dir(const wchar_t*) noexcept;

extern "C" _CRTIMP2_PURE file_type __CLRCALL_PURE_OR_CDECL _Stat(const wchar_t*, perms*) noexcept;
extern "C" _CRTIMP2_PURE file_type __CLRCALL_PURE_OR_CDECL _Lstat(const wchar_t*, perms*) noexcept;
extern "C" _CRTIMP2_PURE uintmax_t __CLRCALL_PURE_OR_CDECL _File_size(const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE uintmax_t __CLRCALL_PURE_OR_CDECL _Hard_links(const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int64_t __CLRCALL_PURE_OR_CDECL _Last_write_time(const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Set_last_write_time(const wchar_t*, int64_t) noexcept;
extern "C" _CRTIMP2_PURE space_info __CLRCALL_PURE_OR_CDECL _Statvfs(const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Equivalent(const wchar_t*, const wchar_t*) noexcept;

extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Link(const wchar_t*, const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Symlink(const wchar_t*, const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Rename(const wchar_t*, const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Resize(const wchar_t*, uintmax_t) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Unlink(const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Copy_file(const wchar_t*, const wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Chmod(const wchar_t*, perms) noexcept;

template <class _Inchar, class _Outchar, class _Outtraits = char_traits<_Outchar>,
class _Outalloc = allocator<_Outchar>>
Expand Down Expand Up @@ -267,8 +264,8 @@ struct _Path_cvt<char32_t, char, _Outtraits,
}
};

_FS_DLL int __CLRCALL_PURE_OR_CDECL _To_byte(const wchar_t*, char*) noexcept;
_FS_DLL int __CLRCALL_PURE_OR_CDECL _To_wide(const char*, wchar_t*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _To_byte(const wchar_t*, char*) noexcept;
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _To_wide(const char*, wchar_t*) noexcept;

template <class _Outtraits, class _Outalloc>
struct _Path_cvt<char, wchar_t, _Outtraits,
Expand Down Expand Up @@ -723,7 +720,7 @@ private:

class path { // stores a pathname
public:
using value_type = _Pchar;
using value_type = wchar_t;
using string_type = basic_string<value_type>;

static constexpr value_type preferred_separator = _FS_PREF;
Expand Down Expand Up @@ -1264,7 +1261,7 @@ template <class _InIt, enable_if_t<_Is_iterator_v<_InIt>, int> = 0>
_NODISCARD path u8path(_InIt _First, _InIt _Last) { // make path from [_First, _Last) UTF8, given iterators
string _Str(_First, _Last);
path::string_type _Str_out;
return path{_Path_cvt<_Char8_t, _Pchar>::_Cvt(_Str_out, _Str.c_str(), _Str.size())};
return path{_Path_cvt<_Char8_t, wchar_t>::_Cvt(_Str_out, _Str.c_str(), _Str.size())};
}

template <class _InIt, enable_if_t<_Is_iterator_v<_InIt>, int> = 0>
Expand All @@ -1275,13 +1272,13 @@ _NODISCARD path u8path(_InIt _First) { // make path from NTBS UTF8, given iterat
}

path::string_type _Str_out;
return path{_Path_cvt<_Char8_t, _Pchar>::_Cvt(_Str_out, _Str.c_str(), _Str.size())};
return path{_Path_cvt<_Char8_t, wchar_t>::_Cvt(_Str_out, _Str.c_str(), _Str.size())};
}

template <class _Traits, class _Alloc>
_NODISCARD path u8path(const basic_string<char, _Traits, _Alloc>& _Str) { // make path from arbitrary char string UTF8
path::string_type _Str_out;
return path{_Path_cvt<_Char8_t, _Pchar>::_Cvt(_Str_out, _Str.c_str(), _Str.size())};
return path{_Path_cvt<_Char8_t, wchar_t>::_Cvt(_Str_out, _Str.c_str(), _Str.size())};
}

class _NODISCARD filesystem_error : public system_error { // base of all filesystem-error exceptions
Expand Down Expand Up @@ -2150,7 +2147,7 @@ _NODISCARD inline path current_path() {

_NODISCARD inline path current_path(error_code& _Code) {
_Code.clear();
_Pchar _Dest[_MAX_FILESYS_NAME];
wchar_t _Dest[_MAX_FILESYS_NAME];
if (!_Current_get(_Dest)) { // report error
_Code = make_error_code(errc::operation_not_permitted);
return {};
Expand Down Expand Up @@ -2456,7 +2453,7 @@ _NODISCARD inline path read_symlink(const path& _Path,
_Code = make_error_code(errc::no_such_file_or_directory);
return {};
}
_Pchar _Dest[_MAX_FILESYS_NAME];
wchar_t _Dest[_MAX_FILESYS_NAME];
return path{_Symlink_get(_Dest, _Path.c_str())};
}

Expand Down Expand Up @@ -2675,7 +2672,7 @@ _NODISCARD inline path temp_directory_path() {
}

_NODISCARD inline path temp_directory_path(error_code& _Code) {
_Pchar _Dest[_MAX_FILESYS_NAME];
wchar_t _Dest[_MAX_FILESYS_NAME];
_Temp_get(_Dest);
path _Ans(_Dest);

Expand Down
59 changes: 33 additions & 26 deletions stl/src/filesys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static file_type _Map_mode(int _Mode) { // map Windows file attributes to file_s
}
}

_FS_DLL void __CLRCALL_PURE_OR_CDECL _Close_dir(void* _Handle) noexcept { // close a directory
extern "C" _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Close_dir(void* _Handle) noexcept { // close a directory
FindClose(_Handle);
}

Expand All @@ -56,7 +56,7 @@ static HANDLE _FilesysOpenFile(const wchar_t* _Fname, DWORD _Desired_access, DWO
&_Create_file_parameters);
}

_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Read_dir(
extern "C" _CRTIMP2_PURE wchar_t* __CLRCALL_PURE_OR_CDECL _Read_dir(
wchar_t (&_Dest)[_MAX_FILESYS_NAME], void* _Handle, file_type& _Ftype) noexcept { // read a directory entry
WIN32_FIND_DATAW _Dentry;

Expand Down Expand Up @@ -86,17 +86,17 @@ static unsigned int _Filesys_code_page() { // determine appropriate code page
#endif // ^^^ !defined(_ONECORE) ^^^
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _To_wide(const char* _Bsrc, wchar_t* _Wdest) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _To_wide(const char* _Bsrc, wchar_t* _Wdest) noexcept {
// return nonzero on success
return MultiByteToWideChar(_Filesys_code_page(), 0, _Bsrc, -1, _Wdest, _MAX_FILESYS_NAME);
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _To_byte(const wchar_t* _Wsrc, char* _Bdest) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _To_byte(const wchar_t* _Wsrc, char* _Bdest) noexcept {
// return nonzero on success
return WideCharToMultiByte(_Filesys_code_page(), 0, _Wsrc, -1, _Bdest, _MAX_FILESYS_NAME, nullptr, nullptr);
}

_FS_DLL void* __CLRCALL_PURE_OR_CDECL _Open_dir(
extern "C" _CRTIMP2_PURE void* __CLRCALL_PURE_OR_CDECL _Open_dir(
wchar_t (&_Dest)[_MAX_FILESYS_NAME], const wchar_t* _Dirname, int& _Errno, file_type& _Ftype) noexcept {
// open a directory for reading
WIN32_FIND_DATAW _Dentry;
Expand Down Expand Up @@ -133,7 +133,7 @@ _FS_DLL void* __CLRCALL_PURE_OR_CDECL _Open_dir(
return _Handle;
}

_FS_DLL bool __CLRCALL_PURE_OR_CDECL _Current_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME]) noexcept {
extern "C" _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL _Current_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME]) noexcept {
// get current working directory
_Strcpy(_Dest, L"");
#ifdef _CRT_APP
Expand All @@ -143,7 +143,7 @@ _FS_DLL bool __CLRCALL_PURE_OR_CDECL _Current_get(wchar_t (&_Dest)[_MAX_FILESYS_
#endif // ^^^ !defined(_CRT_APP) ^^^
}

_FS_DLL bool __CLRCALL_PURE_OR_CDECL _Current_set(const wchar_t* _Dirname) noexcept {
extern "C" _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL _Current_set(const wchar_t* _Dirname) noexcept {
// set current working directory
#ifdef _CRT_APP
(void) _Dirname;
Expand All @@ -153,19 +153,20 @@ _FS_DLL bool __CLRCALL_PURE_OR_CDECL _Current_set(const wchar_t* _Dirname) noexc
#endif // ^^^ !defined(_CRT_APP) ^^^
}

_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Symlink_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME], const wchar_t*) noexcept {
extern "C" _CRTIMP2_PURE wchar_t* __CLRCALL_PURE_OR_CDECL _Symlink_get(
wchar_t (&_Dest)[_MAX_FILESYS_NAME], const wchar_t*) noexcept {
// get symlink -- DUMMY
_Dest[0] = L'\0';
return _Dest;
}

_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Temp_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME]) noexcept {
extern "C" _CRTIMP2_PURE wchar_t* __CLRCALL_PURE_OR_CDECL _Temp_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME]) noexcept {
// get temp directory
wchar_t _Dentry[MAX_PATH];
return _Strcpy(_Dest, __crtGetTempPath2W(MAX_PATH, _Dentry) != 0 ? _Dentry : L".");
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Make_dir(const wchar_t* _Fname, const wchar_t*) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Make_dir(const wchar_t* _Fname, const wchar_t*) noexcept {
// make a new directory (ignore attributes)
if (CreateDirectoryW(_Fname, nullptr)) {
return 1;
Expand All @@ -176,11 +177,13 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Make_dir(const wchar_t* _Fname, const wchar
}
}

_FS_DLL bool __CLRCALL_PURE_OR_CDECL _Remove_dir(const wchar_t* _Fname) noexcept { // remove a directory
extern "C" _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL _Remove_dir(
const wchar_t* _Fname) noexcept { // remove a directory
return _wrmdir(_Fname) != -1;
}

_FS_DLL file_type __CLRCALL_PURE_OR_CDECL _Stat(const wchar_t* _Fname, perms* _Pmode) noexcept { // get file status
extern "C" _CRTIMP2_PURE file_type __CLRCALL_PURE_OR_CDECL _Stat(
const wchar_t* _Fname, perms* _Pmode) noexcept { // get file status
WIN32_FILE_ATTRIBUTE_DATA _Data;

if (GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data)) {
Expand Down Expand Up @@ -210,12 +213,12 @@ _FS_DLL file_type __CLRCALL_PURE_OR_CDECL _Stat(const wchar_t* _Fname, perms* _P
}
}

_FS_DLL file_type __CLRCALL_PURE_OR_CDECL _Lstat(const wchar_t* _Fname, perms* _Pmode) noexcept {
extern "C" _CRTIMP2_PURE file_type __CLRCALL_PURE_OR_CDECL _Lstat(const wchar_t* _Fname, perms* _Pmode) noexcept {
// get symlink file status
return _Stat(_Fname, _Pmode); // symlink not supported
}

_FS_DLL uintmax_t __CLRCALL_PURE_OR_CDECL _Hard_links(const wchar_t* _Fname) noexcept {
extern "C" _CRTIMP2_PURE uintmax_t __CLRCALL_PURE_OR_CDECL _Hard_links(const wchar_t* _Fname) noexcept {
// get hard link count
HANDLE _Handle = _FilesysOpenFile(_Fname, FILE_READ_ATTRIBUTES, FILE_FLAG_BACKUP_SEMANTICS);

Expand All @@ -231,7 +234,7 @@ _FS_DLL uintmax_t __CLRCALL_PURE_OR_CDECL _Hard_links(const wchar_t* _Fname) noe
return _Ok ? _Info.NumberOfLinks : static_cast<uintmax_t>(-1);
}

_FS_DLL uintmax_t __CLRCALL_PURE_OR_CDECL _File_size(const wchar_t* _Fname) noexcept { // get file size
extern "C" _CRTIMP2_PURE uintmax_t __CLRCALL_PURE_OR_CDECL _File_size(const wchar_t* _Fname) noexcept { // get file size
WIN32_FILE_ATTRIBUTE_DATA _Data;

if (GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data)) {
Expand All @@ -252,7 +255,8 @@ _FS_DLL uintmax_t __CLRCALL_PURE_OR_CDECL _File_size(const wchar_t* _Fname) noex
constexpr uint64_t _Win_ticks_per_second = 10000000ULL;
constexpr uint64_t _Win_ticks_from_epoch = ((1970 - 1601) * 365 + 3 * 24 + 17) * 86400ULL * _Win_ticks_per_second;

_FS_DLL int64_t __CLRCALL_PURE_OR_CDECL _Last_write_time(const wchar_t* _Fname) noexcept { // get last write time
extern "C" _CRTIMP2_PURE int64_t __CLRCALL_PURE_OR_CDECL _Last_write_time(
const wchar_t* _Fname) noexcept { // get last write time
WIN32_FILE_ATTRIBUTE_DATA _Data;

if (!GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data)) {
Expand All @@ -265,7 +269,8 @@ _FS_DLL int64_t __CLRCALL_PURE_OR_CDECL _Last_write_time(const wchar_t* _Fname)
return static_cast<int64_t>(_Wtime - _Win_ticks_from_epoch);
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Set_last_write_time(const wchar_t* _Fname, int64_t _When) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Set_last_write_time(
const wchar_t* _Fname, int64_t _When) noexcept {
// set last write time
HANDLE _Handle = _FilesysOpenFile(_Fname, FILE_WRITE_ATTRIBUTES, FILE_FLAG_BACKUP_SEMANTICS);

Expand All @@ -283,7 +288,7 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Set_last_write_time(const wchar_t* _Fname,
return _Result;
}

_FS_DLL space_info __CLRCALL_PURE_OR_CDECL _Statvfs(const wchar_t* _Fname) noexcept {
extern "C" _CRTIMP2_PURE space_info __CLRCALL_PURE_OR_CDECL _Statvfs(const wchar_t* _Fname) noexcept {
// get space information for volume
space_info _Ans = {static_cast<uintmax_t>(-1), static_cast<uintmax_t>(-1), static_cast<uintmax_t>(-1)};
wstring _Devname = _Fname;
Expand All @@ -304,7 +309,7 @@ _FS_DLL space_info __CLRCALL_PURE_OR_CDECL _Statvfs(const wchar_t* _Fname) noexc
return _Ans;
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Equivalent(
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Equivalent(
const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept { // test for equivalent file names
// See GH-3571: File IDs are only guaranteed to be unique and stable while handles remain open
_FILE_ID_INFO _Info1 = {0};
Expand Down Expand Up @@ -336,7 +341,7 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Equivalent(
}
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Link(const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Link(const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept {
// link _Fname2 to _Fname1
#ifdef _CRT_APP
(void) _Fname1;
Expand All @@ -347,7 +352,7 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Link(const wchar_t* _Fname1, const wchar_t*
#endif // ^^^ !defined(_CRT_APP) ^^^
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Symlink(const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Symlink(const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept {
// link _Fname2 to _Fname1
#ifdef _CRT_APP
(void) _Fname1;
Expand All @@ -358,12 +363,13 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Symlink(const wchar_t* _Fname1, const wchar
#endif // ^^^ !defined(_CRT_APP) ^^^
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Rename(const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Rename(const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept {
// rename _Fname1 as _Fname2
return _wrename(_Fname1, _Fname2) == 0 ? 0 : GetLastError();
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Resize(const wchar_t* _Fname, uintmax_t _Newsize) noexcept { // change file size
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Resize(
const wchar_t* _Fname, uintmax_t _Newsize) noexcept { // change file size

HANDLE _Handle = _FilesysOpenFile(_Fname, FILE_GENERIC_WRITE, 0);

Expand All @@ -380,11 +386,12 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Resize(const wchar_t* _Fname, uintmax_t _Ne
return _Ok ? 0 : GetLastError();
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Unlink(const wchar_t* _Fname) noexcept { // unlink _Fname
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Unlink(const wchar_t* _Fname) noexcept { // unlink _Fname
return _wremove(_Fname) == 0 ? 0 : GetLastError();
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Copy_file(const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Copy_file(
const wchar_t* _Fname1, const wchar_t* _Fname2) noexcept {
// copy _Fname1 to _Fname2
COPYFILE2_EXTENDED_PARAMETERS _Params = {0};
_Params.dwSize = sizeof(COPYFILE2_EXTENDED_PARAMETERS);
Expand All @@ -399,7 +406,7 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Copy_file(const wchar_t* _Fname1, const wch
return _Copy_result & 0x0000FFFFU;
}

_FS_DLL int __CLRCALL_PURE_OR_CDECL _Chmod(const wchar_t* _Fname, perms _Newmode) noexcept {
extern "C" _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Chmod(const wchar_t* _Fname, perms _Newmode) noexcept {
// change file mode to _Newmode
WIN32_FILE_ATTRIBUTE_DATA _Data;

Expand Down