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