// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/win/startup_information.h"

#include "base/logging.h"

namespace {

typedef BOOL (WINAPI *InitializeProcThreadAttributeListFunction)(
    LPPROC_THREAD_ATTRIBUTE_LIST attribute_list,
    DWORD attribute_count,
    DWORD flags,
    PSIZE_T size);
static InitializeProcThreadAttributeListFunction
    initialize_proc_thread_attribute_list;

typedef BOOL (WINAPI *UpdateProcThreadAttributeFunction)(
    LPPROC_THREAD_ATTRIBUTE_LIST attribute_list,
    DWORD flags,
    DWORD_PTR attribute,
    PVOID value,
    SIZE_T size,
    PVOID previous_value,
    PSIZE_T return_size);
static UpdateProcThreadAttributeFunction update_proc_thread_attribute_list;

typedef VOID (WINAPI *DeleteProcThreadAttributeListFunction)(
    LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList);
static DeleteProcThreadAttributeListFunction delete_proc_thread_attribute_list;

}  // namespace

namespace base {
namespace win {

StartupInformation::StartupInformation() {
  memset(&startup_info_, 0, sizeof(startup_info_));
  startup_info_.StartupInfo.cb = sizeof(startup_info_);

  // Load the attribute API functions.
  if (!initialize_proc_thread_attribute_list ||
      !update_proc_thread_attribute_list ||
      !delete_proc_thread_attribute_list) {
    HMODULE module = ::GetModuleHandleW(L"kernel32.dll");
    initialize_proc_thread_attribute_list =
        reinterpret_cast<InitializeProcThreadAttributeListFunction>(
            ::GetProcAddress(module, "InitializeProcThreadAttributeList"));
    update_proc_thread_attribute_list =
        reinterpret_cast<UpdateProcThreadAttributeFunction>(
            ::GetProcAddress(module, "UpdateProcThreadAttribute"));
    delete_proc_thread_attribute_list =
        reinterpret_cast<DeleteProcThreadAttributeListFunction>(
            ::GetProcAddress(module, "DeleteProcThreadAttributeList"));
  }
}

StartupInformation::~StartupInformation() {
  if (startup_info_.lpAttributeList) {
    delete_proc_thread_attribute_list(startup_info_.lpAttributeList);
    delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList);
  }
}

bool StartupInformation::InitializeProcThreadAttributeList(
    DWORD attribute_count) {
  if (startup_info_.StartupInfo.cb != sizeof(startup_info_) ||
      startup_info_.lpAttributeList)
    return false;

  SIZE_T size = 0;
  initialize_proc_thread_attribute_list(NULL, attribute_count, 0, &size);
  if (size == 0)
    return false;

  startup_info_.lpAttributeList =
      reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(new BYTE[size]);
  if (!initialize_proc_thread_attribute_list(startup_info_.lpAttributeList,
                                           attribute_count, 0, &size)) {
    delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList);
    startup_info_.lpAttributeList = NULL;
    return false;
  }

  return true;
}

bool StartupInformation::UpdateProcThreadAttribute(
    DWORD_PTR attribute,
    void* value,
    size_t size) {
  if (!startup_info_.lpAttributeList)
    return false;
  return !!update_proc_thread_attribute_list(startup_info_.lpAttributeList, 0,
                                       attribute, value, size, NULL, NULL);
}

}  // namespace win
}  // namespace base

