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