Index: mojo/edk/embedder/named_platform_channel_pair_win.cc |
diff --git a/mojo/edk/embedder/named_platform_channel_pair_win.cc b/mojo/edk/embedder/named_platform_channel_pair_win.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..73e89587b58f58ec051ebb04fd3067594252db00 |
--- /dev/null |
+++ b/mojo/edk/embedder/named_platform_channel_pair_win.cc |
@@ -0,0 +1,113 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "mojo/edk/embedder/named_platform_channel_pair.h" |
+ |
+#include <windows.h> |
+ |
+#include <string> |
+#include <utility> |
+ |
+#include "base/command_line.h" |
+#include "base/logging.h" |
+#include "base/rand_util.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/stringprintf.h" |
+#include "base/win/windows_version.h" |
+#include "mojo/edk/embedder/platform_handle.h" |
+ |
+namespace mojo { |
+namespace edk { |
+ |
+namespace { |
+ |
+const char kMojoNamedPlatformChannelPipeSwitch[] = |
+ "mojo-named-platform-channel-pipe"; |
ncarter (slow)
2016/05/11 00:14:23
It seems unusual to have switches defined outside
Anand Mistry (off Chromium)
2016/05/11 04:15:20
I'm following the pattern in PlatformChannelPair.
|
+ |
+std::wstring GeneratePipeName() { |
+ return base::StringPrintf(L"\\\\.\\pipe\\mojo.%u.%u.%I64u", |
+ GetCurrentProcessId(), GetCurrentThreadId(), |
+ base::RandUint64()); |
+ |
+} |
+ |
+} // namespace |
+ |
+NamedPlatformChannelPair::NamedPlatformChannelPair() { |
+ pipe_name_ = GeneratePipeName(); |
+ |
+ const DWORD kOpenMode = |
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE; |
+ const DWORD kPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE; |
forshaw
2016/05/11 00:01:40
I'd recommend specifying PIPE_REJECT_REMOTE_CLIENT
Anand Mistry (off Chromium)
2016/05/11 04:15:20
Done.
|
+ PlatformHandle handle( |
+ CreateNamedPipeW(pipe_name_.c_str(), kOpenMode, kPipeMode, |
+ 1, // Max instances. |
+ 4096, // Out buffer size. |
+ 4096, // In buffer size. |
+ 5000, // Timeout in milliseconds. |
+ nullptr)); // Default security descriptor. |
forshaw
2016/05/11 00:01:40
Is there any advantage to another user on the syst
Anand Mistry (off Chromium)
2016/05/11 04:15:20
I've tried to add an acl here to restrict access,
forshaw
2016/05/11 12:03:15
Well it's probably not needed, but a simple exampl
Anand Mistry (off Chromium)
2016/05/12 01:17:07
Thanks. Added and it appears to work on my windows
|
+ handle.needs_connection = true; |
+ server_handle_.reset(handle); |
+ PCHECK(server_handle_.is_valid()); |
+} |
+ |
+NamedPlatformChannelPair::~NamedPlatformChannelPair() {} |
+ |
+ScopedPlatformHandle NamedPlatformChannelPair::PassServerHandle() { |
+ return std::move(server_handle_); |
+} |
+ |
+// static |
+ScopedPlatformHandle |
+NamedPlatformChannelPair::PassClientHandleFromParentProcess( |
+ const base::CommandLine& command_line) { |
+ std::wstring client_handle_string = |
+ command_line.GetSwitchValueNative(kMojoNamedPlatformChannelPipeSwitch); |
+ |
+ if (client_handle_string.empty()) |
+ return ScopedPlatformHandle(); |
+ |
+ // Note: This may block. |
+ BOOL ok = WaitNamedPipeW(client_handle_string.c_str(), |
+ NMPWAIT_USE_DEFAULT_WAIT); |
+ if (!ok) |
+ return ScopedPlatformHandle(); |
+ |
+ // In order to support passing the pipe name on the command line, the pipe |
+ // handle is lazily created from the pipe name when requested. |
+ const DWORD kDesiredAccess = GENERIC_READ | GENERIC_WRITE; |
+ // The SECURITY_ANONYMOUS flag means that the server side cannot impersonate |
+ // the client. |
+ const DWORD kFlags = |
+ SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS | FILE_FLAG_OVERLAPPED; |
+ ScopedPlatformHandle handle( |
+ PlatformHandle(CreateFileW(client_handle_string.c_str(), kDesiredAccess, |
+ 0, // No sharing. |
+ nullptr, OPEN_EXISTING, kFlags, |
+ nullptr))); // No template file. |
+ PCHECK(handle.is_valid()); |
+ return handle; |
+} |
+ |
+void NamedPlatformChannelPair::PrepareToPassClientHandleToChildProcess( |
+ base::CommandLine* command_line) const { |
+ DCHECK(command_line); |
+ |
+ // Log a warning if the command line already has the switch, but "clobber" it |
+ // anyway, since it's reasonably likely that all the switches were just copied |
+ // from the parent. |
+ LOG_IF(WARNING, |
+ command_line->HasSwitch(kMojoNamedPlatformChannelPipeSwitch)) |
+ << "Child command line already has switch --" |
+ << kMojoNamedPlatformChannelPipeSwitch << "=" |
+ << command_line->GetSwitchValueNative( |
+ kMojoNamedPlatformChannelPipeSwitch); |
+ // (Any existing switch won't actually be removed from the command line, but |
+ // the last one appended takes precedence.) |
+ command_line->AppendSwitchNative( |
+ kMojoNamedPlatformChannelPipeSwitch, pipe_name_); |
+} |
+ |
+} // namespace edk |
+} // namespace mojo |