michael@0: // Copyright (c) 2012 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "base/win/startup_information.h" michael@0: michael@0: #include "base/logging.h" michael@0: #include "base/win/windows_version.h" michael@0: michael@0: namespace { michael@0: michael@0: typedef BOOL (WINAPI *InitializeProcThreadAttributeListFunction)( michael@0: LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, michael@0: DWORD attribute_count, michael@0: DWORD flags, michael@0: PSIZE_T size); michael@0: static InitializeProcThreadAttributeListFunction michael@0: initialize_proc_thread_attribute_list; michael@0: michael@0: typedef BOOL (WINAPI *UpdateProcThreadAttributeFunction)( michael@0: LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, michael@0: DWORD flags, michael@0: DWORD_PTR attribute, michael@0: PVOID value, michael@0: SIZE_T size, michael@0: PVOID previous_value, michael@0: PSIZE_T return_size); michael@0: static UpdateProcThreadAttributeFunction update_proc_thread_attribute_list; michael@0: michael@0: typedef VOID (WINAPI *DeleteProcThreadAttributeListFunction)( michael@0: LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList); michael@0: static DeleteProcThreadAttributeListFunction delete_proc_thread_attribute_list; michael@0: michael@0: } // namespace michael@0: michael@0: namespace base { michael@0: namespace win { michael@0: michael@0: StartupInformation::StartupInformation() { michael@0: memset(&startup_info_, 0, sizeof(startup_info_)); michael@0: michael@0: // Pre Windows Vista doesn't support STARTUPINFOEX. michael@0: if (base::win::GetVersion() < base::win::VERSION_VISTA) { michael@0: startup_info_.StartupInfo.cb = sizeof(STARTUPINFO); michael@0: return; michael@0: } michael@0: michael@0: startup_info_.StartupInfo.cb = sizeof(startup_info_); michael@0: michael@0: // Load the attribute API functions. michael@0: if (!initialize_proc_thread_attribute_list || michael@0: !update_proc_thread_attribute_list || michael@0: !delete_proc_thread_attribute_list) { michael@0: HMODULE module = ::GetModuleHandleW(L"kernel32.dll"); michael@0: initialize_proc_thread_attribute_list = michael@0: reinterpret_cast( michael@0: ::GetProcAddress(module, "InitializeProcThreadAttributeList")); michael@0: update_proc_thread_attribute_list = michael@0: reinterpret_cast( michael@0: ::GetProcAddress(module, "UpdateProcThreadAttribute")); michael@0: delete_proc_thread_attribute_list = michael@0: reinterpret_cast( michael@0: ::GetProcAddress(module, "DeleteProcThreadAttributeList")); michael@0: } michael@0: } michael@0: michael@0: StartupInformation::~StartupInformation() { michael@0: if (startup_info_.lpAttributeList) { michael@0: delete_proc_thread_attribute_list(startup_info_.lpAttributeList); michael@0: delete [] reinterpret_cast(startup_info_.lpAttributeList); michael@0: } michael@0: } michael@0: michael@0: bool StartupInformation::InitializeProcThreadAttributeList( michael@0: DWORD attribute_count) { michael@0: if (startup_info_.StartupInfo.cb != sizeof(startup_info_) || michael@0: startup_info_.lpAttributeList) michael@0: return false; michael@0: michael@0: SIZE_T size = 0; michael@0: initialize_proc_thread_attribute_list(NULL, attribute_count, 0, &size); michael@0: if (size == 0) michael@0: return false; michael@0: michael@0: startup_info_.lpAttributeList = michael@0: reinterpret_cast(new BYTE[size]); michael@0: if (!initialize_proc_thread_attribute_list(startup_info_.lpAttributeList, michael@0: attribute_count, 0, &size)) { michael@0: delete [] reinterpret_cast(startup_info_.lpAttributeList); michael@0: startup_info_.lpAttributeList = NULL; michael@0: return false; michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: bool StartupInformation::UpdateProcThreadAttribute( michael@0: DWORD_PTR attribute, michael@0: void* value, michael@0: size_t size) { michael@0: if (!startup_info_.lpAttributeList) michael@0: return false; michael@0: return !!update_proc_thread_attribute_list(startup_info_.lpAttributeList, 0, michael@0: attribute, value, size, NULL, NULL); michael@0: } michael@0: michael@0: } // namespace win michael@0: } // namespace base michael@0: