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 10 namespace { 11 12 typedef BOOL (WINAPI *InitializeProcThreadAttributeListFunction)( 13 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, 14 DWORD attribute_count, 15 DWORD flags, 16 PSIZE_T size); 17 static InitializeProcThreadAttributeListFunction 18 initialize_proc_thread_attribute_list; 19 20 typedef 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); 28 static UpdateProcThreadAttributeFunction update_proc_thread_attribute_list; 29 30 typedef VOID (WINAPI *DeleteProcThreadAttributeListFunction)( 31 LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList); 32 static DeleteProcThreadAttributeListFunction delete_proc_thread_attribute_list; 33 34 } // namespace 35 36 namespace base { 37 namespace win { 38 39 StartupInformation::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 67 StartupInformation::~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 74 bool 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 97 bool 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