Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: create singleton pipename from user & executable #34161

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -282,22 +282,31 @@ index 7d3a441bdb64268ed5fbfa7bf589fb35a2fd1b75..b23c16fde275fdba559abb1f30e42f65
return PROCESS_NOTIFIED;
}
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..6225f09da02ce231e9a2a6a8d874818eae1cc79e 100644
index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..d9a47fc419b7d42e31498cc2d803560984f00810 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -21,6 +21,7 @@
@@ -13,14 +13,17 @@
#include "base/command_line.h"
#include "base/debug/activity_tracker.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/process.h"
#include "base/process/process_info.h"
+#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "base/timer/timer.h"
#include "base/trace_event/base_tracing.h"
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
@@ -45,6 +46,14 @@
@@ -45,6 +48,13 @@
namespace {

const char kLockfile[] = "lockfile";
+const LPCWSTR kPipeName = L"\\\\.\\pipe\\electronAckPipe";
+const DWORD kPipeTimeout = 10000;
+const DWORD kMaxMessageLength = 32 * 1024;
+
Expand All @@ -308,7 +317,7 @@ index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..6225f09da02ce231e9a2a6a8d874818e

// A helper class that acquires the given |mutex| while the AutoLockMutex is in
// scope.
@@ -80,10 +89,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
@@ -80,10 +90,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {

bool ParseCommandLine(const COPYDATASTRUCT* cds,
base::CommandLine* parsed_command_line,
Expand All @@ -323,7 +332,7 @@ index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..6225f09da02ce231e9a2a6a8d874818e
static const int min_message_size = 7;
if (cds->cbData < min_message_size * sizeof(wchar_t) ||
cds->cbData % sizeof(wchar_t) != 0) {
@@ -133,11 +144,82 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
@@ -133,11 +145,82 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
const std::wstring cmd_line =
msg.substr(second_null + 1, third_null - second_null);
*parsed_command_line = base::CommandLine::FromString(cmd_line);
Expand Down Expand Up @@ -406,7 +415,7 @@ index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..6225f09da02ce231e9a2a6a8d874818e
bool ProcessLaunchNotification(
const ProcessSingleton::NotificationCallback& notification_callback,
UINT message,
@@ -151,16 +233,35 @@ bool ProcessLaunchNotification(
@@ -151,16 +234,35 @@ bool ProcessLaunchNotification(

// Handle the WM_COPYDATA message from another process.
const COPYDATASTRUCT* cds = reinterpret_cast<COPYDATASTRUCT*>(lparam);
Expand Down Expand Up @@ -446,7 +455,7 @@ index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..6225f09da02ce231e9a2a6a8d874818e
return true;
}

@@ -254,9 +355,13 @@ bool ProcessSingleton::EscapeVirtualization(
@@ -254,9 +356,13 @@ bool ProcessSingleton::EscapeVirtualization(
ProcessSingleton::ProcessSingleton(
const std::string& program_name,
const base::FilePath& user_data_dir,
Expand All @@ -461,16 +470,26 @@ index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..6225f09da02ce231e9a2a6a8d874818e
program_name_(program_name),
is_app_sandboxed_(is_app_sandboxed),
is_virtualized_(false),
@@ -271,6 +376,37 @@ ProcessSingleton::~ProcessSingleton() {
@@ -271,6 +377,47 @@ ProcessSingleton::~ProcessSingleton() {
::CloseHandle(lock_file_);
}

+void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback) {
+void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback,
+ const std::string program_name,
+ base::FilePath& user_data_dir) {
+ // We are reading the ack from the first instance.
+ // First, wait for the pipe.
+ ::WaitNamedPipe(kPipeName, NMPWAIT_USE_DEFAULT_WAIT);
+ HWND remote_window = chrome::FindRunningChromeWindow(user_data_dir);
+ DWORD process_id;
+ DWORD thread_id = GetWindowThreadProcessId(remote_window, &process_id);
+ std::string identifier = base::NumberToString(process_id) +
+ base::NumberToString(thread_id);
+ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier +
+ program_name);
+ const LPCWSTR w_pipe_name = pipe_name.c_str();
+ ::WaitNamedPipe(w_pipe_name, NMPWAIT_USE_DEFAULT_WAIT);
+
+ HANDLE read_ack_pipe = ::CreateFile(kPipeName,
+ HANDLE read_ack_pipe = ::CreateFile(w_pipe_name,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
Expand Down Expand Up @@ -499,23 +518,31 @@ index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..6225f09da02ce231e9a2a6a8d874818e
// Code roughly based on Mozilla.
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
TRACE_EVENT0("startup", "ProcessSingleton::NotifyOtherProcess");
@@ -283,8 +419,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
@@ -283,8 +430,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
return PROCESS_NONE;
}

- switch (chrome::AttemptToNotifyRunningChrome(remote_window_)) {
+ switch (chrome::AttemptToNotifyRunningChrome(remote_window_, additional_data_)) {
case chrome::NOTIFY_SUCCESS:
+ ReadAck(notification_ack_callback_);
+ ReadAck(notification_ack_callback_, program_name_, user_data_dir_);
return PROCESS_NOTIFIED;
case chrome::NOTIFY_FAILED:
remote_window_ = NULL;
@@ -422,6 +559,18 @@ bool ProcessSingleton::Create() {
@@ -422,6 +570,26 @@ bool ProcessSingleton::Create() {
<< "Lock file can not be created! Error code: " << error;

if (lock_file_ != INVALID_HANDLE_VALUE) {
+ // We are the first instance. Create a pipe to send out ack data.
+ ack_pipe_ = ::CreateNamedPipe(kPipeName,
+ // Create a per-process pipename using a combination of the
+ // username, process id, thread id, and program name. Pipe names max
+ // at 256 characters, can include any character other than a backslash
+ std::string identifier = base::NumberToString(::GetCurrentProcessId()) +
+ base::NumberToString(::GetCurrentThreadId());
+ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier +
+ program_name_);
+ const LPCWSTR w_pipe_name = pipe_name.c_str();
+ ack_pipe_ = ::CreateNamedPipe(w_pipe_name,
+ PIPE_ACCESS_OUTBOUND,
+ PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS,
+ PIPE_UNLIMITED_INSTANCES,
Expand All @@ -529,7 +556,7 @@ index 0ea5eb3e3cf055d981ab73486115bac53287f2d7..6225f09da02ce231e9a2a6a8d874818e
// Set the window's title to the path of our user data directory so
// other Chrome instances can decide if they should forward to us.
TRACE_EVENT0("startup", "ProcessSingleton::Create:CreateWindow");
@@ -449,6 +598,7 @@ bool ProcessSingleton::Create() {
@@ -449,6 +617,7 @@ bool ProcessSingleton::Create() {
}

void ProcessSingleton::Cleanup() {
Expand Down