• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
StartupInformation()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 
~StartupInformation()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 
InitializeProcThreadAttributeList(DWORD attribute_count)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 
UpdateProcThreadAttribute(DWORD_PTR attribute,void * value,size_t size)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