1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/win/startup_information.h" 6 7#include "base/logging.h" 8#include "base/win/windows_version.h" 9 10namespace { 11 12typedef BOOL (WINAPI *InitializeProcThreadAttributeListFunction)( 13 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, 14 DWORD attribute_count, 15 DWORD flags, 16 PSIZE_T size); 17static InitializeProcThreadAttributeListFunction 18 initialize_proc_thread_attribute_list; 19 20typedef BOOL (WINAPI *UpdateProcThreadAttributeFunction)( 21 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, 22 DWORD flags, 23 DWORD_PTR attribute, 24 PVOID value, 25 SIZE_T size, 26 PVOID previous_value, 27 PSIZE_T return_size); 28static UpdateProcThreadAttributeFunction update_proc_thread_attribute_list; 29 30typedef VOID (WINAPI *DeleteProcThreadAttributeListFunction)( 31 LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList); 32static DeleteProcThreadAttributeListFunction delete_proc_thread_attribute_list; 33 34} // namespace 35 36namespace base { 37namespace win { 38 39StartupInformation::StartupInformation() { 40 memset(&startup_info_, 0, sizeof(startup_info_)); 41 42 // Pre Windows Vista doesn't support STARTUPINFOEX. 43 if (base::win::GetVersion() < base::win::VERSION_VISTA) { 44 startup_info_.StartupInfo.cb = sizeof(STARTUPINFO); 45 return; 46 } 47 48 startup_info_.StartupInfo.cb = sizeof(startup_info_); 49 50 // Load the attribute API functions. 51 if (!initialize_proc_thread_attribute_list || 52 !update_proc_thread_attribute_list || 53 !delete_proc_thread_attribute_list) { 54 HMODULE module = ::GetModuleHandleW(L"kernel32.dll"); 55 initialize_proc_thread_attribute_list = 56 reinterpret_cast<InitializeProcThreadAttributeListFunction>( 57 ::GetProcAddress(module, "InitializeProcThreadAttributeList")); 58 update_proc_thread_attribute_list = 59 reinterpret_cast<UpdateProcThreadAttributeFunction>( 60 ::GetProcAddress(module, "UpdateProcThreadAttribute")); 61 delete_proc_thread_attribute_list = 62 reinterpret_cast<DeleteProcThreadAttributeListFunction>( 63 ::GetProcAddress(module, "DeleteProcThreadAttributeList")); 64 } 65} 66 67StartupInformation::~StartupInformation() { 68 if (startup_info_.lpAttributeList) { 69 delete_proc_thread_attribute_list(startup_info_.lpAttributeList); 70 delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList); 71 } 72} 73 74bool StartupInformation::InitializeProcThreadAttributeList( 75 DWORD attribute_count) { 76 if (startup_info_.StartupInfo.cb != sizeof(startup_info_) || 77 startup_info_.lpAttributeList) 78 return false; 79 80 SIZE_T size = 0; 81 initialize_proc_thread_attribute_list(NULL, attribute_count, 0, &size); 82 if (size == 0) 83 return false; 84 85 startup_info_.lpAttributeList = 86 reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(new BYTE[size]); 87 if (!initialize_proc_thread_attribute_list(startup_info_.lpAttributeList, 88 attribute_count, 0, &size)) { 89 delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList); 90 startup_info_.lpAttributeList = NULL; 91 return false; 92 } 93 94 return true; 95} 96 97bool StartupInformation::UpdateProcThreadAttribute( 98 DWORD_PTR attribute, 99 void* value, 100 size_t size) { 101 if (!startup_info_.lpAttributeList) 102 return false; 103 return !!update_proc_thread_attribute_list(startup_info_.lpAttributeList, 0, 104 attribute, value, size, NULL, NULL); 105} 106 107} // namespace win 108} // namespace base 109 110