1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/*
* 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;
}
}
|