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

Side by Side Diff: chrome_frame/test_utils.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, 9 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_frame/test_utils.h" 5 #include "chrome_frame/test_utils.h"
6 6
7 #include <atlbase.h> 7 #include <atlbase.h>
8 #include <atlwin.h> 8 #include <atlwin.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #include <winternl.h>
11 10
12 #include <algorithm> 11 #include <algorithm>
13 12
14 #include "base/command_line.h" 13 #include "base/command_line.h"
15 #include "base/file_path.h" 14 #include "base/file_path.h"
16 #include "base/file_util.h" 15 #include "base/file_util.h"
17 #include "base/logging.h" 16 #include "base/logging.h"
18 #include "base/path_service.h" 17 #include "base/path_service.h"
19 #include "base/process_util.h" 18 #include "base/process_util.h"
20 #include "base/string_util.h"
21 #include "base/stringprintf.h" 19 #include "base/stringprintf.h"
22 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
23 #include "base/win/scoped_handle.h" 21 #include "base/win/scoped_handle.h"
24 #include "chrome/common/chrome_paths.h" 22 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/chrome_switches.h" 23 #include "chrome/common/chrome_switches.h"
26 #include "chrome_frame/test/chrome_frame_test_utils.h" 24 #include "chrome_frame/test/chrome_frame_test_utils.h"
27 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
28 26
29 const wchar_t kChromeFrameDllName[] = L"npchrome_frame.dll"; 27 const wchar_t kChromeFrameDllName[] = L"npchrome_frame.dll";
30 const wchar_t kChromeLauncherExeName[] = L"chrome_launcher.exe"; 28 const wchar_t kChromeLauncherExeName[] = L"chrome_launcher.exe";
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } 260 }
263 261
264 void ScopedChromeFrameRegistrar::RegisterReferenceChromeFrameBuild() { 262 void ScopedChromeFrameRegistrar::RegisterReferenceChromeFrameBuild() {
265 RegisterChromeFrameAtPath(GetReferenceChromeFrameDllPath().value()); 263 RegisterChromeFrameAtPath(GetReferenceChromeFrameDllPath().value());
266 } 264 }
267 265
268 std::wstring ScopedChromeFrameRegistrar::GetChromeFrameDllPath() const { 266 std::wstring ScopedChromeFrameRegistrar::GetChromeFrameDllPath() const {
269 return new_chrome_frame_dll_path_; 267 return new_chrome_frame_dll_path_;
270 } 268 }
271 269
272 // TODO(robertshield): The following could be factored out into its own file.
273 namespace {
274
275 typedef LONG WINAPI
276 NtQueryInformationProcess(
277 IN HANDLE ProcessHandle,
278 IN PROCESSINFOCLASS ProcessInformationClass,
279 OUT PVOID ProcessInformation,
280 IN ULONG ProcessInformationLength,
281 OUT PULONG ReturnLength OPTIONAL
282 );
283
284 // Get the function pointer to NtQueryInformationProcess in NTDLL.DLL
285 static bool GetQIP(NtQueryInformationProcess** qip_func_ptr) {
286 static NtQueryInformationProcess* qip_func =
287 reinterpret_cast<NtQueryInformationProcess*>(
288 GetProcAddress(GetModuleHandle(L"ntdll.dll"),
289 "NtQueryInformationProcess"));
290 DCHECK(qip_func) << "Could not get pointer to NtQueryInformationProcess.";
291 *qip_func_ptr = qip_func;
292 return qip_func != NULL;
293 }
294
295 // Get the command line of a process
296 bool GetCommandLineForProcess(uint32 process_id, std::wstring* cmd_line) {
297 DCHECK(process_id != 0);
298 DCHECK(cmd_line);
299
300 // Open the process
301 base::win::ScopedHandle process_handle(::OpenProcess(
302 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
303 false,
304 process_id));
305 if (!process_handle) {
306 DLOG(ERROR) << "Failed to open process " << process_id << ", last error = "
307 << GetLastError();
308 }
309
310 // Obtain Process Environment Block
311 NtQueryInformationProcess* qip_func = NULL;
312 if (process_handle) {
313 GetQIP(&qip_func);
314 }
315
316 // Read the address of the process params from the peb.
317 DWORD process_params_address = 0;
318 if (qip_func) {
319 PROCESS_BASIC_INFORMATION info = { 0 };
320 // NtQueryInformationProcess returns an NTSTATUS for whom negative values
321 // are negative. Just check for that instead of pulling in DDK macros.
322 if ((qip_func(process_handle.Get(),
323 ProcessBasicInformation,
324 &info,
325 sizeof(info),
326 NULL)) < 0) {
327 DLOG(ERROR) << "Failed to invoke NtQueryProcessInformation, last error = "
328 << GetLastError();
329 } else {
330 BYTE* peb = reinterpret_cast<BYTE*>(info.PebBaseAddress);
331
332 // The process command line parameters are (or were once) located at
333 // the base address of the PEB + 0x10 for 32 bit processes. 64 bit
334 // processes have a different PEB struct as per
335 // http://msdn.microsoft.com/en-us/library/aa813706(VS.85).aspx.
336 // TODO(robertshield): See about doing something about this.
337 SIZE_T bytes_read = 0;
338 if (!::ReadProcessMemory(process_handle.Get(),
339 peb + 0x10,
340 &process_params_address,
341 sizeof(process_params_address),
342 &bytes_read)) {
343 DLOG(ERROR) << "Failed to read process params address, last error = "
344 << GetLastError();
345 }
346 }
347 }
348
349 // Copy all the process parameters into a buffer.
350 bool success = false;
351 std::wstring buffer;
352 if (process_params_address) {
353 SIZE_T bytes_read;
354 RTL_USER_PROCESS_PARAMETERS params = { 0 };
355 if (!::ReadProcessMemory(process_handle.Get(),
356 reinterpret_cast<void*>(process_params_address),
357 &params,
358 sizeof(params),
359 &bytes_read)) {
360 DLOG(ERROR) << "Failed to read RTL_USER_PROCESS_PARAMETERS, "
361 << "last error = " << GetLastError();
362 } else {
363 // Read the command line parameter
364 const int max_cmd_line_len = std::min(
365 static_cast<int>(params.CommandLine.MaximumLength),
366 4096);
367 buffer.resize(max_cmd_line_len + 1);
368 if (!::ReadProcessMemory(process_handle.Get(),
369 params.CommandLine.Buffer,
370 &buffer[0],
371 max_cmd_line_len,
372 &bytes_read)) {
373 DLOG(ERROR) << "Failed to copy process command line, "
374 << "last error = " << GetLastError();
375 } else {
376 *cmd_line = buffer;
377 success = true;
378 }
379 }
380 }
381
382 return success;
383 }
384
385 // Used to filter processes by process ID.
386 class ArgumentFilter : public base::ProcessFilter {
387 public:
388 explicit ArgumentFilter(const std::wstring& argument)
389 : argument_to_find_(argument) {}
390
391 // Returns true to indicate set-inclusion and false otherwise. This method
392 // should not have side-effects and should be idempotent.
393 virtual bool Includes(const base::ProcessEntry& entry) const {
394 bool found = false;
395 std::wstring command_line;
396 if (GetCommandLineForProcess(entry.pid(), &command_line)) {
397 std::wstring::const_iterator it =
398 std::search(command_line.begin(),
399 command_line.end(),
400 argument_to_find_.begin(),
401 argument_to_find_.end(),
402 base::CaseInsensitiveCompareASCII<wchar_t>());
403 found = (it != command_line.end());
404 }
405 return found;
406 }
407
408 protected:
409 std::wstring argument_to_find_;
410 };
411
412 } // namespace
413
414 bool KillAllNamedProcessesWithArgument(const std::wstring& process_name,
415 const std::wstring& argument) {
416 return base::KillProcesses(process_name, 0, &ArgumentFilter(argument));
417 }
418
419 bool IsWorkstationLocked() { 270 bool IsWorkstationLocked() {
420 bool is_locked = true; 271 bool is_locked = true;
421 HDESK input_desk = ::OpenInputDesktop(0, 0, GENERIC_READ); 272 HDESK input_desk = ::OpenInputDesktop(0, 0, GENERIC_READ);
422 if (input_desk) { 273 if (input_desk) {
423 wchar_t name[256] = {0}; 274 wchar_t name[256] = {0};
424 DWORD needed = 0; 275 DWORD needed = 0;
425 if (::GetUserObjectInformation(input_desk, 276 if (::GetUserObjectInformation(input_desk,
426 UOI_NAME, 277 UOI_NAME,
427 name, 278 name,
428 sizeof(name), 279 sizeof(name),
429 &needed)) { 280 &needed)) {
430 is_locked = lstrcmpi(name, L"default") != 0; 281 is_locked = lstrcmpi(name, L"default") != 0;
431 } 282 }
432 ::CloseDesktop(input_desk); 283 ::CloseDesktop(input_desk);
433 } 284 }
434 return is_locked; 285 return is_locked;
435 } 286 }
OLDNEW
« base/test/test_process_killer_win.cc ('K') | « chrome_frame/test_utils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698