summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/file/winfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/file/winfile.cpp')
-rw-r--r--src/osd/modules/file/winfile.cpp176
1 files changed, 107 insertions, 69 deletions
diff --git a/src/osd/modules/file/winfile.cpp b/src/osd/modules/file/winfile.cpp
index 4c265be613d..be4fa6f70c3 100644
--- a/src/osd/modules/file/winfile.cpp
+++ b/src/osd/modules/file/winfile.cpp
@@ -6,7 +6,6 @@
//
//============================================================
-
#include "winfile.h"
// MAMEOS headers
@@ -45,7 +44,7 @@ public:
win_osd_file& operator=(win_osd_file const &) = delete;
win_osd_file& operator=(win_osd_file &&) = delete;
- win_osd_file(HANDLE handle) : m_handle(handle)
+ win_osd_file(HANDLE handle) noexcept : m_handle(handle)
{
assert(m_handle);
assert(INVALID_HANDLE_VALUE != m_handle);
@@ -57,7 +56,7 @@ public:
CloseHandle(m_handle);
}
- virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
// attempt to set the file pointer
LARGE_INTEGER largeOffset;
@@ -71,10 +70,10 @@ public:
return win_error_to_file_error(GetLastError());
actual = result;
- return error::NONE;
+ return std::error_condition();
}
- virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ virtual std::error_condition write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) noexcept override
{
// attempt to set the file pointer
LARGE_INTEGER largeOffset;
@@ -88,10 +87,10 @@ public:
return win_error_to_file_error(GetLastError());
actual = result;
- return error::NONE;
+ return std::error_condition();
}
- virtual error truncate(std::uint64_t offset) override
+ virtual std::error_condition truncate(std::uint64_t offset) noexcept override
{
// attempt to set the file pointer
LARGE_INTEGER largeOffset;
@@ -103,13 +102,13 @@ public:
if (!SetEndOfFile(m_handle))
return win_error_to_file_error(GetLastError());
else
- return error::NONE;
+ return std::error_condition();
}
- virtual error flush() override
+ virtual std::error_condition flush() noexcept override
{
// shouldn't be any userspace buffers on the file handle
- return error::NONE;
+ return std::error_condition();
}
private:
@@ -162,11 +161,11 @@ DWORD create_path_recursive(TCHAR *path)
// osd_open
//============================================================
-osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags, ptr &file, std::uint64_t &filesize)
+std::error_condition osd_file::open(std::string const &orig_path, uint32_t openflags, ptr &file, std::uint64_t &filesize) noexcept
{
std::string path;
try { osd_subst_env(path, orig_path); }
- catch (...) { return error::OUT_OF_MEMORY; }
+ catch (...) { return std::errc::not_enough_memory; }
if (win_check_socket_path(path))
return win_open_socket(path, openflags, file, filesize);
@@ -174,10 +173,11 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
return win_open_ptty(path, openflags, file, filesize);
// convert path to TCHAR
- osd::text::tstring t_path = osd::text::to_tstring(path);
+ osd::text::tstring t_path;
+ try { t_path = osd::text::to_tstring(path); }
+ catch (...) { return std::errc::not_enough_memory; }
- // convert the path into something Windows compatible (the actual interesting part appears
- // to have been commented out???)
+ // convert the path into something Windows compatible (the actual interesting part appears to have been commented out???)
for (auto iter = t_path.begin(); iter != t_path.end(); iter++)
*iter = /* ('/' == *iter) ? '\\' : */ *iter;
@@ -187,7 +187,8 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
{
disposition = (!is_path_to_physical_drive(path.c_str()) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING;
access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE;
- if (is_path_to_physical_drive(path.c_str())) access |= GENERIC_READ;
+ if (is_path_to_physical_drive(path.c_str()))
+ access |= GENERIC_READ;
sharemode = FILE_SHARE_READ;
}
else if (openflags & OPEN_FLAG_READ)
@@ -198,7 +199,7 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
}
else
{
- return error::INVALID_ACCESS;
+ return std::errc::invalid_argument;
}
// attempt to open the file
@@ -262,17 +263,15 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
}
}
- try
- {
- file = std::make_unique<win_osd_file>(h);
- filesize = (std::uint64_t(upper) << 32) | lower;
- return error::NONE;
- }
- catch (...)
+ osd_file::ptr result(new (std::nothrow) win_osd_file(h));
+ if (!result)
{
CloseHandle(h);
- return error::OUT_OF_MEMORY;
+ return std::errc::not_enough_memory;
}
+ file = std::move(result);
+ filesize = (std::uint64_t(upper) << 32) | lower;
+ return std::error_condition();
}
@@ -281,9 +280,9 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags,
// osd_openpty
//============================================================
-osd_file::error osd_file::openpty(ptr &file, std::string &name)
+std::error_condition osd_file::openpty(ptr &file, std::string &name) noexcept
{
- return error::FAILURE;
+ return std::errc::not_supported; // TODO: revisit this error code
}
@@ -292,11 +291,13 @@ osd_file::error osd_file::openpty(ptr &file, std::string &name)
// osd_rmfile
//============================================================
-osd_file::error osd_file::remove(std::string const &filename)
+std::error_condition osd_file::remove(std::string const &filename) noexcept
{
- osd::text::tstring tempstr = osd::text::to_tstring(filename);
+ osd::text::tstring tempstr;
+ try { tempstr = osd::text::to_tstring(filename); }
+ catch (...) { return std::errc::not_enough_memory; }
- error filerr = error::NONE;
+ std::error_condition filerr;
if (!DeleteFile(tempstr.c_str()))
filerr = win_error_to_file_error(GetLastError());
@@ -309,7 +310,7 @@ osd_file::error osd_file::remove(std::string const &filename)
// osd_get_physical_drive_geometry
//============================================================
-bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps)
+bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors, uint32_t *bps) noexcept
{
DISK_GEOMETRY dg;
DWORD bytesRead;
@@ -321,10 +322,17 @@ bool osd_get_physical_drive_geometry(const char *filename, uint32_t *cylinders,
return false;
// do a create file on the drive
- auto t_filename = osd::text::to_tstring(filename);
- file = CreateFile(t_filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, nullptr);
- if (file == INVALID_HANDLE_VALUE)
+ try
+ {
+ auto t_filename = osd::text::to_tstring(filename);
+ file = CreateFile(t_filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, nullptr);
+ if (file == INVALID_HANDLE_VALUE)
+ return false;
+ }
+ catch (...)
+ {
return false;
+ }
// device I/O control should return the geometry
result = DeviceIoControl(file, IOCTL_DISK_GET_DRIVE_GEOMETRY, nullptr, 0, &dg, sizeof(dg), &bytesRead, nullptr);
@@ -399,22 +407,29 @@ std::unique_ptr<osd::directory::entry> osd_stat(const std::string &path)
// osd_get_full_path
//============================================================
-osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
+std::error_condition osd_get_full_path(std::string &dst, std::string const &path) noexcept
{
- // get the length of the full path
- std::wstring const w_path(osd::text::to_wstring(path));
- DWORD const length(GetFullPathNameW(w_path.c_str(), 0, nullptr, nullptr));
- if (!length)
- return win_error_to_file_error(GetLastError());
+ try
+ {
+ // get the length of the full path
+ std::wstring const w_path(osd::text::to_wstring(path));
+ DWORD const length(GetFullPathNameW(w_path.c_str(), 0, nullptr, nullptr));
+ if (!length)
+ return win_error_to_file_error(GetLastError());
- // allocate a buffer and get the canonical path
- std::unique_ptr<wchar_t []> buffer(std::make_unique<wchar_t []>(length));
- if (!GetFullPathNameW(w_path.c_str(), length, buffer.get(), nullptr))
- return win_error_to_file_error(GetLastError());
+ // allocate a buffer and get the canonical path
+ std::unique_ptr<wchar_t []> buffer(std::make_unique<wchar_t []>(length));
+ if (!GetFullPathNameW(w_path.c_str(), length, buffer.get(), nullptr))
+ return win_error_to_file_error(GetLastError());
- // convert the result back to UTF-8
- osd::text::from_wstring(dst, buffer.get());
- return osd_file::error::NONE;
+ // convert the result back to UTF-8
+ osd::text::from_wstring(dst, buffer.get());
+ return std::error_condition();
+ }
+ catch (...)
+ {
+ return std::errc::not_enough_memory; // the string conversions can throw bad_alloc
+ }
}
@@ -423,7 +438,7 @@ osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
// osd_is_absolute_path
//============================================================
-bool osd_is_absolute_path(std::string const &path)
+bool osd_is_absolute_path(std::string const &path) noexcept
{
return !PathIsRelativeW(osd::text::to_wstring(path).c_str());
}
@@ -493,7 +508,7 @@ std::vector<std::string> osd_get_volume_names()
// osd_is_valid_filename_char
//============================================================
-bool osd_is_valid_filename_char(char32_t uchar)
+bool osd_is_valid_filename_char(char32_t uchar) noexcept
{
return osd_is_valid_filepath_char(uchar)
&& uchar != '/'
@@ -507,7 +522,7 @@ bool osd_is_valid_filename_char(char32_t uchar)
// osd_is_valid_filepath_char
//============================================================
-bool osd_is_valid_filepath_char(char32_t uchar)
+bool osd_is_valid_filepath_char(char32_t uchar) noexcept
{
return uchar >= 0x20
&& uchar != '<'
@@ -526,39 +541,62 @@ bool osd_is_valid_filepath_char(char32_t uchar)
// win_error_to_file_error
//============================================================
-osd_file::error win_error_to_file_error(DWORD error)
+std::error_condition win_error_to_file_error(DWORD error) noexcept
{
- osd_file::error filerr;
-
- // convert a Windows error to a osd_file::error
+ // TODO: work out if there's a better way to do this
switch (error)
{
case ERROR_SUCCESS:
- filerr = osd_file::error::NONE;
- break;
+ return std::error_condition();
+
+ case ERROR_INVALID_HANDLE:
+ return std::errc::bad_file_descriptor;
case ERROR_OUTOFMEMORY:
- filerr = osd_file::error::OUT_OF_MEMORY;
- break;
+ return std::errc::not_enough_memory;
+
+ case ERROR_NOT_SUPPORTED:
+ return std::errc::not_supported;
case ERROR_FILE_NOT_FOUND:
- case ERROR_FILENAME_EXCED_RANGE:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_NAME:
- filerr = osd_file::error::NOT_FOUND;
- break;
+ return std::errc::no_such_file_or_directory;
- case ERROR_ACCESS_DENIED:
- filerr = osd_file::error::ACCESS_DENIED;
- break;
+ case ERROR_FILENAME_EXCED_RANGE:
+ return std::errc::filename_too_long;
+ case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
- filerr = osd_file::error::ALREADY_OPEN;
- break;
+ return std::errc::permission_denied;
+
+ case ERROR_ALREADY_EXISTS:
+ return std::errc::file_exists;
+
+ case ERROR_TOO_MANY_OPEN_FILES:
+ return std::errc::too_many_files_open;
+
+ case ERROR_WRITE_FAULT:
+ case ERROR_READ_FAULT:
+ return std::errc::io_error;
+
+ case ERROR_HANDLE_DISK_FULL:
+ case ERROR_DISK_FULL:
+ return std::errc::no_space_on_device;
+
+ case ERROR_PATH_BUSY:
+ case ERROR_BUSY:
+ return std::errc::device_or_resource_busy;
+
+ case ERROR_FILE_TOO_LARGE:
+ return std::errc::file_too_large;
+
+ case ERROR_INVALID_ACCESS:
+ case ERROR_NEGATIVE_SEEK:
+ case ERROR_BAD_ARGUMENTS:
+ return std::errc::invalid_argument;
default:
- filerr = osd_file::error::FAILURE;
- break;
+ return std::error_condition(error, std::system_category());
}
- return filerr;
}