|  | // 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" | 
|  | #include "base/win/windows_version.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_)); | 
|  |  | 
|  | // Pre Windows Vista doesn't support STARTUPINFOEX. | 
|  | if (base::win::GetVersion() < base::win::VERSION_VISTA) { | 
|  | startup_info_.StartupInfo.cb = sizeof(STARTUPINFO); | 
|  | return; | 
|  | } | 
|  |  | 
|  | 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 | 
|  |  |