// Copyright (c) 2006-2008 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.

#ifndef SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__
#define SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__

#include <stdint.h>

#include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/sandbox_nt_util.h"

// This header defines the classes that allow the low level policy to select
// the input parameters. In order to better make sense of this header is
// recommended that you check policy_engine_opcodes.h first.

namespace sandbox {

// Models the set of interesting parameters of an intercepted system call
// normally you don't create objects of this class directly, instead you
// use the POLPARAMS_XXX macros.
// For example, if an intercepted function has the following signature:
//
// NTSTATUS NtOpenFileFunction (PHANDLE FileHandle,
//                              ACCESS_MASK DesiredAccess,
//                              POBJECT_ATTRIBUTES ObjectAttributes,
//                              PIO_STATUS_BLOCK IoStatusBlock,
//                              ULONG ShareAccess,
//                              ULONG OpenOptions);
//
// You could say that the following parameters are of interest to policy:
//
//   POLPARAMS_BEGIN(open_params)
//      POLPARAM(DESIRED_ACCESS)
//      POLPARAM(OBJECT_NAME)
//      POLPARAM(SECURITY_DESCRIPTOR)
//      POLPARAM(IO_STATUS)
//      POLPARAM(OPEN_OPTIONS)
//   POLPARAMS_END;
//
// and the actual code will use this for defining the parameters:
//
//   CountedParameterSet<open_params> p;
//   p[open_params::DESIRED_ACCESS] = ParamPickerMake(DesiredAccess);
//   p[open_params::OBJECT_NAME] =
//       ParamPickerMake(ObjectAttributes->ObjectName);
//   p[open_params::SECURITY_DESCRIPTOR] =
//       ParamPickerMake(ObjectAttributes->SecurityDescriptor);
//   p[open_params::IO_STATUS] = ParamPickerMake(IoStatusBlock);
//   p[open_params::OPEN_OPTIONS] = ParamPickerMake(OpenOptions);
//
//  These will create an stack-allocated array of ParameterSet objects which
//  have each 1) the address of the parameter 2) a numeric id that encodes the
//  original C++ type. This allows the policy to treat any set of supported
//  argument types uniformily and with some type safety.
//
//  TODO(cpu): support not fully implemented yet for unicode string and will
//  probably add other types as well.
class ParameterSet {
 public:
  ParameterSet() : real_type_(INVALID_TYPE), address_(NULL) {}

  // Retrieve the stored parameter. If the type does not match ulong fail.
  bool Get(uint32_t* destination) const {
    if (real_type_ != UINT32_TYPE) {
      return false;
    }
    *destination = Void2TypePointerCopy<uint32_t>();
    return true;
  }

  // Retrieve the stored parameter. If the type does not match void* fail.
  bool Get(const void** destination) const {
    if (real_type_ != VOIDPTR_TYPE) {
      return false;
    }
    *destination = Void2TypePointerCopy<void*>();
    return true;
  }

  // Retrieve the stored parameter. If the type does not match wchar_t* fail.
  bool Get(const wchar_t** destination) const {
    if (real_type_ != WCHAR_TYPE) {
      return false;
    }
    *destination = Void2TypePointerCopy<const wchar_t*>();
    return true;
  }

  // False if the parameter is not properly initialized.
  bool IsValid() const {
    return real_type_ != INVALID_TYPE;
  }

 protected:
  // The constructor can only be called by derived types, which should
  // safely provide the real_type and the address of the argument.
  ParameterSet(ArgType real_type, const void* address)
      : real_type_(real_type), address_(address) {
  }

 private:
  // This template provides the same functionality as bits_cast but
  // it works with pointer while the former works only with references.
  template <typename T>
  T Void2TypePointerCopy() const {
    return *(reinterpret_cast<const T*>(address_));
  }

  ArgType real_type_;
  const void* address_;
};

// To safely infer the type, we use a set of template specializations
// in ParameterSetEx with a template function ParamPickerMake to do the
// parameter type deduction.

// Base template class. Not implemented so using unsupported types should
// fail to compile.
template <typename T>
class ParameterSetEx : public ParameterSet {
 public:
  ParameterSetEx(const void* address);
};

template<>
class ParameterSetEx<void const*> : public ParameterSet {
 public:
  ParameterSetEx(const void* address)
      : ParameterSet(VOIDPTR_TYPE, address) {}
};

template<>
class ParameterSetEx<void*> : public ParameterSet {
 public:
  ParameterSetEx(const void* address)
      : ParameterSet(VOIDPTR_TYPE, address) {}
};


template<>
class ParameterSetEx<wchar_t*> : public ParameterSet {
 public:
  ParameterSetEx(const void* address)
      : ParameterSet(WCHAR_TYPE, address) {}
};

template<>
class ParameterSetEx<wchar_t const*> : public ParameterSet {
 public:
  ParameterSetEx(const void* address)
      : ParameterSet(WCHAR_TYPE, address) {}
};

template <>
class ParameterSetEx<uint32_t> : public ParameterSet {
 public:
  ParameterSetEx(const void* address)
      : ParameterSet(UINT32_TYPE, address) {}
};

template<>
class ParameterSetEx<UNICODE_STRING> : public ParameterSet {
 public:
  ParameterSetEx(const void* address)
      : ParameterSet(UNISTR_TYPE, address) {}
};

template <typename T>
ParameterSet ParamPickerMake(T& parameter) {
  return ParameterSetEx<T>(&parameter);
};

struct CountedParameterSetBase {
  int count;
  ParameterSet parameters[1];
};

// This template defines the actual list of policy parameters for a given
// interception.
// Warning: This template stores the address to the actual variables, in
// other words, the values are not copied.
template <typename T>
struct CountedParameterSet {
  CountedParameterSet() : count(T::PolParamLast) {}

  ParameterSet& operator[](typename T::Args n) {
    return parameters[n];
  }

  CountedParameterSetBase* GetBase() {
    return reinterpret_cast<CountedParameterSetBase*>(this);
  }

  int count;
  ParameterSet parameters[T::PolParamLast];
};

}  // namespace sandbox

#endif  // SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__
