* Copyright (c) 2015-2023 Google, Inc. All rights reserved.
* **********************************************************/
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Google, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#include <string>
#include <windows.h>
#include "named_pipe.h"
namespace dynamorio {
namespace drmemtrace {
#define MAX_NAME_LEN 256
#define ALLOC_UNIT (64 * 1025)
#define OUT_BUFSZ (16 * ALLOC_UNIT)
#define IN_BUFSZ OUT_BUFSZ
named_pipe_t::named_pipe_t()
: fd_(INVALID_HANDLE_VALUE)
{
}
named_pipe_t::named_pipe_t(const char *name)
: fd_(INVALID_HANDLE_VALUE)
{
set_name(name);
}
named_pipe_t::~named_pipe_t()
{
if (fd_ != INVALID_HANDLE_VALUE)
close();
}
bool
named_pipe_t::set_name(const char *name)
{
if (fd_ == INVALID_HANDLE_VALUE) {
pipe_name_ = std::string("\\\\.\\pipe\\") + name;
if (pipe_name_.size() > MAX_NAME_LEN)
pipe_name_.resize(MAX_NAME_LEN);
return true;
}
return false;
}
std::string
named_pipe_t::get_name() const
{
return pipe_name_;
}
bool
named_pipe_t::create()
{
fd_ = CreateNamedPipeA(pipe_name_.c_str(), PIPE_ACCESS_INBOUND,
PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
OUT_BUFSZ, IN_BUFSZ, 0, NULL);
return (fd_ != INVALID_HANDLE_VALUE);
}
bool
named_pipe_t::destroy()
{
return close();
}
bool
named_pipe_t::open_for_read()
{
if (fd_ == INVALID_HANDLE_VALUE) {
fd_ = CreateFileA(pipe_name_.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
return (fd_ != INVALID_HANDLE_VALUE);
} else {
BOOL res = ConnectNamedPipe(fd_, NULL);
return res == TRUE;
}
}
bool
named_pipe_t::open_for_write()
{
if (fd_ == INVALID_HANDLE_VALUE) {
fd_ = CreateFileA(pipe_name_.c_str(), GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
return (fd_ != INVALID_HANDLE_VALUE);
} else {
BOOL res = ConnectNamedPipe(fd_, NULL);
return res == TRUE;
}
}
bool
named_pipe_t::close()
{
BOOL res = CloseHandle(fd_);
return res == TRUE;
}
bool
named_pipe_t::maximize_buffer()
{
return true;
}
ssize_t
named_pipe_t::read(void *buf OUT, size_t sz)
{
DWORD actual;
BOOL res = ReadFile(fd_, buf, (DWORD)sz, &actual, NULL);
if (!res)
return -1;
else
return actual;
}
ssize_t
named_pipe_t::write(const void *buf IN, size_t sz)
{
DWORD actual;
BOOL res = WriteFile(fd_, buf, (DWORD)sz, &actual, NULL);
if (!res)
return -1;
else
return actual;
}
const ssize_t
named_pipe_t::get_atomic_write_size() const
{
return 512;
}
}
}