| OLD | NEW | 
|    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 "base/process_util.h" |    5 #include "base/process_util.h" | 
|    6  |    6  | 
|    7 #include <fcntl.h> |    7 #include <fcntl.h> | 
|    8 #include <io.h> |    8 #include <io.h> | 
|    9 #include <windows.h> |    9 #include <windows.h> | 
|   10 #include <userenv.h> |   10 #include <userenv.h> | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   43 static const int kWaitInterval = 2000; |   43 static const int kWaitInterval = 2000; | 
|   44  |   44  | 
|   45 // This exit code is used by the Windows task manager when it kills a |   45 // This exit code is used by the Windows task manager when it kills a | 
|   46 // process.  It's value is obviously not that unique, and it's |   46 // process.  It's value is obviously not that unique, and it's | 
|   47 // surprising to me that the task manager uses this value, but it |   47 // surprising to me that the task manager uses this value, but it | 
|   48 // seems to be common practice on Windows to test for it as an |   48 // seems to be common practice on Windows to test for it as an | 
|   49 // indication that the task manager has killed something if the |   49 // indication that the task manager has killed something if the | 
|   50 // process goes away. |   50 // process goes away. | 
|   51 const DWORD kProcessKilledExitCode = 1; |   51 const DWORD kProcessKilledExitCode = 1; | 
|   52  |   52  | 
|   53 // HeapSetInformation function pointer. |  | 
|   54 typedef BOOL (WINAPI* HeapSetFn)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T); |  | 
|   55  |  | 
|   56 void OnNoMemory() { |  | 
|   57   // Kill the process. This is important for security, since WebKit doesn't |  | 
|   58   // NULL-check many memory allocations. If a malloc fails, returns NULL, and |  | 
|   59   // the buffer is then used, it provides a handy mapping of memory starting at |  | 
|   60   // address 0 for an attacker to utilize. |  | 
|   61   __debugbreak(); |  | 
|   62   _exit(1); |  | 
|   63 } |  | 
|   64  |  | 
|   65 class TimerExpiredTask : public win::ObjectWatcher::Delegate { |   53 class TimerExpiredTask : public win::ObjectWatcher::Delegate { | 
|   66  public: |   54  public: | 
|   67   explicit TimerExpiredTask(ProcessHandle process); |   55   explicit TimerExpiredTask(ProcessHandle process); | 
|   68   ~TimerExpiredTask(); |   56   ~TimerExpiredTask(); | 
|   69  |   57  | 
|   70   void TimedOut(); |   58   void TimedOut(); | 
|   71  |   59  | 
|   72   // MessageLoop::Watcher ----------------------------------------------------- |   60   // MessageLoop::Watcher ----------------------------------------------------- | 
|   73   virtual void OnObjectSignaled(HANDLE object); |   61   virtual void OnObjectSignaled(HANDLE object); | 
|   74  |   62  | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  176 } |  164 } | 
|  177  |  165  | 
|  178 ProcessId GetCurrentProcId() { |  166 ProcessId GetCurrentProcId() { | 
|  179   return ::GetCurrentProcessId(); |  167   return ::GetCurrentProcessId(); | 
|  180 } |  168 } | 
|  181  |  169  | 
|  182 ProcessHandle GetCurrentProcessHandle() { |  170 ProcessHandle GetCurrentProcessHandle() { | 
|  183   return ::GetCurrentProcess(); |  171   return ::GetCurrentProcess(); | 
|  184 } |  172 } | 
|  185  |  173  | 
|  186 HMODULE GetModuleFromAddress(void* address) { |  | 
|  187   HMODULE instance = NULL; |  | 
|  188   if (!::GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | |  | 
|  189                             GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, |  | 
|  190                             static_cast<char*>(address), |  | 
|  191                             &instance)) { |  | 
|  192     NOTREACHED(); |  | 
|  193   } |  | 
|  194   return instance; |  | 
|  195 } |  | 
|  196  |  | 
|  197 bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) { |  174 bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) { | 
|  198   // We try to limit privileges granted to the handle. If you need this |  175   // We try to limit privileges granted to the handle. If you need this | 
|  199   // for test code, consider using OpenPrivilegedProcessHandle instead of |  176   // for test code, consider using OpenPrivilegedProcessHandle instead of | 
|  200   // adding more privileges here. |  177   // adding more privileges here. | 
|  201   ProcessHandle result = OpenProcess(PROCESS_TERMINATE | |  178   ProcessHandle result = OpenProcess(PROCESS_TERMINATE | | 
|  202                                      PROCESS_QUERY_INFORMATION | |  179                                      PROCESS_QUERY_INFORMATION | | 
|  203                                      SYNCHRONIZE, |  180                                      SYNCHRONIZE, | 
|  204                                      FALSE, pid); |  181                                      FALSE, pid); | 
|  205  |  182  | 
|  206   if (result == NULL) |  183   if (result == NULL) | 
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  625     return; |  602     return; | 
|  626   } |  603   } | 
|  627  |  604  | 
|  628   MessageLoop::current()->PostDelayedTask( |  605   MessageLoop::current()->PostDelayedTask( | 
|  629       FROM_HERE, |  606       FROM_HERE, | 
|  630       base::Bind(&TimerExpiredTask::TimedOut, |  607       base::Bind(&TimerExpiredTask::TimedOut, | 
|  631                  base::Owned(new TimerExpiredTask(process))), |  608                  base::Owned(new TimerExpiredTask(process))), | 
|  632       base::TimeDelta::FromMilliseconds(kWaitInterval)); |  609       base::TimeDelta::FromMilliseconds(kWaitInterval)); | 
|  633 } |  610 } | 
|  634  |  611  | 
|  635 bool EnableLowFragmentationHeap() { |  | 
|  636   HMODULE kernel32 = GetModuleHandle(L"kernel32.dll"); |  | 
|  637   HeapSetFn heap_set = reinterpret_cast<HeapSetFn>(GetProcAddress( |  | 
|  638       kernel32, |  | 
|  639       "HeapSetInformation")); |  | 
|  640  |  | 
|  641   // On Windows 2000, the function is not exported. This is not a reason to |  | 
|  642   // fail. |  | 
|  643   if (!heap_set) |  | 
|  644     return true; |  | 
|  645  |  | 
|  646   unsigned number_heaps = GetProcessHeaps(0, NULL); |  | 
|  647   if (!number_heaps) |  | 
|  648     return false; |  | 
|  649  |  | 
|  650   // Gives us some extra space in the array in case a thread is creating heaps |  | 
|  651   // at the same time we're querying them. |  | 
|  652   static const int MARGIN = 8; |  | 
|  653   scoped_ptr<HANDLE[]> heaps(new HANDLE[number_heaps + MARGIN]); |  | 
|  654   number_heaps = GetProcessHeaps(number_heaps + MARGIN, heaps.get()); |  | 
|  655   if (!number_heaps) |  | 
|  656     return false; |  | 
|  657  |  | 
|  658   for (unsigned i = 0; i < number_heaps; ++i) { |  | 
|  659     ULONG lfh_flag = 2; |  | 
|  660     // Don't bother with the result code. It may fails on heaps that have the |  | 
|  661     // HEAP_NO_SERIALIZE flag. This is expected and not a problem at all. |  | 
|  662     heap_set(heaps[i], |  | 
|  663              HeapCompatibilityInformation, |  | 
|  664              &lfh_flag, |  | 
|  665              sizeof(lfh_flag)); |  | 
|  666   } |  | 
|  667   return true; |  | 
|  668 } |  | 
|  669  |  | 
|  670 void EnableTerminationOnHeapCorruption() { |  | 
|  671   // Ignore the result code. Supported on XP SP3 and Vista. |  | 
|  672   HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); |  | 
|  673 } |  | 
|  674  |  | 
|  675 void EnableTerminationOnOutOfMemory() { |  | 
|  676   std::set_new_handler(&OnNoMemory); |  | 
|  677 } |  | 
|  678  |  | 
|  679 void RaiseProcessToHighPriority() { |  612 void RaiseProcessToHighPriority() { | 
|  680   SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); |  613   SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); | 
|  681 } |  614 } | 
|  682  |  615  | 
|  683 }  // namespace base |  616 }  // namespace base | 
| OLD | NEW |