| // 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 |
| |