diff options
author | 2016-03-13 13:54:57 +1100 | |
---|---|---|
committer | 2016-03-14 18:55:00 +1100 | |
commit | 42fbb9c3967fcda37f2d9ae17d5796a79cf027b9 (patch) | |
tree | a43047ee00431e5e22bfc5f8f612ff775586e415 /src/osd/modules/file/winptty.cpp | |
parent | 5fc27747031b6ed6f6c0582502098ebfb960be67 (diff) |
Make osd_file a polymorphic class that's held with smart pointers
Make avi_file a class that's held with smart pointers, encapsulate various AVI I/O structures
Make zip_file and _7z_file classes rather than having free functions everywhere
Hide zip/7z class implementation behind an interface, no longer need to call close() to send back to the cache
Don't dump as much crap in global namespace
Add solaris PTY implementation
Improve variable expansion for SDL OSD - supports ~/$FOO/${BAR} syntax
Rearrange stuff so the same things are in file module for all OSDs
Move file stuff into its own module
7z/zip open and destruct are still not thread-safe due to lack of interlocks around cache access
Directory functions still need to be moved to file module
SDL OSD may not initialise WinSock on Windows
Diffstat (limited to 'src/osd/modules/file/winptty.cpp')
-rw-r--r-- | src/osd/modules/file/winptty.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/osd/modules/file/winptty.cpp b/src/osd/modules/file/winptty.cpp new file mode 100644 index 00000000000..44c42d40588 --- /dev/null +++ b/src/osd/modules/file/winptty.cpp @@ -0,0 +1,111 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles, Vas Crabb + +#define WIN32_LEAN_AND_MEAN + +#include "winfile.h" + +#include "strconv.h" +#include "winutil.h" + +#include <cassert> + +#include <windows.h> +#include <stdlib.h> + + +namespace { +char const *const winfile_ptty_identifier = "\\\\.\\pipe\\"; + + +class win_osd_ptty : public osd_file +{ +public: + win_osd_ptty(win_osd_ptty const &) = delete; + win_osd_ptty(win_osd_ptty &&) = delete; + win_osd_ptty& operator=(win_osd_ptty const &) = delete; + win_osd_ptty& operator=(win_osd_ptty &&) = delete; + + win_osd_ptty(HANDLE handle) : m_handle(handle) + { + assert(m_handle); + assert(INVALID_HANDLE_VALUE != m_handle); + } + + ~win_osd_ptty() + { + FlushFileBuffers(m_handle); + DisconnectNamedPipe(m_handle); + CloseHandle(m_handle); + } + + virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override + { + DWORD bytes_read; + if (!ReadFile(m_handle, buffer, count, &bytes_read, NULL)) + return win_error_to_file_error(GetLastError()); + + actual = bytes_read; + return error::NONE; + } + + virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) + { + DWORD bytes_written; + if (!WriteFile(m_handle, buffer, count, &bytes_written, NULL)) + return win_error_to_file_error(GetLastError()); + + actual = bytes_written; + return error::NONE; + } + + virtual error truncate(std::uint64_t offset) override + { + // doesn't make sense for a PTTY + return error::INVALID_ACCESS; + } + + virtual error flush() override + { + // don't want to wait for client to read all data as implied by FlushFileBuffers + return error::NONE; + } + +private: + HANDLE m_handle; +}; + +} // anonymous namespace + + +bool win_check_ptty_path(std::string const &path) +{ + if (strncmp(path.c_str(), winfile_ptty_identifier, strlen(winfile_ptty_identifier)) == 0) return true; + return false; +} + + +osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize) +{ + TCHAR *t_name = tstring_from_utf8(path.c_str()); + if (!t_name) + return osd_file::error::OUT_OF_MEMORY; + + HANDLE pipe = CreateNamedPipe(t_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 32, 32, 0, NULL); + osd_free(t_name); + + if (INVALID_HANDLE_VALUE == pipe) + return osd_file::error::ACCESS_DENIED; + + try + { + file = std::make_unique<win_osd_ptty>(pipe); + filesize = 0; + return osd_file::error::NONE; + } + catch (...) + { + CloseHandle(pipe); + return osd_file::error::OUT_OF_MEMORY; + } +} |