nextcloud-desktop/shell_integration/windows/NCUtil/CommunicationSocket.cpp
Andy Scherzinger 5fe94ea149 docs(reuse): Migrate to SPDX header
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2025-05-07 09:28:53 +02:00

137 lines
3.1 KiB
C++

/*
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2014 ownCloud GmbH
* SPDX-FileCopyrightText: 2000-2013 Liferay, Inc. All rights reserved
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "CommunicationSocket.h"
#include "StringUtil.h"
#include "WinShellExtConstants.h"
#include <iostream>
#include <vector>
#include <array>
#include <fstream>
#define DEFAULT_BUFLEN 4096
using namespace std;
namespace {
std::wstring getUserName() {
DWORD len = DEFAULT_BUFLEN;
TCHAR buf[DEFAULT_BUFLEN];
if (GetUserName(buf, &len)) {
return std::wstring(&buf[0], len);
} else {
return std::wstring();
}
}
}
std::wstring CommunicationSocket::DefaultPipePath()
{
auto pipename = std::wstring(LR"(\\.\pipe\)");
pipename += std::wstring(UTIL_PIPE_APP_NAME);
pipename += L"-";
pipename += getUserName();
return pipename;
}
CommunicationSocket::CommunicationSocket()
: _pipe(INVALID_HANDLE_VALUE)
{
}
CommunicationSocket::~CommunicationSocket()
{
Close();
}
bool CommunicationSocket::Close()
{
if (_pipe == INVALID_HANDLE_VALUE) {
return false;
}
CloseHandle(_pipe);
_pipe = INVALID_HANDLE_VALUE;
return true;
}
bool CommunicationSocket::Connect(const std::wstring &pipename)
{
_pipe = CreateFile(pipename.data(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
if (_pipe == INVALID_HANDLE_VALUE) {
return false;
}
return true;
}
bool CommunicationSocket::SendMsg(const wchar_t* message) const
{
auto utf8_msg = StringUtil::toUtf8(message);
DWORD numBytesWritten = 0;
auto result = WriteFile( _pipe, utf8_msg.c_str(), DWORD(utf8_msg.size()), &numBytesWritten, nullptr);
if (result) {
return true;
} else {
const_cast<CommunicationSocket*>(this)->Close();
return false;
}
}
bool CommunicationSocket::ReadLine(wstring* response)
{
if (!response) {
return false;
}
response->clear();
if (_pipe == INVALID_HANDLE_VALUE) {
return false;
}
while (true) {
int lbPos = 0;
auto it = std::find(_buffer.begin() + lbPos, _buffer.end(), '\n');
if (it != _buffer.end()) {
*response = StringUtil::toUtf16(_buffer.data(), DWORD(it - _buffer.begin()));
_buffer.erase(_buffer.begin(), it + 1);
return true;
}
std::array<char, 128> resp_utf8 = {};
DWORD numBytesRead = 0;
DWORD totalBytesAvailable = 0;
if (!PeekNamedPipe(_pipe, nullptr, 0, nullptr, &totalBytesAvailable, nullptr)) {
Close();
return false;
}
if (totalBytesAvailable == 0) {
return false;
}
if (!ReadFile(_pipe, resp_utf8.data(), DWORD(resp_utf8.size()), &numBytesRead, nullptr)) {
Close();
return false;
}
if (numBytesRead <= 0) {
return false;
}
_buffer.insert(_buffer.end(), resp_utf8.begin(), resp_utf8.begin()+numBytesRead);
continue;
}
}