Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: base/test/test_process_killer_win.cc

Issue 12314043: Make Ash unittests clean up zombie viewer processes between test runs. These zombie viewer proce… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: "Add missing test_scrubber.cc change." Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/test/test_process_killer_win.h ('k') | chrome_frame/test/chrome_frame_automation_mock.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/test/test_process_killer_win.h"
6
7 #include <windows.h>
8 #include <winternl.h>
9
10 #include <algorithm>
11
12 #include "base/logging.h"
13 #include "base/process_util.h"
14 #include "base/string_util.h"
15 #include "base/win/scoped_handle.h"
16
17 namespace {
18
19 typedef LONG WINAPI
20 NtQueryInformationProcess(
21 IN HANDLE ProcessHandle,
22 IN PROCESSINFOCLASS ProcessInformationClass,
23 OUT PVOID ProcessInformation,
24 IN ULONG ProcessInformationLength,
25 OUT PULONG ReturnLength OPTIONAL
26 );
27
28 // Get the function pointer to NtQueryInformationProcess in NTDLL.DLL
29 static bool GetQIP(NtQueryInformationProcess** qip_func_ptr) {
30 static NtQueryInformationProcess* qip_func =
31 reinterpret_cast<NtQueryInformationProcess*>(
32 GetProcAddress(GetModuleHandle(L"ntdll.dll"),
33 "NtQueryInformationProcess"));
34 DCHECK(qip_func) << "Could not get pointer to NtQueryInformationProcess.";
35 *qip_func_ptr = qip_func;
36 return qip_func != NULL;
37 }
38
39 // Get the command line of a process
40 bool GetCommandLineForProcess(uint32 process_id, string16* cmd_line) {
41 DCHECK(process_id != 0);
42 DCHECK(cmd_line);
43
44 // Open the process
45 base::win::ScopedHandle process_handle(::OpenProcess(
46 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
47 false,
48 process_id));
49 if (!process_handle) {
50 DLOG(ERROR) << "Failed to open process " << process_id << ", last error = "
51 << GetLastError();
52 }
53
54 // Obtain Process Environment Block
55 NtQueryInformationProcess* qip_func = NULL;
56 if (process_handle) {
57 GetQIP(&qip_func);
58 }
59
60 // Read the address of the process params from the peb.
61 DWORD process_params_address = 0;
62 if (qip_func) {
63 PROCESS_BASIC_INFORMATION info = { 0 };
64 // NtQueryInformationProcess returns an NTSTATUS for whom negative values
65 // are negative. Just check for that instead of pulling in DDK macros.
66 if ((qip_func(process_handle.Get(),
67 ProcessBasicInformation,
68 &info,
69 sizeof(info),
70 NULL)) < 0) {
71 DLOG(ERROR) << "Failed to invoke NtQueryProcessInformation, last error = "
72 << GetLastError();
73 } else {
74 BYTE* peb = reinterpret_cast<BYTE*>(info.PebBaseAddress);
75
76 // The process command line parameters are (or were once) located at
77 // the base address of the PEB + 0x10 for 32 bit processes. 64 bit
78 // processes have a different PEB struct as per
79 // http://msdn.microsoft.com/en-us/library/aa813706(VS.85).aspx.
80 // TODO(robertshield): See about doing something about this.
81 SIZE_T bytes_read = 0;
82 if (!::ReadProcessMemory(process_handle.Get(),
83 peb + 0x10,
84 &process_params_address,
85 sizeof(process_params_address),
86 &bytes_read)) {
87 DLOG(ERROR) << "Failed to read process params address, last error = "
88 << GetLastError();
89 }
90 }
91 }
92
93 // Copy all the process parameters into a buffer.
94 bool success = false;
95 string16 buffer;
96 if (process_params_address) {
97 SIZE_T bytes_read;
98 RTL_USER_PROCESS_PARAMETERS params = { 0 };
99 if (!::ReadProcessMemory(process_handle.Get(),
100 reinterpret_cast<void*>(process_params_address),
101 &params,
102 sizeof(params),
103 &bytes_read)) {
104 DLOG(ERROR) << "Failed to read RTL_USER_PROCESS_PARAMETERS, "
105 << "last error = " << GetLastError();
106 } else {
107 // Read the command line parameter
108 const int max_cmd_line_len = std::min(
109 static_cast<int>(params.CommandLine.MaximumLength),
110 4096);
111 buffer.resize(max_cmd_line_len + 1);
112 if (!::ReadProcessMemory(process_handle.Get(),
113 params.CommandLine.Buffer,
114 &buffer[0],
115 max_cmd_line_len,
116 &bytes_read)) {
117 DLOG(ERROR) << "Failed to copy process command line, "
118 << "last error = " << GetLastError();
119 } else {
120 *cmd_line = buffer;
121 success = true;
122 }
123 }
124 }
125
126 return success;
127 }
128
129 // Used to filter processes by process ID.
130 class ArgumentFilter : public base::ProcessFilter {
131 public:
132 explicit ArgumentFilter(const string16& argument)
133 : argument_to_find_(argument) {}
134
135 // Returns true to indicate set-inclusion and false otherwise. This method
136 // should not have side-effects and should be idempotent.
137 virtual bool Includes(const base::ProcessEntry& entry) const {
138 bool found = false;
139 string16 command_line;
140 if (GetCommandLineForProcess(entry.pid(), &command_line)) {
141 string16::const_iterator it =
142 std::search(command_line.begin(),
143 command_line.end(),
144 argument_to_find_.begin(),
145 argument_to_find_.end(),
146 base::CaseInsensitiveCompareASCII<wchar_t>());
147 found = (it != command_line.end());
148 }
149 return found;
150 }
151
152 protected:
153 string16 argument_to_find_;
154 };
155
156 } // namespace
157
158 namespace base {
159
160 bool KillAllNamedProcessesWithArgument(const string16& process_name,
161 const string16& argument) {
162 return base::KillProcesses(process_name, 0, &ArgumentFilter(argument));
Timur Iskhodzhanov 2013/03/18 22:28:47 I think this is a buggy line: http://crbug.com/219
163 }
164
165 } // namespace base
OLDNEW
« no previous file with comments | « base/test/test_process_killer_win.h ('k') | chrome_frame/test/chrome_frame_automation_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698