Home | History | Annotate | Download | only in win
      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