OLD | NEW |
---|---|
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/app/chrome_watcher_command_line_win.h" | 5 #include "chrome/app/chrome_watcher_command_line_win.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
14 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
15 | 15 |
16 namespace { | 16 namespace { |
17 | |
18 const char kOnIninitializedEventHandleSwitch[] = "on-initialized-event-handle"; | |
17 const char kParentHandleSwitch[] = "parent-handle"; | 19 const char kParentHandleSwitch[] = "parent-handle"; |
20 | |
21 void AppendHandleSwitch(base::CommandLine* command_line, | |
grt (UTC plus 2)
2015/02/03 21:20:45
base::CommandLine* command_line should be last sin
erikwright (departed)
2015/02/03 21:56:47
Done.
| |
22 const std::string& switch_name, | |
23 HANDLE handle) { | |
24 command_line->AppendSwitchASCII( | |
25 switch_name, base::UintToString(reinterpret_cast<unsigned int>(handle))); | |
26 } | |
27 | |
28 HANDLE ReadHandleFromSwitch(const base::CommandLine& command_line, | |
29 const std::string& switch_name) { | |
30 std::string switch_string = command_line.GetSwitchValueASCII(switch_name); | |
31 unsigned switch_uint = 0; | |
grt (UTC plus 2)
2015/02/03 21:20:45
"unsigned" -> "unsigned int"
erikwright (departed)
2015/02/03 21:56:47
Done.
| |
32 if (switch_string.empty() || | |
33 !base::StringToUint(switch_string, &switch_uint)) { | |
34 LOG(ERROR) << "Missing or invalid " << switch_name << " argument."; | |
35 return NULL; | |
grt (UTC plus 2)
2015/02/03 21:20:45
nullptr
erikwright (departed)
2015/02/03 21:56:47
Done.
| |
36 } | |
37 return reinterpret_cast<HANDLE>(switch_uint); | |
38 } | |
39 | |
18 } // namespace | 40 } // namespace |
19 | 41 |
20 base::CommandLine GenerateChromeWatcherCommandLine( | 42 base::CommandLine GenerateChromeWatcherCommandLine( |
21 const base::FilePath& chrome_exe, | 43 const base::FilePath& chrome_exe, |
44 HANDLE on_initialized_event, | |
22 HANDLE parent_process) { | 45 HANDLE parent_process) { |
23 base::CommandLine command_line(chrome_exe); | 46 base::CommandLine command_line(chrome_exe); |
24 command_line.AppendSwitchASCII(switches::kProcessType, "watcher"); | 47 command_line.AppendSwitchASCII(switches::kProcessType, "watcher"); |
25 command_line.AppendSwitchASCII( | 48 AppendHandleSwitch(&command_line, kOnIninitializedEventHandleSwitch, |
26 kParentHandleSwitch, | 49 on_initialized_event); |
27 base::UintToString(reinterpret_cast<unsigned int>(parent_process))); | 50 AppendHandleSwitch(&command_line, kParentHandleSwitch, parent_process); |
28 return command_line; | 51 return command_line; |
29 } | 52 } |
30 | 53 |
31 base::win::ScopedHandle InterpretChromeWatcherCommandLine( | 54 bool InterpretChromeWatcherCommandLine( |
32 const base::CommandLine& command_line) { | 55 const base::CommandLine& command_line, |
33 std::string parent_handle_str = | 56 base::win::ScopedHandle* on_initialized_event, |
34 command_line.GetSwitchValueASCII(kParentHandleSwitch); | 57 base::win::ScopedHandle* parent_process) { |
35 unsigned parent_handle_uint = 0; | 58 DCHECK(on_initialized_event); |
36 if (parent_handle_str.empty() || | 59 DCHECK(parent_process); |
37 !base::StringToUint(parent_handle_str, &parent_handle_uint)) { | 60 |
38 LOG(ERROR) << "Missing or invalid " << kParentHandleSwitch << " argument."; | 61 HANDLE parent_handle = |
39 return base::win::ScopedHandle(); | 62 ReadHandleFromSwitch(command_line, kParentHandleSwitch); |
63 HANDLE on_initialized_event_handle = | |
64 ReadHandleFromSwitch(command_line, kOnIninitializedEventHandleSwitch); | |
65 | |
66 if (parent_handle) { | |
67 // Initial test of the handle, a zero PID indicates invalid handle, or not | |
68 // a process handle. In this case, parsing fails and we avoid closing the | |
69 // handle. | |
70 DWORD process_pid = ::GetProcessId(parent_handle); | |
71 if (process_pid == 0) { | |
72 LOG(ERROR) << "Invalid " << kParentHandleSwitch | |
73 << " argument. Can't get parent PID."; | |
74 } else { | |
75 parent_process->Set(parent_handle); | |
76 } | |
40 } | 77 } |
41 | 78 |
42 HANDLE parent_process = reinterpret_cast<HANDLE>(parent_handle_uint); | 79 if (on_initialized_event_handle) { |
43 // Initial test of the handle, a zero PID indicates invalid handle, or not | 80 DWORD result = ::WaitForSingleObject(on_initialized_event_handle, 0); |
44 // a process handle. In this case, parsing fails and we avoid closing the | 81 if (result == WAIT_FAILED) { |
45 // handle. | 82 PLOG(ERROR) << "Unexpected error while testing the initialization event."; |
46 DWORD process_pid = ::GetProcessId(parent_process); | 83 } else if (result != WAIT_TIMEOUT) { |
47 if (process_pid == 0) { | 84 LOG(ERROR) << "Unexpected result while testing the initialization event " |
48 LOG(ERROR) << "Invalid " << kParentHandleSwitch | 85 "with WaitForSingleObject: " << result; |
49 << " argument. Can't get parent PID."; | 86 } else { |
50 return base::win::ScopedHandle(); | 87 on_initialized_event->Set(on_initialized_event_handle); |
88 } | |
51 } | 89 } |
52 | 90 |
53 return base::win::ScopedHandle(parent_process); | 91 if (!on_initialized_event->IsValid() || !parent_process->IsValid()) { |
grt (UTC plus 2)
2015/02/03 21:20:45
this function doesn't ensure that the two ScopedHa
erikwright (departed)
2015/02/03 21:56:47
Added explicit Close calls as an expedient and con
| |
92 // If one was valid and not the other, free the valid one. | |
93 on_initialized_event->Close(); | |
94 parent_process->Close(); | |
95 return false; | |
96 } | |
97 | |
98 return true; | |
54 } | 99 } |
OLD | NEW |