Path: blob/master/drivers/windows/file_access_windows_pipe.cpp
9903 views
/**************************************************************************/1/* file_access_windows_pipe.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#ifdef WINDOWS_ENABLED3132#include "file_access_windows_pipe.h"3334#include "core/os/os.h"35#include "core/string/print_string.h"3637Error FileAccessWindowsPipe::open_existing(HANDLE p_rfd, HANDLE p_wfd, bool p_blocking) {38// Open pipe using handles created by CreatePipe(rfd, wfd, NULL, 4096) call in the OS.execute_with_pipe.39_close();4041path_src = String();42ERR_FAIL_COND_V_MSG(fd[0] != nullptr || fd[1] != nullptr, ERR_ALREADY_IN_USE, "Pipe is already in use.");43fd[0] = p_rfd;44fd[1] = p_wfd;4546if (!p_blocking) {47DWORD mode = PIPE_READMODE_BYTE | PIPE_NOWAIT;48SetNamedPipeHandleState(fd[0], &mode, nullptr, nullptr);49SetNamedPipeHandleState(fd[1], &mode, nullptr, nullptr);50}5152last_error = OK;53return OK;54}5556Error FileAccessWindowsPipe::open_internal(const String &p_path, int p_mode_flags) {57_close();5859path_src = p_path;60ERR_FAIL_COND_V_MSG(fd[0] != nullptr || fd[1] != nullptr, ERR_ALREADY_IN_USE, "Pipe is already in use.");6162path = String("\\\\.\\pipe\\LOCAL\\") + p_path.replace("pipe://", "").replace_char('/', '_');6364HANDLE h = CreateFileW((LPCWSTR)path.utf16().get_data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);65if (h == INVALID_HANDLE_VALUE) {66h = CreateNamedPipeW((LPCWSTR)path.utf16().get_data(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 4096, 4096, 0, nullptr);67if (h == INVALID_HANDLE_VALUE) {68last_error = ERR_FILE_CANT_OPEN;69return last_error;70}71ConnectNamedPipe(h, nullptr);72}73fd[0] = h;74fd[1] = h;7576last_error = OK;77return OK;78}7980void FileAccessWindowsPipe::_close() {81if (fd[0] == nullptr) {82return;83}84if (fd[1] != fd[0]) {85CloseHandle(fd[1]);86}87CloseHandle(fd[0]);88fd[0] = nullptr;89fd[1] = nullptr;90}9192bool FileAccessWindowsPipe::is_open() const {93return (fd[0] != nullptr || fd[1] != nullptr);94}9596String FileAccessWindowsPipe::get_path() const {97return path_src;98}99100String FileAccessWindowsPipe::get_path_absolute() const {101return path_src;102}103104uint64_t FileAccessWindowsPipe::get_length() const {105ERR_FAIL_COND_V_MSG(fd[0] == nullptr, -1, "Pipe must be opened before use.");106107DWORD buf_rem = 0;108ERR_FAIL_COND_V(!PeekNamedPipe(fd[0], nullptr, 0, nullptr, &buf_rem, nullptr), 0);109return buf_rem;110}111112uint64_t FileAccessWindowsPipe::get_buffer(uint8_t *p_dst, uint64_t p_length) const {113ERR_FAIL_COND_V_MSG(fd[0] == nullptr, -1, "Pipe must be opened before use.");114ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);115116DWORD read = 0;117if (!ReadFile(fd[0], p_dst, p_length, &read, nullptr) || read != p_length) {118last_error = ERR_FILE_CANT_READ;119} else {120last_error = OK;121}122return read;123}124125Error FileAccessWindowsPipe::get_error() const {126return last_error;127}128129bool FileAccessWindowsPipe::store_buffer(const uint8_t *p_src, uint64_t p_length) {130ERR_FAIL_COND_V_MSG(fd[1] == nullptr, false, "Pipe must be opened before use.");131ERR_FAIL_COND_V(!p_src && p_length > 0, false);132133DWORD read = -1;134bool ok = WriteFile(fd[1], p_src, p_length, &read, nullptr);135if (!ok || read != p_length) {136last_error = ERR_FILE_CANT_WRITE;137return false;138} else {139last_error = OK;140return true;141}142}143144void FileAccessWindowsPipe::close() {145_close();146}147148FileAccessWindowsPipe::~FileAccessWindowsPipe() {149_close();150}151152#endif // WINDOWS_ENABLED153154155