This source file includes following definitions.
- CreateConnectedIpcChannel
- CreateIpcChannel
#include "remoting/host/ipc_util.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_handle.h"
#include "base/win/win_util.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
#include "remoting/host/win/security_descriptor.h"
using base::win::ScopedHandle;
namespace remoting {
const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome.";
bool CreateConnectedIpcChannel(
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
IPC::Listener* listener,
IPC::PlatformFileForTransit* client_out,
scoped_ptr<IPC::ChannelProxy>* server_out) {
std::wstring user_sid;
if (!base::win::GetUserSidString(&user_sid)) {
LOG(ERROR) << "Failed to query the current user SID.";
return false;
}
std::string security_descriptor = base::StringPrintf(
"O:%1$sG:%1$sD:(A;;GA;;;%1$s)", base::WideToUTF8(user_sid).c_str());
std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID();
ScopedHandle pipe;
if (!CreateIpcChannel(channel_name, security_descriptor, &pipe)) {
return false;
}
scoped_ptr<IPC::ChannelProxy> server(new IPC::ChannelProxy(
IPC::ChannelHandle(pipe),
IPC::Channel::MODE_SERVER,
listener,
io_task_runner));
std::string pipe_name(kChromePipeNamePrefix);
pipe_name.append(channel_name);
SECURITY_ATTRIBUTES security_attributes = {0};
security_attributes.nLength = sizeof(security_attributes);
security_attributes.lpSecurityDescriptor = NULL;
security_attributes.bInheritHandle = TRUE;
ScopedHandle client;
client.Set(CreateFile(base::UTF8ToUTF16(pipe_name).c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
&security_attributes,
OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION |
FILE_FLAG_OVERLAPPED,
NULL));
if (!client.IsValid()) {
LOG_GETLASTERROR(ERROR) << "Failed to connect to '" << pipe_name << "'";
return false;
}
*client_out = client.Take();
*server_out = server.Pass();
return true;
}
bool CreateIpcChannel(
const std::string& channel_name,
const std::string& pipe_security_descriptor,
base::win::ScopedHandle* pipe_out) {
ScopedSd sd = ConvertSddlToSd(pipe_security_descriptor);
if (!sd) {
LOG_GETLASTERROR(ERROR) <<
"Failed to create a security descriptor for the Chromoting IPC channel";
return false;
}
SECURITY_ATTRIBUTES security_attributes = {0};
security_attributes.nLength = sizeof(security_attributes);
security_attributes.lpSecurityDescriptor = sd.get();
security_attributes.bInheritHandle = FALSE;
std::string pipe_name(kChromePipeNamePrefix);
pipe_name.append(channel_name);
base::win::ScopedHandle pipe;
pipe.Set(CreateNamedPipe(
base::UTF8ToUTF16(pipe_name).c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1,
IPC::Channel::kReadBufferSize,
IPC::Channel::kReadBufferSize,
5000,
&security_attributes));
if (!pipe.IsValid()) {
LOG_GETLASTERROR(ERROR) <<
"Failed to create the server end of the Chromoting IPC channel";
return false;
}
*pipe_out = pipe.Pass();
return true;
}
}