Skip to content

Commit ff198b0

Browse files
authored
Merge branch 'master' into to_array_view
2 parents 6befa97 + 7b7b64f commit ff198b0

File tree

3 files changed

+327
-8
lines changed

3 files changed

+327
-8
lines changed

include/wil/filesystem.h

Lines changed: 215 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <combaseapi.h> // Needed for CoTaskMemFree() used in output of some helpers.
2020
#include <winbase.h> // LocalAlloc
2121
#include <PathCch.h>
22+
#include "wistd_type_traits.h"
2223
#include "result.h"
2324
#include "win32_helpers.h"
2425
#include "resource.h"
@@ -197,6 +198,7 @@ namespace wil
197198
};
198199
DEFINE_ENUM_FLAG_OPERATORS(RemoveDirectoryOptions);
199200

201+
/// @cond
200202
namespace details
201203
{
202204
// Reparse points should not be traversed in most recursive walks of the file system,
@@ -208,6 +210,7 @@ namespace wil
208210
(IsReparseTagDirectory(info.ReparseTag) || (info.ReparseTag == IO_REPARSE_TAG_WCI))));
209211
}
210212
}
213+
/// @endcond
211214

212215
// Retrieve a handle to a directory only if it is safe to recurse into.
213216
inline wil::unique_hfile TryCreateFileCanRecurseIntoDirectory(PCWSTR path, PWIN32_FIND_DATAW fileFindData, DWORD access = GENERIC_READ | /*DELETE*/ 0x00010000L, DWORD share = FILE_SHARE_READ)
@@ -716,10 +719,10 @@ namespace wil
716719
{
717720
for (auto const& info : create_next_entry_offset_iterator(reinterpret_cast<FILE_NOTIFY_INFORMATION *>(readerState->m_readBuffer)))
718721
{
719-
wchar_t realtiveFileName[MAX_PATH];
720-
StringCchCopyNW(realtiveFileName, ARRAYSIZE(realtiveFileName), info.FileName, info.FileNameLength / sizeof(info.FileName[0]));
722+
wchar_t relativeFileName[MAX_PATH];
723+
StringCchCopyNW(relativeFileName, ARRAYSIZE(relativeFileName), info.FileName, info.FileNameLength / sizeof(info.FileName[0]));
721724

722-
readerState->m_callback(static_cast<FolderChangeEvent>(info.Action), realtiveFileName);
725+
readerState->m_callback(static_cast<FolderChangeEvent>(info.Action), relativeFileName);
723726
}
724727
}
725728
else if (result == ERROR_NOTIFY_ENUM_DIR)
@@ -1047,8 +1050,217 @@ namespace wil
10471050
THROW_IF_FAILED(GetFileInfoNoThrow<infoClass>(fileHandle, result));
10481051
return result;
10491052
}
1053+
1054+
// Helpers to make the CreateFileW API easier to use.
1055+
// https://learn.microsoft.com/windows/win32/api/fileapi/nf-fileapi-createfilew
1056+
1057+
struct file_and_error_result
1058+
{
1059+
file_and_error_result(HANDLE file_handle, DWORD error) : file(file_handle), last_error(error)
1060+
{
1061+
}
1062+
1063+
wil::unique_hfile file;
1064+
DWORD last_error{};
1065+
};
1066+
1067+
/** Non-throwing open existing using OPEN_EXISTING.
1068+
~~~
1069+
auto handle = wil::try_open_file(filePath.c_str());
1070+
~~~
1071+
*/
1072+
inline file_and_error_result try_open_file(PCWSTR path, DWORD dwDesiredAccess = FILE_READ_ACCESS,
1073+
DWORD dwShareMode = FILE_SHARE_READ, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1074+
bool inheritHandle = false) noexcept
1075+
{
1076+
SECURITY_ATTRIBUTES secAttributes{ sizeof(secAttributes) };
1077+
secAttributes.bInheritHandle = inheritHandle;
1078+
auto handle = CreateFileW(path, dwDesiredAccess, dwShareMode, &secAttributes, OPEN_EXISTING, dwFlagsAndAttributes, nullptr);
1079+
return { handle, ::GetLastError() };
1080+
}
1081+
1082+
/** open existing using OPEN_EXISTING, throws on error.
1083+
~~~
1084+
auto handle = wil::open_file(filePath.c_str());
1085+
~~~
1086+
*/
1087+
inline wil::unique_hfile open_file(PCWSTR path, DWORD dwDesiredAccess = FILE_READ_ACCESS,
1088+
DWORD dwShareMode = FILE_SHARE_READ, DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1089+
bool inheritHandle = false) noexcept
1090+
{
1091+
auto result = try_open_file(path, dwDesiredAccess, dwShareMode, inheritHandle, dwFlagsAndAttributes);
1092+
THROW_WIN32_IF(result.last_error, !result.file.is_valid());
1093+
return std::move(result.file);
1094+
}
1095+
1096+
/// @cond
1097+
namespace details
1098+
{
1099+
template<DWORD dwCreateDisposition>
1100+
file_and_error_result create_file(PCWSTR path, DWORD dwDesiredAccess,
1101+
DWORD dwShareMode,
1102+
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
1103+
DWORD dwFlagsAndAttributes,
1104+
HANDLE hTemplateFile) noexcept
1105+
{
1106+
auto handle = CreateFileW(
1107+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreateDisposition, dwFlagsAndAttributes, hTemplateFile);
1108+
return { handle, ::GetLastError() };
1109+
}
1110+
}
1111+
/// @endcond
1112+
1113+
1114+
/** create using CREATE_NEW, returns handle and error code.
1115+
~~~
1116+
auto [handle, error = wil::try_create_new_file(filePath.c_str());
1117+
~~~
1118+
*/
1119+
inline file_and_error_result try_create_new_file(PCWSTR path,
1120+
DWORD dwDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS,
1121+
DWORD dwShareMode = FILE_SHARE_READ,
1122+
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
1123+
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1124+
HANDLE hTemplateFile = nullptr) noexcept
1125+
{
1126+
return details::create_file<CREATE_NEW>(
1127+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
1128+
}
1129+
1130+
/** create using OPEN_ALWAYS, returns handle and error code.
1131+
~~~
1132+
auto [handle, error = wil::try_open_or_create_file(filePath.c_str());
1133+
~~~
1134+
*/
1135+
inline file_and_error_result try_open_or_create_file(PCWSTR path,
1136+
DWORD dwDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS,
1137+
DWORD dwShareMode = FILE_SHARE_READ,
1138+
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
1139+
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1140+
HANDLE hTemplateFile = nullptr) noexcept
1141+
{
1142+
return details::create_file<OPEN_ALWAYS>(
1143+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
1144+
}
1145+
1146+
/** create using CREATE_ALWAYS, returns handle and error code.
1147+
~~~
1148+
auto [handle, error = wil::try_open_or_truncate_existing_file(filePath.c_str());
1149+
~~~
1150+
*/
1151+
inline file_and_error_result try_open_or_truncate_existing_file(PCWSTR path,
1152+
DWORD dwDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS,
1153+
DWORD dwShareMode = FILE_SHARE_READ,
1154+
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
1155+
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1156+
HANDLE hTemplateFile = nullptr) noexcept
1157+
{
1158+
return details::create_file<CREATE_ALWAYS>(
1159+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
1160+
}
1161+
1162+
/** create using TRUNCATE_EXISTING, returns handle and error code.
1163+
~~~
1164+
auto [handle, error = wil::try_truncate_existing_file(filePath.c_str());
1165+
~~~
1166+
*/
1167+
inline file_and_error_result try_truncate_existing_file(PCWSTR path,
1168+
DWORD dwDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS | GENERIC_WRITE,
1169+
DWORD dwShareMode = FILE_SHARE_READ,
1170+
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
1171+
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1172+
HANDLE hTemplateFile = nullptr) noexcept
1173+
{
1174+
return details::create_file<TRUNCATE_EXISTING>(
1175+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
1176+
}
1177+
1178+
/** create using CREATE_NEW, returns the file handle, throws on error.
1179+
~~~
1180+
auto handle = wil::create_new_file(filePath.c_str());
1181+
~~~
1182+
*/
1183+
inline wil::unique_hfile create_new_file(PCWSTR path,
1184+
DWORD dwDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS,
1185+
DWORD dwShareMode = FILE_SHARE_READ,
1186+
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
1187+
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1188+
HANDLE hTemplateFile = nullptr) noexcept
1189+
{
1190+
auto result = try_create_new_file(
1191+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
1192+
THROW_WIN32_IF(result.last_error, !result.file.is_valid());
1193+
return std::move(result.file);
1194+
}
1195+
1196+
/** create using OPEN_ALWAYS, returns the file handle, throws on error.
1197+
~~~
1198+
auto handle = wil::open_or_create_file(filePath.c_str());
1199+
~~~
1200+
*/
1201+
inline wil::unique_hfile open_or_create_file(PCWSTR path,
1202+
DWORD dwDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS,
1203+
DWORD dwShareMode = FILE_SHARE_READ,
1204+
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
1205+
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1206+
HANDLE hTemplateFile = nullptr) noexcept
1207+
{
1208+
auto result = try_open_or_create_file(
1209+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
1210+
THROW_WIN32_IF(result.last_error, !result.file.is_valid());
1211+
return std::move(result.file);
1212+
}
1213+
1214+
/** create using CREATE_ALWAYS, returns the file handle, throws on error.
1215+
~~~
1216+
auto handle = wil::open_or_truncate_existing_file(filePath.c_str());
1217+
~~~
1218+
*/
1219+
inline wil::unique_hfile open_or_truncate_existing_file(PCWSTR path,
1220+
DWORD dwDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS,
1221+
DWORD dwShareMode = FILE_SHARE_READ,
1222+
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
1223+
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1224+
HANDLE hTemplateFile = nullptr) noexcept
1225+
{
1226+
auto result = try_open_or_truncate_existing_file(
1227+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
1228+
THROW_WIN32_IF(result.last_error, !result.file.is_valid());
1229+
return std::move(result.file);
1230+
}
1231+
1232+
/** create using TRUNCATE_EXISTING, returns the file handle, throws on error.
1233+
~~~
1234+
auto handle = wil::truncate_existing_file(filePath.c_str());
1235+
~~~
1236+
*/
1237+
inline wil::unique_hfile truncate_existing_file(PCWSTR path,
1238+
DWORD dwDesiredAccess = FILE_READ_ACCESS | FILE_WRITE_ACCESS,
1239+
DWORD dwShareMode = FILE_SHARE_READ,
1240+
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
1241+
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
1242+
HANDLE hTemplateFile = nullptr) noexcept
1243+
{
1244+
auto result = try_truncate_existing_file(
1245+
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
1246+
THROW_WIN32_IF(result.last_error, !result.file.is_valid());
1247+
return std::move(result.file);
1248+
}
1249+
10501250
#endif // _CPPUNWIND
10511251
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN7)
10521252
}
10531253

1254+
#ifndef WIL_NO_FILE_TYPE_OPERATORS
1255+
inline bool operator==(const FILE_ID_128& left, const FILE_ID_128& right)
1256+
{
1257+
return memcmp(&left, &right, sizeof(left)) == 0;
1258+
}
1259+
1260+
inline bool operator!=(const FILE_ID_128& left, const FILE_ID_128& right)
1261+
{
1262+
return !operator==(left, right);
1263+
}
1264+
#endif
1265+
10541266
#endif // __WIL_FILESYSTEM_INCLUDED

include/wil/resource.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5597,7 +5597,7 @@ namespace wil
55975597
/// @cond
55985598
namespace details
55995599
{
5600-
inline void __stdcall CloseWlanHandle(_Frees_ptr_ HANDLE hClientHandle)
5600+
inline void __stdcall CloseWlanHandle(_In_ HANDLE hClientHandle)
56015601
{
56025602
::WlanCloseHandle(hClientHandle, nullptr);
56035603
}

0 commit comments

Comments
 (0)