| // Copyright (c) 2012 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/startup_information.h" | 
 |  | 
 | #include "base/logging.h" | 
 |  | 
 | namespace { | 
 |  | 
 | typedef BOOL (WINAPI *InitializeProcThreadAttributeListFunction)( | 
 |     LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, | 
 |     DWORD attribute_count, | 
 |     DWORD flags, | 
 |     PSIZE_T size); | 
 | static InitializeProcThreadAttributeListFunction | 
 |     initialize_proc_thread_attribute_list; | 
 |  | 
 | typedef BOOL (WINAPI *UpdateProcThreadAttributeFunction)( | 
 |     LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, | 
 |     DWORD flags, | 
 |     DWORD_PTR attribute, | 
 |     PVOID value, | 
 |     SIZE_T size, | 
 |     PVOID previous_value, | 
 |     PSIZE_T return_size); | 
 | static UpdateProcThreadAttributeFunction update_proc_thread_attribute_list; | 
 |  | 
 | typedef VOID (WINAPI *DeleteProcThreadAttributeListFunction)( | 
 |     LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList); | 
 | static DeleteProcThreadAttributeListFunction delete_proc_thread_attribute_list; | 
 |  | 
 | }  // namespace | 
 |  | 
 | namespace base { | 
 | namespace win { | 
 |  | 
 | StartupInformation::StartupInformation() { | 
 |   memset(&startup_info_, 0, sizeof(startup_info_)); | 
 |   startup_info_.StartupInfo.cb = sizeof(startup_info_); | 
 |  | 
 |   // Load the attribute API functions. | 
 |   if (!initialize_proc_thread_attribute_list || | 
 |       !update_proc_thread_attribute_list || | 
 |       !delete_proc_thread_attribute_list) { | 
 |     HMODULE module = ::GetModuleHandleW(L"kernel32.dll"); | 
 |     initialize_proc_thread_attribute_list = | 
 |         reinterpret_cast<InitializeProcThreadAttributeListFunction>( | 
 |             ::GetProcAddress(module, "InitializeProcThreadAttributeList")); | 
 |     update_proc_thread_attribute_list = | 
 |         reinterpret_cast<UpdateProcThreadAttributeFunction>( | 
 |             ::GetProcAddress(module, "UpdateProcThreadAttribute")); | 
 |     delete_proc_thread_attribute_list = | 
 |         reinterpret_cast<DeleteProcThreadAttributeListFunction>( | 
 |             ::GetProcAddress(module, "DeleteProcThreadAttributeList")); | 
 |   } | 
 | } | 
 |  | 
 | StartupInformation::~StartupInformation() { | 
 |   if (startup_info_.lpAttributeList) { | 
 |     delete_proc_thread_attribute_list(startup_info_.lpAttributeList); | 
 |     delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList); | 
 |   } | 
 | } | 
 |  | 
 | bool StartupInformation::InitializeProcThreadAttributeList( | 
 |     DWORD attribute_count) { | 
 |   if (startup_info_.StartupInfo.cb != sizeof(startup_info_) || | 
 |       startup_info_.lpAttributeList) | 
 |     return false; | 
 |  | 
 |   SIZE_T size = 0; | 
 |   initialize_proc_thread_attribute_list(NULL, attribute_count, 0, &size); | 
 |   if (size == 0) | 
 |     return false; | 
 |  | 
 |   startup_info_.lpAttributeList = | 
 |       reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(new BYTE[size]); | 
 |   if (!initialize_proc_thread_attribute_list(startup_info_.lpAttributeList, | 
 |                                            attribute_count, 0, &size)) { | 
 |     delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList); | 
 |     startup_info_.lpAttributeList = NULL; | 
 |     return false; | 
 |   } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | bool StartupInformation::UpdateProcThreadAttribute( | 
 |     DWORD_PTR attribute, | 
 |     void* value, | 
 |     size_t size) { | 
 |   if (!startup_info_.lpAttributeList) | 
 |     return false; | 
 |   return !!update_proc_thread_attribute_list(startup_info_.lpAttributeList, 0, | 
 |                                        attribute, value, size, NULL, NULL); | 
 | } | 
 |  | 
 | }  // namespace win | 
 | }  // namespace base | 
 |  |