| // Copyright 2017 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "base/win/patch_util.h" | 
 |  | 
 | #include "base/logging.h" | 
 |  | 
 | namespace base { | 
 | namespace win { | 
 | namespace internal { | 
 |  | 
 | DWORD ModifyCode(void* destination, const void* source, int length) { | 
 |   if ((NULL == destination) || (NULL == source) || (0 == length)) { | 
 |     NOTREACHED(); | 
 |     return ERROR_INVALID_PARAMETER; | 
 |   } | 
 |  | 
 |   // Change the page protection so that we can write. | 
 |   MEMORY_BASIC_INFORMATION memory_info; | 
 |   DWORD error = NO_ERROR; | 
 |   DWORD old_page_protection = 0; | 
 |  | 
 |   if (!VirtualQuery(destination, &memory_info, sizeof(memory_info))) { | 
 |     error = GetLastError(); | 
 |     return error; | 
 |   } | 
 |  | 
 |   DWORD is_executable = (PAGE_EXECUTE | PAGE_EXECUTE_READ | | 
 |                          PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) & | 
 |                         memory_info.Protect; | 
 |  | 
 |   if (VirtualProtect(destination, length, | 
 |                      is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, | 
 |                      &old_page_protection)) { | 
 |     // Write the data. | 
 |     CopyMemory(destination, source, length); | 
 |  | 
 |     // Restore the old page protection. | 
 |     error = ERROR_SUCCESS; | 
 |     VirtualProtect(destination, length, old_page_protection, | 
 |                    &old_page_protection); | 
 |   } else { | 
 |     error = GetLastError(); | 
 |   } | 
 |  | 
 |   return error; | 
 | } | 
 |  | 
 | }  // namespace internal | 
 | }  // namespace win | 
 | }  // namespace bsae |