From 4b2fa49f26a16312dfbd17c5bc84249aeb55e10f Mon Sep 17 00:00:00 2001 From: VerteDinde Date: Sun, 8 May 2022 13:25:03 -0700 Subject: [PATCH 1/6] fix: create singleton pipename from user & executable --- ...ransfer_to_requestsingleinstancelock.patch | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch index a539bdab51ef7..870cd37090781 100644 --- a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch +++ b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch @@ -282,7 +282,7 @@ index be2c417c07a4206fac4a9a6c03e516fd0493c942..78f74b0b21242553b6af98628dc48190 return PROCESS_NOTIFIED; } diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc -index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d05018b627 100644 +index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803a5ea7df9 100644 --- a/chrome/browser/process_singleton_win.cc +++ b/chrome/browser/process_singleton_win.cc @@ -21,6 +21,7 @@ @@ -293,11 +293,10 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0 #include "base/trace_event/base_tracing.h" #include "base/win/registry.h" #include "base/win/scoped_handle.h" -@@ -45,6 +46,14 @@ +@@ -45,6 +46,13 @@ namespace { const char kLockfile[] = "lockfile"; -+const LPCWSTR kPipeName = L"\\\\.\\pipe\\electronAckPipe"; +const DWORD kPipeTimeout = 10000; +const DWORD kMaxMessageLength = 32 * 1024; + @@ -308,7 +307,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0 // 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 +88,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) { bool ParseCommandLine(const COPYDATASTRUCT* cds, base::CommandLine* parsed_command_line, @@ -323,7 +322,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0 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 +143,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); @@ -406,7 +405,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0 bool ProcessLaunchNotification( const ProcessSingleton::NotificationCallback& notification_callback, UINT message, -@@ -151,16 +233,35 @@ bool ProcessLaunchNotification( +@@ -151,16 +232,35 @@ bool ProcessLaunchNotification( // Handle the WM_COPYDATA message from another process. const COPYDATASTRUCT* cds = reinterpret_cast(lparam); @@ -446,7 +445,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0 return true; } -@@ -261,9 +362,13 @@ bool ProcessSingleton::EscapeVirtualization( +@@ -261,9 +361,13 @@ bool ProcessSingleton::EscapeVirtualization( ProcessSingleton::ProcessSingleton( const std::string& program_name, const base::FilePath& user_data_dir, @@ -461,13 +460,30 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0 program_name_(program_name), is_app_sandboxed_(is_app_sandboxed), is_virtualized_(false), -@@ -278,6 +383,37 @@ ProcessSingleton::~ProcessSingleton() { +@@ -278,6 +382,54 @@ ProcessSingleton::~ProcessSingleton() { ::CloseHandle(lock_file_); } -+void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback) { ++std::wstring GetPipeName(std::string& program_name_) { ++ // Create a per-process pipename using a combination of the ++ // username and executable name. Pipe names are maxed to 256 ++ // characters and can include any character other than a backslash ++ wchar_t user_name[256]; ++ DWORD size = std::size(user_name); ++ if (::GetUserName(user_name, &size) == 0 || size < 1) { ++ NOTREACHED(); ++ } ++ ++ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + program_name_.substr(0, 5)); ++ pipe_name.append(user_name, 10); ++ return pipe_name; ++} ++ ++void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback, std::string& program_name_) { + // We are reading the ack from the first instance. + // First, wait for the pipe. ++ std::wstring pipe_name = GetPipeName(program_name_); ++ const LPCWSTR kPipeName = pipe_name.c_str(); + ::WaitNamedPipe(kPipeName, NMPWAIT_USE_DEFAULT_WAIT); + + HANDLE read_ack_pipe = ::CreateFile(kPipeName, @@ -499,22 +515,24 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0 // Code roughly based on Mozilla. ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { TRACE_EVENT0("startup", "ProcessSingleton::NotifyOtherProcess"); -@@ -290,8 +426,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { +@@ -290,8 +442,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_); return PROCESS_NOTIFIED; case chrome::NOTIFY_FAILED: remote_window_ = NULL; -@@ -429,6 +566,18 @@ bool ProcessSingleton::Create() { +@@ -429,6 +582,20 @@ 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. ++ std::wstring pipe_name = GetPipeName(program_name_); ++ const LPCWSTR kPipeName = pipe_name.c_str(); + ack_pipe_ = ::CreateNamedPipe(kPipeName, + PIPE_ACCESS_OUTBOUND, + PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS, @@ -529,7 +547,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0 // 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"); -@@ -456,6 +605,7 @@ bool ProcessSingleton::Create() { +@@ -456,6 +623,7 @@ bool ProcessSingleton::Create() { } void ProcessSingleton::Cleanup() { From 7ca6f088213b1e28d1c9da79072a2cf69d251765 Mon Sep 17 00:00:00 2001 From: VerteDinde Date: Mon, 9 May 2022 12:25:36 -0700 Subject: [PATCH 2/6] fix: use process id & main thread id for pipe name --- ...ransfer_to_requestsingleinstancelock.patch | 95 ++++++++++++------- 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch index 870cd37090781..3fee3fa38bcf6 100644 --- a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch +++ b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch @@ -282,10 +282,20 @@ index be2c417c07a4206fac4a9a6c03e516fd0493c942..78f74b0b21242553b6af98628dc48190 return PROCESS_NOTIFIED; } diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc -index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803a5ea7df9 100644 +index ec725b44296266bea1a51aea889463a0bba8449c..6d9aa90857c0ad0d55df1efd1e6791fdab5ecb0a 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" @@ -293,7 +303,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803 #include "base/trace_event/base_tracing.h" #include "base/win/registry.h" #include "base/win/scoped_handle.h" -@@ -45,6 +46,13 @@ +@@ -45,6 +48,13 @@ namespace { const char kLockfile[] = "lockfile"; @@ -307,7 +317,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803 // A helper class that acquires the given |mutex| while the AutoLockMutex is in // scope. -@@ -80,10 +88,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, @@ -322,7 +332,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803 static const int min_message_size = 7; if (cds->cbData < min_message_size * sizeof(wchar_t) || cds->cbData % sizeof(wchar_t) != 0) { -@@ -133,11 +143,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); @@ -405,7 +415,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803 bool ProcessLaunchNotification( const ProcessSingleton::NotificationCallback& notification_callback, UINT message, -@@ -151,16 +232,35 @@ bool ProcessLaunchNotification( +@@ -151,16 +234,35 @@ bool ProcessLaunchNotification( // Handle the WM_COPYDATA message from another process. const COPYDATASTRUCT* cds = reinterpret_cast(lparam); @@ -445,7 +455,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803 return true; } -@@ -261,9 +361,13 @@ bool ProcessSingleton::EscapeVirtualization( +@@ -261,9 +363,13 @@ bool ProcessSingleton::EscapeVirtualization( ProcessSingleton::ProcessSingleton( const std::string& program_name, const base::FilePath& user_data_dir, @@ -460,33 +470,31 @@ index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803 program_name_(program_name), is_app_sandboxed_(is_app_sandboxed), is_virtualized_(false), -@@ -278,6 +382,54 @@ ProcessSingleton::~ProcessSingleton() { +@@ -278,6 +384,52 @@ ProcessSingleton::~ProcessSingleton() { ::CloseHandle(lock_file_); } -+std::wstring GetPipeName(std::string& program_name_) { -+ // Create a per-process pipename using a combination of the -+ // username and executable name. Pipe names are maxed to 256 -+ // characters and can include any character other than a backslash -+ wchar_t user_name[256]; -+ DWORD size = std::size(user_name); -+ if (::GetUserName(user_name, &size) == 0 || size < 1) { -+ NOTREACHED(); -+ } -+ -+ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + program_name_.substr(0, 5)); -+ pipe_name.append(user_name, 10); -+ return pipe_name; -+} -+ -+void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback, std::string& program_name_) { ++void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback, ++ std::string program_name_, ++ base::FilePath& user_data_dir_) { + // We are reading the ack from the first instance. + // First, wait for the pipe. -+ std::wstring pipe_name = GetPipeName(program_name_); -+ const LPCWSTR kPipeName = pipe_name.c_str(); -+ ::WaitNamedPipe(kPipeName, NMPWAIT_USE_DEFAULT_WAIT); ++ HWND remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_); ++ base::FilePath lock_file_path = user_data_dir_.AppendASCII(kLockfile); ++ int64_t file_size = 0; ++ base::GetFileSize(lock_file_path, &file_size); ++ std::string contents(file_size, '\0'); ++ base::ReadFile(lock_file_path, &contents[0], file_size); ++ ++ 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_ + contents); ++ 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, @@ -522,18 +530,37 @@ index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803 - switch (chrome::AttemptToNotifyRunningChrome(remote_window_)) { + switch (chrome::AttemptToNotifyRunningChrome(remote_window_, additional_data_)) { case chrome::NOTIFY_SUCCESS: -+ ReadAck(notification_ack_callback_, program_name_); ++ ReadAck(notification_ack_callback_, program_name_, user_data_dir_); return PROCESS_NOTIFIED; case chrome::NOTIFY_FAILED: remote_window_ = NULL; -@@ -429,6 +582,20 @@ bool ProcessSingleton::Create() { +@@ -410,13 +563,13 @@ bool ProcessSingleton::Create() { + // between the time where we looked for it above and the time the mutex + // was given to us. + remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_); ++ base::FilePath lock_file_path = user_data_dir_.AppendASCII(kLockfile); + + if (!remote_window_) { + // We have to make sure there is no Chrome instance running on another + // machine that uses the same profile. + { + TRACE_EVENT0("startup", "ProcessSingleton::Create:CreateLockFile"); +- base::FilePath lock_file_path = user_data_dir_.AppendASCII(kLockfile); + lock_file_ = ::CreateFile( + lock_file_path.value().c_str(), GENERIC_WRITE, FILE_SHARE_READ, + NULL, CREATE_ALWAYS, +@@ -429,6 +582,24 @@ 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. -+ std::wstring pipe_name = GetPipeName(program_name_); -+ const LPCWSTR kPipeName = pipe_name.c_str(); -+ ack_pipe_ = ::CreateNamedPipe(kPipeName, ++ std::string rand = std::to_string(base::RandUint64()); ++ base::WriteFile(lock_file_path, rand); ++ std::string identifier = base::NumberToString(::GetCurrentProcessId()) + ++ base::NumberToString(::GetCurrentThreadId()); ++ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier + program_name_ + rand); ++ 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, @@ -547,7 +574,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..ba03aed92df7e584fc7e7380892a6803 // 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"); -@@ -456,6 +623,7 @@ bool ProcessSingleton::Create() { +@@ -456,6 +627,7 @@ bool ProcessSingleton::Create() { } void ProcessSingleton::Cleanup() { From 90791851c9515fe38ed59c6e02d9acaa82b75862 Mon Sep 17 00:00:00 2001 From: VerteDinde Date: Mon, 9 May 2022 22:43:23 -0700 Subject: [PATCH 3/6] fix: write rand to file using WIN method --- ...transfer_to_requestsingleinstancelock.patch | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch index 3fee3fa38bcf6..432d8c4d64d5d 100644 --- a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch +++ b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch @@ -282,7 +282,7 @@ index be2c417c07a4206fac4a9a6c03e516fd0493c942..78f74b0b21242553b6af98628dc48190 return PROCESS_NOTIFIED; } diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc -index ec725b44296266bea1a51aea889463a0bba8449c..6d9aa90857c0ad0d55df1efd1e6791fdab5ecb0a 100644 +index ec725b44296266bea1a51aea889463a0bba8449c..5d68e5c8bf99c6ccd0e4fde6386c93cb1db65280 100644 --- a/chrome/browser/process_singleton_win.cc +++ b/chrome/browser/process_singleton_win.cc @@ -13,14 +13,17 @@ @@ -549,16 +549,22 @@ index ec725b44296266bea1a51aea889463a0bba8449c..6d9aa90857c0ad0d55df1efd1e6791fd lock_file_ = ::CreateFile( lock_file_path.value().c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, -@@ -429,6 +582,24 @@ bool ProcessSingleton::Create() { +@@ -429,6 +582,30 @@ 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. -+ std::string rand = std::to_string(base::RandUint64()); -+ base::WriteFile(lock_file_path, rand); ++ uint64_t rand = base::RandUint64(); ++ DWORD bytes_written = 0; ++ ::WriteFile(lock_file_, ++ (LPCVOID)rand, ++ sizeof(rand), ++ &bytes_written, ++ NULL); + std::string identifier = base::NumberToString(::GetCurrentProcessId()) + + base::NumberToString(::GetCurrentThreadId()); -+ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier + program_name_ + rand); ++ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier + ++ program_name_ + std::to_string(rand)); + const LPCWSTR w_pipe_name = pipe_name.c_str(); + ack_pipe_ = ::CreateNamedPipe(w_pipe_name, + PIPE_ACCESS_OUTBOUND, @@ -574,7 +580,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..6d9aa90857c0ad0d55df1efd1e6791fd // 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"); -@@ -456,6 +627,7 @@ bool ProcessSingleton::Create() { +@@ -456,6 +633,7 @@ bool ProcessSingleton::Create() { } void ProcessSingleton::Cleanup() { From ca8cab41c2dc4bfdfd39a9e13a4db77662267db6 Mon Sep 17 00:00:00 2001 From: VerteDinde Date: Mon, 9 May 2022 23:47:16 -0700 Subject: [PATCH 4/6] fix: remove file rand, add user_name to pipe --- ...ransfer_to_requestsingleinstancelock.patch | 60 ++++++++----------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch index 432d8c4d64d5d..018fe59cf7012 100644 --- a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch +++ b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch @@ -282,7 +282,7 @@ index be2c417c07a4206fac4a9a6c03e516fd0493c942..78f74b0b21242553b6af98628dc48190 return PROCESS_NOTIFIED; } diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc -index ec725b44296266bea1a51aea889463a0bba8449c..5d68e5c8bf99c6ccd0e4fde6386c93cb1db65280 100644 +index ec725b44296266bea1a51aea889463a0bba8449c..cf3218df4be6ac4ebf3209ef0d6ede446acbe48a 100644 --- a/chrome/browser/process_singleton_win.cc +++ b/chrome/browser/process_singleton_win.cc @@ -13,14 +13,17 @@ @@ -470,7 +470,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..5d68e5c8bf99c6ccd0e4fde6386c93cb program_name_(program_name), is_app_sandboxed_(is_app_sandboxed), is_virtualized_(false), -@@ -278,6 +384,52 @@ ProcessSingleton::~ProcessSingleton() { +@@ -278,6 +384,53 @@ ProcessSingleton::~ProcessSingleton() { ::CloseHandle(lock_file_); } @@ -480,17 +480,18 @@ index ec725b44296266bea1a51aea889463a0bba8449c..5d68e5c8bf99c6ccd0e4fde6386c93cb + // We are reading the ack from the first instance. + // First, wait for the pipe. + HWND remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_); -+ base::FilePath lock_file_path = user_data_dir_.AppendASCII(kLockfile); -+ int64_t file_size = 0; -+ base::GetFileSize(lock_file_path, &file_size); -+ std::string contents(file_size, '\0'); -+ base::ReadFile(lock_file_path, &contents[0], file_size); -+ ++ wchar_t user_name[256]; ++ DWORD size = std::size(user_name); ++ if (::GetUserName(user_name, &size) == 0 || size < 1) { ++ LOG(ERROR) << "User name could not be found for pipe name."; ++ } + 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_ + contents); ++ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + program_name_ + ++ identifier); ++ pipe_name.append(user_name); + const LPCWSTR w_pipe_name = pipe_name.c_str(); + ::WaitNamedPipe(w_pipe_name, NMPWAIT_USE_DEFAULT_WAIT); + @@ -523,7 +524,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..5d68e5c8bf99c6ccd0e4fde6386c93cb // Code roughly based on Mozilla. ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { TRACE_EVENT0("startup", "ProcessSingleton::NotifyOtherProcess"); -@@ -290,8 +442,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { +@@ -290,8 +443,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { return PROCESS_NONE; } @@ -534,37 +535,24 @@ index ec725b44296266bea1a51aea889463a0bba8449c..5d68e5c8bf99c6ccd0e4fde6386c93cb return PROCESS_NOTIFIED; case chrome::NOTIFY_FAILED: remote_window_ = NULL; -@@ -410,13 +563,13 @@ bool ProcessSingleton::Create() { - // between the time where we looked for it above and the time the mutex - // was given to us. - remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_); -+ base::FilePath lock_file_path = user_data_dir_.AppendASCII(kLockfile); - - if (!remote_window_) { - // We have to make sure there is no Chrome instance running on another - // machine that uses the same profile. - { - TRACE_EVENT0("startup", "ProcessSingleton::Create:CreateLockFile"); -- base::FilePath lock_file_path = user_data_dir_.AppendASCII(kLockfile); - lock_file_ = ::CreateFile( - lock_file_path.value().c_str(), GENERIC_WRITE, FILE_SHARE_READ, - NULL, CREATE_ALWAYS, -@@ -429,6 +582,30 @@ bool ProcessSingleton::Create() { +@@ -429,6 +583,32 @@ 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. -+ uint64_t rand = base::RandUint64(); -+ DWORD bytes_written = 0; -+ ::WriteFile(lock_file_, -+ (LPCVOID)rand, -+ sizeof(rand), -+ &bytes_written, -+ NULL); ++ // 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 ++ wchar_t user_name[256]; ++ DWORD size = std::size(user_name); ++ if (::GetUserName(user_name, &size) == 0 || size < 1) { ++ LOG(ERROR) << "User name could not be found for pipe name."; ++ } + std::string identifier = base::NumberToString(::GetCurrentProcessId()) + + base::NumberToString(::GetCurrentThreadId()); -+ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier + -+ program_name_ + std::to_string(rand)); ++ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + program_name_ + ++ identifier); ++ pipe_name.append(user_name); + const LPCWSTR w_pipe_name = pipe_name.c_str(); + ack_pipe_ = ::CreateNamedPipe(w_pipe_name, + PIPE_ACCESS_OUTBOUND, @@ -580,7 +568,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..5d68e5c8bf99c6ccd0e4fde6386c93cb // 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"); -@@ -456,6 +633,7 @@ bool ProcessSingleton::Create() { +@@ -456,6 +636,7 @@ bool ProcessSingleton::Create() { } void ProcessSingleton::Cleanup() { From d5294998dff2d54771160f0a94f19df02d7cfa8a Mon Sep 17 00:00:00 2001 From: VerteDinde Date: Tue, 10 May 2022 07:22:02 -0700 Subject: [PATCH 5/6] chore: style fixes, shorten program_name & user_name --- ...ransfer_to_requestsingleinstancelock.patch | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch index 018fe59cf7012..bf3c08a4bb235 100644 --- a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch +++ b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch @@ -282,7 +282,7 @@ index be2c417c07a4206fac4a9a6c03e516fd0493c942..78f74b0b21242553b6af98628dc48190 return PROCESS_NOTIFIED; } diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc -index ec725b44296266bea1a51aea889463a0bba8449c..cf3218df4be6ac4ebf3209ef0d6ede446acbe48a 100644 +index ec725b44296266bea1a51aea889463a0bba8449c..f0ae34a7c1020be043ed8d56a755ad9caf8fc330 100644 --- a/chrome/browser/process_singleton_win.cc +++ b/chrome/browser/process_singleton_win.cc @@ -13,14 +13,17 @@ @@ -475,23 +475,23 @@ index ec725b44296266bea1a51aea889463a0bba8449c..cf3218df4be6ac4ebf3209ef0d6ede44 } +void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback, -+ std::string program_name_, -+ base::FilePath& user_data_dir_) { ++ const std::string program_name, ++ base::FilePath& user_data_dir) { + // We are reading the ack from the first instance. + // First, wait for the pipe. -+ HWND remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_); ++ HWND remote_window = chrome::FindRunningChromeWindow(user_data_dir); + wchar_t user_name[256]; + DWORD size = std::size(user_name); + if (::GetUserName(user_name, &size) == 0 || size < 1) { + LOG(ERROR) << "User name could not be found for pipe name."; + } + DWORD process_id; -+ DWORD thread_id = GetWindowThreadProcessId(remote_window_, &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\\" + program_name_ + -+ identifier); -+ pipe_name.append(user_name); ++ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier + ++ program_name.substr(0, 5)); ++ pipe_name.append(user_name, 5); + const LPCWSTR w_pipe_name = pipe_name.c_str(); + ::WaitNamedPipe(w_pipe_name, NMPWAIT_USE_DEFAULT_WAIT); + @@ -535,7 +535,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..cf3218df4be6ac4ebf3209ef0d6ede44 return PROCESS_NOTIFIED; case chrome::NOTIFY_FAILED: remote_window_ = NULL; -@@ -429,6 +583,32 @@ bool ProcessSingleton::Create() { +@@ -429,6 +583,34 @@ bool ProcessSingleton::Create() { << "Lock file can not be created! Error code: " << error; if (lock_file_ != INVALID_HANDLE_VALUE) { @@ -543,6 +543,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..cf3218df4be6ac4ebf3209ef0d6ede44 + // 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 p = program_name_.substr(0, 5); + wchar_t user_name[256]; + DWORD size = std::size(user_name); + if (::GetUserName(user_name, &size) == 0 || size < 1) { @@ -550,10 +551,11 @@ index ec725b44296266bea1a51aea889463a0bba8449c..cf3218df4be6ac4ebf3209ef0d6ede44 + } + std::string identifier = base::NumberToString(::GetCurrentProcessId()) + + base::NumberToString(::GetCurrentThreadId()); -+ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + program_name_ + -+ identifier); -+ pipe_name.append(user_name); ++ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier + ++ program_name_.substr(0, 5)); ++ pipe_name.append(user_name, 5); + const LPCWSTR w_pipe_name = pipe_name.c_str(); ++ LOG(INFO) << "Pipe Name: " << w_pipe_name; + ack_pipe_ = ::CreateNamedPipe(w_pipe_name, + PIPE_ACCESS_OUTBOUND, + PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS, @@ -568,7 +570,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..cf3218df4be6ac4ebf3209ef0d6ede44 // 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"); -@@ -456,6 +636,7 @@ bool ProcessSingleton::Create() { +@@ -456,6 +638,7 @@ bool ProcessSingleton::Create() { } void ProcessSingleton::Cleanup() { From 8d592adce319988b12bd2482be23c8a5c8c0034d Mon Sep 17 00:00:00 2001 From: VerteDinde Date: Tue, 10 May 2022 10:03:51 -0700 Subject: [PATCH 6/6] fix: remove user_name --- ...ransfer_to_requestsingleinstancelock.patch | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch index bf3c08a4bb235..61eeec59f5705 100644 --- a/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch +++ b/patches/chromium/feat_add_data_transfer_to_requestsingleinstancelock.patch @@ -282,7 +282,7 @@ index be2c417c07a4206fac4a9a6c03e516fd0493c942..78f74b0b21242553b6af98628dc48190 return PROCESS_NOTIFIED; } diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc -index ec725b44296266bea1a51aea889463a0bba8449c..f0ae34a7c1020be043ed8d56a755ad9caf8fc330 100644 +index ec725b44296266bea1a51aea889463a0bba8449c..6355e5c73ba9df9bdb9ff48205d909dca04470f1 100644 --- a/chrome/browser/process_singleton_win.cc +++ b/chrome/browser/process_singleton_win.cc @@ -13,14 +13,17 @@ @@ -470,7 +470,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..f0ae34a7c1020be043ed8d56a755ad9c program_name_(program_name), is_app_sandboxed_(is_app_sandboxed), is_virtualized_(false), -@@ -278,6 +384,53 @@ ProcessSingleton::~ProcessSingleton() { +@@ -278,6 +384,47 @@ ProcessSingleton::~ProcessSingleton() { ::CloseHandle(lock_file_); } @@ -480,18 +480,12 @@ index ec725b44296266bea1a51aea889463a0bba8449c..f0ae34a7c1020be043ed8d56a755ad9c + // We are reading the ack from the first instance. + // First, wait for the pipe. + HWND remote_window = chrome::FindRunningChromeWindow(user_data_dir); -+ wchar_t user_name[256]; -+ DWORD size = std::size(user_name); -+ if (::GetUserName(user_name, &size) == 0 || size < 1) { -+ LOG(ERROR) << "User name could not be found for pipe name."; -+ } + 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.substr(0, 5)); -+ pipe_name.append(user_name, 5); ++ program_name); + const LPCWSTR w_pipe_name = pipe_name.c_str(); + ::WaitNamedPipe(w_pipe_name, NMPWAIT_USE_DEFAULT_WAIT); + @@ -524,7 +518,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..f0ae34a7c1020be043ed8d56a755ad9c // Code roughly based on Mozilla. ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { TRACE_EVENT0("startup", "ProcessSingleton::NotifyOtherProcess"); -@@ -290,8 +443,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { +@@ -290,8 +437,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { return PROCESS_NONE; } @@ -535,7 +529,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..f0ae34a7c1020be043ed8d56a755ad9c return PROCESS_NOTIFIED; case chrome::NOTIFY_FAILED: remote_window_ = NULL; -@@ -429,6 +583,34 @@ bool ProcessSingleton::Create() { +@@ -429,6 +577,26 @@ bool ProcessSingleton::Create() { << "Lock file can not be created! Error code: " << error; if (lock_file_ != INVALID_HANDLE_VALUE) { @@ -543,19 +537,11 @@ index ec725b44296266bea1a51aea889463a0bba8449c..f0ae34a7c1020be043ed8d56a755ad9c + // 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 p = program_name_.substr(0, 5); -+ wchar_t user_name[256]; -+ DWORD size = std::size(user_name); -+ if (::GetUserName(user_name, &size) == 0 || size < 1) { -+ LOG(ERROR) << "User name could not be found for pipe name."; -+ } + std::string identifier = base::NumberToString(::GetCurrentProcessId()) + + base::NumberToString(::GetCurrentThreadId()); + std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier + -+ program_name_.substr(0, 5)); -+ pipe_name.append(user_name, 5); ++ program_name_); + const LPCWSTR w_pipe_name = pipe_name.c_str(); -+ LOG(INFO) << "Pipe Name: " << w_pipe_name; + ack_pipe_ = ::CreateNamedPipe(w_pipe_name, + PIPE_ACCESS_OUTBOUND, + PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS, @@ -570,7 +556,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..f0ae34a7c1020be043ed8d56a755ad9c // 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"); -@@ -456,6 +638,7 @@ bool ProcessSingleton::Create() { +@@ -456,6 +624,7 @@ bool ProcessSingleton::Create() { } void ProcessSingleton::Cleanup() {