<commit_before>// 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 "chrome/browser/chrome_quota_permission_context.h"

#include <string>

#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
#include "chrome/browser/ui/website_settings/permission_bubble_request.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/locale_settings.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/infobars/core/infobar.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/web_contents.h"
#include "grit/theme_resources.h"
#include "net/base/net_util.h"
#include "storage/common/quota/quota_types.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace {

// If the site requested larger quota than this threshold, show a different
// message to the user.
const int64 kRequestLargeQuotaThreshold = 5 * 1024 * 1024;

// QuotaPermissionRequest ---------------------------------------------

class QuotaPermissionRequest : public PermissionBubbleRequest {
 public:
  QuotaPermissionRequest(
      ChromeQuotaPermissionContext* context,
      const GURL& origin_url,
      int64 requested_quota,
      bool user_gesture,
      const std::string& display_languages,
      const content::QuotaPermissionContext::PermissionCallback& callback);

  ~QuotaPermissionRequest() override;

  // PermissionBubbleRequest:
  int GetIconID() const override;
  base::string16 GetMessageText() const override;
  base::string16 GetMessageTextFragment() const override;
  bool HasUserGesture() const override;
  GURL GetRequestingHostname() const override;
  void PermissionGranted() override;
  void PermissionDenied() override;
  void Cancelled() override;
  void RequestFinished() override;

 private:
  scoped_refptr<ChromeQuotaPermissionContext> context_;
  GURL origin_url_;
  std::string display_languages_;
  int64 requested_quota_;
  bool user_gesture_;
  content::QuotaPermissionContext::PermissionCallback callback_;

  DISALLOW_COPY_AND_ASSIGN(QuotaPermissionRequest);
};

QuotaPermissionRequest::QuotaPermissionRequest(
    ChromeQuotaPermissionContext* context,
    const GURL& origin_url,
    int64 requested_quota,
    bool user_gesture,
    const std::string& display_languages,
    const content::QuotaPermissionContext::PermissionCallback& callback)
    : context_(context),
      origin_url_(origin_url),
      display_languages_(display_languages),
      requested_quota_(requested_quota),
      user_gesture_(user_gesture),
      callback_(callback) {}

QuotaPermissionRequest::~QuotaPermissionRequest() {}

int QuotaPermissionRequest::GetIconID() const {
  // TODO(gbillock): get the proper image here
  return IDR_INFOBAR_WARNING;
}

base::string16 QuotaPermissionRequest::GetMessageText() const {
  return l10n_util::GetStringFUTF16(
      (requested_quota_ > kRequestLargeQuotaThreshold ?
          IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
          IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
      net::FormatUrl(origin_url_, display_languages_,
                     net::kFormatUrlOmitUsernamePassword |
                     net::kFormatUrlOmitTrailingSlashOnBareHostname,
                     net::UnescapeRule::SPACES, NULL, NULL, NULL)
  );
}

base::string16 QuotaPermissionRequest::GetMessageTextFragment() const {
  return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT);
}

bool QuotaPermissionRequest::HasUserGesture() const {
  return user_gesture_;
}

GURL QuotaPermissionRequest::GetRequestingHostname() const {
  return origin_url_;
}

void QuotaPermissionRequest::PermissionGranted() {
  context_->DispatchCallbackOnIOThread(
      callback_,
      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
  callback_ = content::QuotaPermissionContext::PermissionCallback();
}

void QuotaPermissionRequest::PermissionDenied() {
  context_->DispatchCallbackOnIOThread(
      callback_,
      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
  callback_ = content::QuotaPermissionContext::PermissionCallback();
}

void QuotaPermissionRequest::Cancelled() {
}

void QuotaPermissionRequest::RequestFinished() {
  if (!callback_.is_null()) {
    context_->DispatchCallbackOnIOThread(
        callback_,
        content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
  }

  delete this;
}

// RequestQuotaInfoBarDelegate ------------------------------------------------

class RequestQuotaInfoBarDelegate : public ConfirmInfoBarDelegate {
 public:
  // Creates a request quota infobar and delegate and adds the infobar to
  // |infobar_service|.
  static void Create(
      InfoBarService* infobar_service,
      ChromeQuotaPermissionContext* context,
      const GURL& origin_url,
      int64 requested_quota,
      const std::string& display_languages,
      const content::QuotaPermissionContext::PermissionCallback& callback);

 private:
  RequestQuotaInfoBarDelegate(
      ChromeQuotaPermissionContext* context,
      const GURL& origin_url,
      int64 requested_quota,
      const std::string& display_languages,
      const content::QuotaPermissionContext::PermissionCallback& callback);
  ~RequestQuotaInfoBarDelegate() override;

  // ConfirmInfoBarDelegate:
  base::string16 GetMessageText() const override;
  bool Accept() override;
  bool Cancel() override;

  scoped_refptr<ChromeQuotaPermissionContext> context_;
  GURL origin_url_;
  std::string display_languages_;
  int64 requested_quota_;
  content::QuotaPermissionContext::PermissionCallback callback_;

  DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
};

// static
void RequestQuotaInfoBarDelegate::Create(
    InfoBarService* infobar_service,
    ChromeQuotaPermissionContext* context,
    const GURL& origin_url,
    int64 requested_quota,
    const std::string& display_languages,
    const content::QuotaPermissionContext::PermissionCallback& callback) {
  infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar(
      scoped_ptr<ConfirmInfoBarDelegate>(new RequestQuotaInfoBarDelegate(
          context, origin_url, requested_quota, display_languages, callback))));
}

RequestQuotaInfoBarDelegate::RequestQuotaInfoBarDelegate(
    ChromeQuotaPermissionContext* context,
    const GURL& origin_url,
    int64 requested_quota,
    const std::string& display_languages,
    const content::QuotaPermissionContext::PermissionCallback& callback)
    : ConfirmInfoBarDelegate(),
      context_(context),
      origin_url_(origin_url),
      display_languages_(display_languages),
      requested_quota_(requested_quota),
      callback_(callback) {
}

RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
  if (!callback_.is_null()) {
    context_->DispatchCallbackOnIOThread(
        callback_,
        content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
  }
}

base::string16 RequestQuotaInfoBarDelegate::GetMessageText() const {
  // If the site requested larger quota than this threshold, show a different
  // message to the user.
  return l10n_util::GetStringFUTF16(
      (requested_quota_ > kRequestLargeQuotaThreshold ?
          IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
          IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
      net::FormatUrl(origin_url_, display_languages_,
                     net::kFormatUrlOmitUsernamePassword |
                     net::kFormatUrlOmitTrailingSlashOnBareHostname,
                     net::UnescapeRule::SPACES, NULL, NULL, NULL)
      );
}

bool RequestQuotaInfoBarDelegate::Accept() {
  context_->DispatchCallbackOnIOThread(
      callback_,
      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
  return true;
}

bool RequestQuotaInfoBarDelegate::Cancel() {
  context_->DispatchCallbackOnIOThread(
      callback_,
      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
  return true;
}

}  // namespace

// ChromeQuotaPermissionContext -----------------------------------------------

ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
}

void ChromeQuotaPermissionContext::RequestQuotaPermission(
    const content::StorageQuotaParams& params,
    int render_process_id,
    const PermissionCallback& callback) {
  if (params.storage_type != storage::kStorageTypePersistent) {
    // For now we only support requesting quota with this interface
    // for Persistent storage type.
    callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
    return;
  }

  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
    content::BrowserThread::PostTask(
        content::BrowserThread::UI, FROM_HERE,
        base::Bind(&ChromeQuotaPermissionContext::RequestQuotaPermission, this,
                   params, render_process_id, callback));
    return;
  }

  content::WebContents* web_contents =
      tab_util::GetWebContentsByID(render_process_id,
                                   params.render_view_id);
  if (!web_contents) {
    // The tab may have gone away or the request may not be from a tab.
    LOG(WARNING) << "Attempt to request quota tabless renderer: "
                 << render_process_id << "," << params.render_view_id;
    DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
    return;
  }

  if (PermissionBubbleManager::Enabled()) {
    PermissionBubbleManager* bubble_manager =
        PermissionBubbleManager::FromWebContents(web_contents);
    if (bubble_manager) {
      bubble_manager->AddRequest(new QuotaPermissionRequest(this,
              params.origin_url, params.requested_size, params.user_gesture,
              Profile::FromBrowserContext(web_contents->GetBrowserContext())->
                  GetPrefs()->GetString(prefs::kAcceptLanguages),
              callback));
    }
    return;
  }

  InfoBarService* infobar_service =
      InfoBarService::FromWebContents(web_contents);
  if (!infobar_service) {
    // The tab has no infobar service.
    LOG(WARNING) << "Attempt to request quota from a background page: "
                 << render_process_id << "," << params.render_view_id;
    DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
    return;
  }
  RequestQuotaInfoBarDelegate::Create(
      infobar_service, this, params.origin_url, params.requested_size,
      Profile::FromBrowserContext(web_contents->GetBrowserContext())->
          GetPrefs()->GetString(prefs::kAcceptLanguages),
      callback);
}

void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
    const PermissionCallback& callback,
    QuotaPermissionResponse response) {
  DCHECK_EQ(false, callback.is_null());

  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
    content::BrowserThread::PostTask(
        content::BrowserThread::IO, FROM_HERE,
        base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
                   this, callback, response));
    return;
  }

  callback.Run(response);
}

ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}
<commit_msg>Don't allow quota requests without an infobar service<commit_after>// 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 "chrome/browser/chrome_quota_permission_context.h"

#include <string>

#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
#include "chrome/browser/ui/website_settings/permission_bubble_request.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/locale_settings.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/infobars/core/infobar.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/web_contents.h"
#include "grit/theme_resources.h"
#include "net/base/net_util.h"
#include "storage/common/quota/quota_types.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace {

// If the site requested larger quota than this threshold, show a different
// message to the user.
const int64 kRequestLargeQuotaThreshold = 5 * 1024 * 1024;

// QuotaPermissionRequest ---------------------------------------------

class QuotaPermissionRequest : public PermissionBubbleRequest {
 public:
  QuotaPermissionRequest(
      ChromeQuotaPermissionContext* context,
      const GURL& origin_url,
      int64 requested_quota,
      bool user_gesture,
      const std::string& display_languages,
      const content::QuotaPermissionContext::PermissionCallback& callback);

  ~QuotaPermissionRequest() override;

  // PermissionBubbleRequest:
  int GetIconID() const override;
  base::string16 GetMessageText() const override;
  base::string16 GetMessageTextFragment() const override;
  bool HasUserGesture() const override;
  GURL GetRequestingHostname() const override;
  void PermissionGranted() override;
  void PermissionDenied() override;
  void Cancelled() override;
  void RequestFinished() override;

 private:
  scoped_refptr<ChromeQuotaPermissionContext> context_;
  GURL origin_url_;
  std::string display_languages_;
  int64 requested_quota_;
  bool user_gesture_;
  content::QuotaPermissionContext::PermissionCallback callback_;

  DISALLOW_COPY_AND_ASSIGN(QuotaPermissionRequest);
};

QuotaPermissionRequest::QuotaPermissionRequest(
    ChromeQuotaPermissionContext* context,
    const GURL& origin_url,
    int64 requested_quota,
    bool user_gesture,
    const std::string& display_languages,
    const content::QuotaPermissionContext::PermissionCallback& callback)
    : context_(context),
      origin_url_(origin_url),
      display_languages_(display_languages),
      requested_quota_(requested_quota),
      user_gesture_(user_gesture),
      callback_(callback) {}

QuotaPermissionRequest::~QuotaPermissionRequest() {}

int QuotaPermissionRequest::GetIconID() const {
  // TODO(gbillock): get the proper image here
  return IDR_INFOBAR_WARNING;
}

base::string16 QuotaPermissionRequest::GetMessageText() const {
  return l10n_util::GetStringFUTF16(
      (requested_quota_ > kRequestLargeQuotaThreshold ?
          IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
          IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
      net::FormatUrl(origin_url_, display_languages_,
                     net::kFormatUrlOmitUsernamePassword |
                     net::kFormatUrlOmitTrailingSlashOnBareHostname,
                     net::UnescapeRule::SPACES, NULL, NULL, NULL)
  );
}

base::string16 QuotaPermissionRequest::GetMessageTextFragment() const {
  return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT);
}

bool QuotaPermissionRequest::HasUserGesture() const {
  return user_gesture_;
}

GURL QuotaPermissionRequest::GetRequestingHostname() const {
  return origin_url_;
}

void QuotaPermissionRequest::PermissionGranted() {
  context_->DispatchCallbackOnIOThread(
      callback_,
      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
  callback_ = content::QuotaPermissionContext::PermissionCallback();
}

void QuotaPermissionRequest::PermissionDenied() {
  context_->DispatchCallbackOnIOThread(
      callback_,
      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
  callback_ = content::QuotaPermissionContext::PermissionCallback();
}

void QuotaPermissionRequest::Cancelled() {
}

void QuotaPermissionRequest::RequestFinished() {
  if (!callback_.is_null()) {
    context_->DispatchCallbackOnIOThread(
        callback_,
        content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
  }

  delete this;
}

// RequestQuotaInfoBarDelegate ------------------------------------------------

class RequestQuotaInfoBarDelegate : public ConfirmInfoBarDelegate {
 public:
  // Creates a request quota infobar and delegate and adds the infobar to
  // |infobar_service|.
  static void Create(
      InfoBarService* infobar_service,
      ChromeQuotaPermissionContext* context,
      const GURL& origin_url,
      int64 requested_quota,
      const std::string& display_languages,
      const content::QuotaPermissionContext::PermissionCallback& callback);

 private:
  RequestQuotaInfoBarDelegate(
      ChromeQuotaPermissionContext* context,
      const GURL& origin_url,
      int64 requested_quota,
      const std::string& display_languages,
      const content::QuotaPermissionContext::PermissionCallback& callback);
  ~RequestQuotaInfoBarDelegate() override;

  // ConfirmInfoBarDelegate:
  base::string16 GetMessageText() const override;
  bool Accept() override;
  bool Cancel() override;

  scoped_refptr<ChromeQuotaPermissionContext> context_;
  GURL origin_url_;
  std::string display_languages_;
  int64 requested_quota_;
  content::QuotaPermissionContext::PermissionCallback callback_;

  DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
};

// static
void RequestQuotaInfoBarDelegate::Create(
    InfoBarService* infobar_service,
    ChromeQuotaPermissionContext* context,
    const GURL& origin_url,
    int64 requested_quota,
    const std::string& display_languages,
    const content::QuotaPermissionContext::PermissionCallback& callback) {
  infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar(
      scoped_ptr<ConfirmInfoBarDelegate>(new RequestQuotaInfoBarDelegate(
          context, origin_url, requested_quota, display_languages, callback))));
}

RequestQuotaInfoBarDelegate::RequestQuotaInfoBarDelegate(
    ChromeQuotaPermissionContext* context,
    const GURL& origin_url,
    int64 requested_quota,
    const std::string& display_languages,
    const content::QuotaPermissionContext::PermissionCallback& callback)
    : ConfirmInfoBarDelegate(),
      context_(context),
      origin_url_(origin_url),
      display_languages_(display_languages),
      requested_quota_(requested_quota),
      callback_(callback) {
}

RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
  if (!callback_.is_null()) {
    context_->DispatchCallbackOnIOThread(
        callback_,
        content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
  }
}

base::string16 RequestQuotaInfoBarDelegate::GetMessageText() const {
  // If the site requested larger quota than this threshold, show a different
  // message to the user.
  return l10n_util::GetStringFUTF16(
      (requested_quota_ > kRequestLargeQuotaThreshold ?
          IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
          IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
      net::FormatUrl(origin_url_, display_languages_,
                     net::kFormatUrlOmitUsernamePassword |
                     net::kFormatUrlOmitTrailingSlashOnBareHostname,
                     net::UnescapeRule::SPACES, NULL, NULL, NULL)
      );
}

bool RequestQuotaInfoBarDelegate::Accept() {
  context_->DispatchCallbackOnIOThread(
      callback_,
      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
  return true;
}

bool RequestQuotaInfoBarDelegate::Cancel() {
  context_->DispatchCallbackOnIOThread(
      callback_,
      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
  return true;
}

}  // namespace

// ChromeQuotaPermissionContext -----------------------------------------------

ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
}

void ChromeQuotaPermissionContext::RequestQuotaPermission(
    const content::StorageQuotaParams& params,
    int render_process_id,
    const PermissionCallback& callback) {
  if (params.storage_type != storage::kStorageTypePersistent) {
    // For now we only support requesting quota with this interface
    // for Persistent storage type.
    callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
    return;
  }

  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
    content::BrowserThread::PostTask(
        content::BrowserThread::UI, FROM_HERE,
        base::Bind(&ChromeQuotaPermissionContext::RequestQuotaPermission, this,
                   params, render_process_id, callback));
    return;
  }

  content::WebContents* web_contents =
      tab_util::GetWebContentsByID(render_process_id,
                                   params.render_view_id);
  if (!web_contents) {
    // The tab may have gone away or the request may not be from a tab.
    LOG(WARNING) << "Attempt to request quota tabless renderer: "
                 << render_process_id << "," << params.render_view_id;
    DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
    return;
  }

  InfoBarService* infobar_service =
      InfoBarService::FromWebContents(web_contents);
  if (!infobar_service) {
    // The tab has no infobar service.
    LOG(WARNING) << "Attempt to request quota from a background page: "
                 << render_process_id << "," << params.render_view_id;
    DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
    return;
  }

  if (PermissionBubbleManager::Enabled()) {
    PermissionBubbleManager* bubble_manager =
        PermissionBubbleManager::FromWebContents(web_contents);
    if (bubble_manager) {
      bubble_manager->AddRequest(new QuotaPermissionRequest(this,
              params.origin_url, params.requested_size, params.user_gesture,
              Profile::FromBrowserContext(web_contents->GetBrowserContext())->
                  GetPrefs()->GetString(prefs::kAcceptLanguages),
              callback));
    }
    return;
  }

  RequestQuotaInfoBarDelegate::Create(
      infobar_service, this, params.origin_url, params.requested_size,
      Profile::FromBrowserContext(web_contents->GetBrowserContext())->
          GetPrefs()->GetString(prefs::kAcceptLanguages),
      callback);
}

void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
    const PermissionCallback& callback,
    QuotaPermissionResponse response) {
  DCHECK_EQ(false, callback.is_null());

  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
    content::BrowserThread::PostTask(
        content::BrowserThread::IO, FROM_HERE,
        base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
                   this, callback, response));
    return;
  }

  callback.Run(response);
}

ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}
<|endoftext|>


<commit_before>// Copyright Joshua Boyce 2010-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is part of HadesMem.
// <http://www.raptorfactor.com/> <raptorfactor@raptorfactor.com>

#include <memory>
#include <string>
#include <vector>
#include <iostream>

#include <hadesmem/detail/warning_disable_prefix.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <hadesmem/detail/warning_disable_suffix.hpp>

#include <hadesmem/error.hpp>
#include <hadesmem/module.hpp>
#include <hadesmem/process.hpp>
#include <hadesmem/injector.hpp>
#include <hadesmem/detail/self_path.hpp>

#include "../common/initialize.hpp"

// TODO: Add support for CreateAndInject.
// TODO: Add support for kAddPathToEnvironment flag.

namespace
{

std::wstring PtrToString(void const* const ptr)
{
  std::wostringstream str;
  str.imbue(std::locale::classic());
  str << std::hex << reinterpret_cast<DWORD_PTR>(ptr);
  return str.str();
}

}

int main()
{
  try
  {
    DisableUserModeCallbackExceptionFilter();
    EnableCrtDebugFlags();
    EnableTerminationOnHeapCorruption();
    EnableBottomUpRand();
    ImbueAllDefault();

    std::cout << "HadesMem Injector\n";

    boost::program_options::options_description opts_desc(
      "General options");
    opts_desc.add_options()
      ("help", "produce help message")
      ("pid", boost::program_options::value<DWORD>(), "process id")
      ("path", boost::program_options::wvalue<std::wstring>(), "module path")
      ("path-resolution", "perform path resolution")
      ("export", boost::program_options::value<std::string>(), "export name")
      ("free", "unload module")
      ("add-path", "add module dir to %PATH%")
      ;

    std::vector<std::wstring> const args = boost::program_options::
      split_winmain(GetCommandLine());
    boost::program_options::variables_map var_map;
    boost::program_options::store(boost::program_options::wcommand_line_parser(
      args).options(opts_desc).run(), var_map);
    boost::program_options::notify(var_map);

    if (var_map.count("help"))
    {
      std::cout << '\n' << opts_desc << '\n';
      return 1;
    }

    if (!var_map.count("pid"))
    {
      std::cerr << "Error! Process ID must be specified.\n";
      return 1;
    }

    if (!var_map.count("path"))
    {
      std::cerr << "Error! Module path must be specified.\n";
      return 1;
    }

    DWORD const pid = var_map["pid"].as<DWORD>();

    try
    {
      hadesmem::GetSeDebugPrivilege();

      std::wcout << "\nAcquired SeDebugPrivilege.\n";
    }
    catch (std::exception const& /*e*/)
    {
      std::wcout << "\nFailed to acquire SeDebugPrivilege.\n";
    }

    hadesmem::Process const process(pid);

    std::wstring const path = var_map["path"].as<std::wstring>();
    bool const path_resolution = var_map.count("path-resolution") != 0;
    bool const add_path = var_map.count("add-path") != 0;

    bool const inject = var_map.count("free") == 0;

    HMODULE module = nullptr;

    if (inject)
    {
      int flags = hadesmem::InjectFlags::kNone;
      if (path_resolution)
      {
        flags |= hadesmem::InjectFlags::kPathResolution;
      }
      if (add_path)
      {
        flags |= hadesmem::InjectFlags::kAddToSearchOrder;
      }

      module = hadesmem::InjectDll(process, path, flags);

      std::wcout << "\nSuccessfully injected module at base address " <<
        PtrToString(module) << ".\n";
    }
    else
    {
      boost::filesystem::path path_real(path);
      if (path_resolution && path_real.is_relative())
      {
        path_real = boost::filesystem::absolute(path_real,
          hadesmem::detail::GetSelfDirPath());
      }
      path_real.make_preferred();

      hadesmem::Module const remote_module(&process, path_real.native());
      module = remote_module.GetHandle();
    }

    if (var_map.count("export"))
    {
      std::string const export_name = var_map["export"].as<std::string>();
      std::pair<DWORD_PTR, DWORD> const export_ret = hadesmem::CallExport(
        process, module, export_name, module);

      std::wcout << "Successfully called module export.\n";
      std::wcout << "Return: " << export_ret.first << ".\n";
      std::wcout << "LastError: " << export_ret.second << ".\n";
    }

    if (!inject)
    {
      hadesmem::FreeDll(process, module);
    }
  }
  catch (std::exception const& e)
  {
    std::cerr << "Error!\n";
    std::cerr << boost::diagnostic_information(e) << "\n";

    return 1;
  }
}
<commit_msg>* Minor cleanup.<commit_after>// Copyright Joshua Boyce 2010-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is part of HadesMem.
// <http://www.raptorfactor.com/> <raptorfactor@raptorfactor.com>

#include <memory>
#include <string>
#include <vector>
#include <iostream>

#include <hadesmem/detail/warning_disable_prefix.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <hadesmem/detail/warning_disable_suffix.hpp>

#include <hadesmem/error.hpp>
#include <hadesmem/module.hpp>
#include <hadesmem/process.hpp>
#include <hadesmem/injector.hpp>
#include <hadesmem/detail/self_path.hpp>

#include "../common/initialize.hpp"

// TODO: Add support for CreateAndInject.

namespace
{

std::wstring PtrToString(void const* const ptr)
{
  std::wostringstream str;
  str.imbue(std::locale::classic());
  str << std::hex << reinterpret_cast<DWORD_PTR>(ptr);
  return str.str();
}

}

int main()
{
  try
  {
    DisableUserModeCallbackExceptionFilter();
    EnableCrtDebugFlags();
    EnableTerminationOnHeapCorruption();
    EnableBottomUpRand();
    ImbueAllDefault();

    std::cout << "HadesMem Injector\n";

    boost::program_options::options_description opts_desc(
      "General options");
    opts_desc.add_options()
      ("help", "produce help message")
      ("pid", boost::program_options::value<DWORD>(), "process id")
      ("module", boost::program_options::wvalue<std::wstring>(), "module path")
      ("path-resolution", "perform path resolution")
      ("export", boost::program_options::value<std::string>(), "export name")
      ("free", "unload module")
      ("add-path", "add module dir to serach order")
      ;

    std::vector<std::wstring> const args = boost::program_options::
      split_winmain(GetCommandLine());
    boost::program_options::variables_map var_map;
    boost::program_options::store(boost::program_options::wcommand_line_parser(
      args).options(opts_desc).run(), var_map);
    boost::program_options::notify(var_map);

    if (var_map.count("help"))
    {
      std::cout << '\n' << opts_desc << '\n';
      return 1;
    }

    if (!var_map.count("pid"))
    {
      std::cerr << "Error! Process ID must be specified.\n";
      return 1;
    }

    if (!var_map.count("path"))
    {
      std::cerr << "Error! Module path must be specified.\n";
      return 1;
    }

    DWORD const pid = var_map["pid"].as<DWORD>();

    try
    {
      hadesmem::GetSeDebugPrivilege();

      std::wcout << "\nAcquired SeDebugPrivilege.\n";
    }
    catch (std::exception const& /*e*/)
    {
      std::wcout << "\nFailed to acquire SeDebugPrivilege.\n";
    }

    hadesmem::Process const process(pid);

    std::wstring const path = var_map["path"].as<std::wstring>();
    bool const path_resolution = var_map.count("path-resolution") != 0;
    bool const add_path = var_map.count("add-path") != 0;

    bool const inject = var_map.count("free") == 0;

    HMODULE module = nullptr;

    if (inject)
    {
      int flags = hadesmem::InjectFlags::kNone;
      if (path_resolution)
      {
        flags |= hadesmem::InjectFlags::kPathResolution;
      }
      if (add_path)
      {
        flags |= hadesmem::InjectFlags::kAddToSearchOrder;
      }

      module = hadesmem::InjectDll(process, path, flags);

      std::wcout << "\nSuccessfully injected module at base address " <<
        PtrToString(module) << ".\n";
    }
    else
    {
      boost::filesystem::path path_real(path);
      if (path_resolution && path_real.is_relative())
      {
        path_real = boost::filesystem::absolute(path_real,
          hadesmem::detail::GetSelfDirPath());
      }
      path_real.make_preferred();

      hadesmem::Module const remote_module(&process, path_real.native());
      module = remote_module.GetHandle();
    }

    if (var_map.count("export"))
    {
      std::string const export_name = var_map["export"].as<std::string>();
      std::pair<DWORD_PTR, DWORD> const export_ret = hadesmem::CallExport(
        process, module, export_name, module);

      std::wcout << "Successfully called module export.\n";
      std::wcout << "Return: " << export_ret.first << ".\n";
      std::wcout << "LastError: " << export_ret.second << ".\n";
    }

    if (!inject)
    {
      hadesmem::FreeDll(process, module);
    }
  }
  catch (std::exception const& e)
  {
    std::cerr << "Error!\n";
    std::cerr << boost::diagnostic_information(e) << "\n";

    return 1;
  }
}
<|endoftext|>


<commit_before>/*
 */

/*
 * Copyright (C) 2015-present ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * SPDX-License-Identifier: (AGPL-3.0-or-later and Apache-2.0)
 */

#pragma once

#include "db/consistency_level_type.hh"
#include "db/write_type.hh"
#include <stdexcept>
#include <seastar/core/sstring.hh>
#include <seastar/core/print.hh>
#include "bytes.hh"

namespace exceptions {

enum class exception_code : int32_t {
    SERVER_ERROR    = 0x0000,
    PROTOCOL_ERROR  = 0x000A,

    BAD_CREDENTIALS = 0x0100,

    // 1xx: problem during request execution
    UNAVAILABLE     = 0x1000,
    OVERLOADED      = 0x1001,
    IS_BOOTSTRAPPING= 0x1002,
    TRUNCATE_ERROR  = 0x1003,
    WRITE_TIMEOUT   = 0x1100,
    READ_TIMEOUT    = 0x1200,
    READ_FAILURE    = 0x1300,
    FUNCTION_FAILURE= 0x1400,
    WRITE_FAILURE   = 0x1500,
    CDC_WRITE_FAILURE = 0x1600,

    // 2xx: problem validating the request
    SYNTAX_ERROR    = 0x2000,
    UNAUTHORIZED    = 0x2100,
    INVALID         = 0x2200,
    CONFIG_ERROR    = 0x2300,
    ALREADY_EXISTS  = 0x2400,
    UNPREPARED      = 0x2500
};

const std::unordered_map<exception_code, sstring>& exception_map();

class cassandra_exception : public std::exception {
private:
    exception_code _code;
    sstring _msg;
protected:
    template<typename... Args>
    static inline sstring prepare_message(const char* fmt, Args&&... args) noexcept {
        try {
            return format(fmt, std::forward<Args>(args)...);
        } catch (...) {
            return sstring();
        }
    }
public:
    cassandra_exception(exception_code code, sstring msg) noexcept
        : _code(code)
        , _msg(std::move(msg))
    { }
    virtual const char* what() const noexcept override { return _msg.c_str(); }
    exception_code code() const { return _code; }
    sstring get_message() const { return what(); }
};

class server_exception : public cassandra_exception {
public:
    server_exception(sstring msg) noexcept
        : exceptions::cassandra_exception{exceptions::exception_code::SERVER_ERROR, std::move(msg)}
    { }
};

class protocol_exception : public cassandra_exception {
public:
    protocol_exception(sstring msg) noexcept
        : exceptions::cassandra_exception{exceptions::exception_code::PROTOCOL_ERROR, std::move(msg)}
    { }
};

struct unavailable_exception : cassandra_exception {
    db::consistency_level consistency;
    int32_t required;
    int32_t alive;

    unavailable_exception(sstring msg, db::consistency_level cl, int32_t required, int32_t alive) noexcept
        : exceptions::cassandra_exception(exceptions::exception_code::UNAVAILABLE, std::move(msg))
        , consistency(cl)
        , required(required)
        , alive(alive)
    {}

    unavailable_exception(db::consistency_level cl, int32_t required, int32_t alive) noexcept
        : unavailable_exception(prepare_message("Cannot achieve consistency level for cl {}. Requires {}, alive {}", cl, required, alive),
                cl, required, alive)
    {}
};

class request_execution_exception : public cassandra_exception {
public:
    request_execution_exception(exception_code code, sstring msg) noexcept
        : cassandra_exception(code, std::move(msg))
    { }
};

class truncate_exception : public request_execution_exception
{
public:
    truncate_exception(std::exception_ptr ep);
};

class request_timeout_exception : public cassandra_exception {
public:
    db::consistency_level consistency;
    int32_t received;
    int32_t block_for;

    request_timeout_exception(exception_code code, const sstring& ks, const sstring& cf, db::consistency_level consistency, int32_t received, int32_t block_for) noexcept
        : cassandra_exception{code, prepare_message("Operation timed out for {}.{} - received only {} responses from {} CL={}.", ks, cf, received, block_for, consistency)}
        , consistency{consistency}
        , received{received}
        , block_for{block_for}
    { }
};

class read_timeout_exception : public request_timeout_exception {
public:
    bool data_present;

    read_timeout_exception(const sstring& ks, const sstring& cf, db::consistency_level consistency, int32_t received, int32_t block_for, bool data_present) noexcept
        : request_timeout_exception{exception_code::READ_TIMEOUT, ks, cf, consistency, received, block_for}
        , data_present{data_present}
    { }
};

struct mutation_write_timeout_exception : public request_timeout_exception {
    db::write_type type;
    mutation_write_timeout_exception(const sstring& ks, const sstring& cf, db::consistency_level consistency, int32_t received, int32_t block_for, db::write_type type) noexcept :
        request_timeout_exception(exception_code::WRITE_TIMEOUT, ks, cf, consistency, received, block_for)
        , type{std::move(type)}
    { }
};

class request_failure_exception : public cassandra_exception {
public:
    db::consistency_level consistency;
    int32_t received;
    int32_t failures;
    int32_t block_for;

protected:
    request_failure_exception(exception_code code, const sstring& ks, const sstring& cf, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_) noexcept
        : cassandra_exception{code, prepare_message("Operation failed for {}.{} - received {} responses and {} failures from {} CL={}.", ks, cf, received_, failures_, block_for_, consistency_)}
        , consistency{consistency_}
        , received{received_}
        , failures{failures_}
        , block_for{block_for_}
    {}

    request_failure_exception(exception_code code, const sstring& msg, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_) noexcept
        : cassandra_exception{code, msg}
        , consistency{consistency_}
        , received{received_}
        , failures{failures_}
        , block_for{block_for_}
    {}
};

struct mutation_write_failure_exception : public request_failure_exception {
    db::write_type type;
    mutation_write_failure_exception(const sstring& ks, const sstring& cf, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_, db::write_type type_) noexcept :
        request_failure_exception(exception_code::WRITE_FAILURE, ks, cf, consistency_, received_, failures_, block_for_)
        , type{std::move(type_)}
    { }

    mutation_write_failure_exception(const sstring& msg, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_, db::write_type type_) noexcept :
        request_failure_exception(exception_code::WRITE_FAILURE, msg, consistency_, received_, failures_, block_for_)
        , type{std::move(type_)}
    { }
};

struct read_failure_exception : public request_failure_exception {
    bool data_present;

    read_failure_exception(const sstring& ks, const sstring& cf, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_, bool data_present_) noexcept
        : request_failure_exception{exception_code::READ_FAILURE, ks, cf, consistency_, received_, failures_, block_for_}
        , data_present{data_present_}
    { }

    read_failure_exception(const sstring& msg, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_, bool data_present_) noexcept
        : request_failure_exception{exception_code::READ_FAILURE, msg, consistency_, received_, failures_, block_for_}
        , data_present{data_present_}
    { }
};

struct overloaded_exception : public cassandra_exception {
    explicit overloaded_exception(size_t c) noexcept :
        cassandra_exception(exception_code::OVERLOADED, prepare_message("Too many in flight hints: {}", c)) {}
    explicit overloaded_exception(sstring msg) noexcept :
        cassandra_exception(exception_code::OVERLOADED, std::move(msg)) {}
};

class request_validation_exception : public cassandra_exception {
public:
    using cassandra_exception::cassandra_exception;
};

class invalidated_prepared_usage_attempt_exception : public exceptions::request_validation_exception {
public:
    invalidated_prepared_usage_attempt_exception() : request_validation_exception{exception_code::UNPREPARED, "Attempt to execute the invalidated prepared statement."} {}
};

class unauthorized_exception: public request_validation_exception {
public:
    unauthorized_exception(sstring msg) noexcept
                    : request_validation_exception(exception_code::UNAUTHORIZED,
                                    std::move(msg)) {
    }
};

class authentication_exception: public request_validation_exception {
public:
    authentication_exception(sstring msg) noexcept
                    : request_validation_exception(exception_code::BAD_CREDENTIALS,
                                    std::move(msg)) {
    }
};

class invalid_request_exception : public request_validation_exception {
public:
    invalid_request_exception(sstring cause) noexcept
        : request_validation_exception(exception_code::INVALID, std::move(cause))
    { }
};

class keyspace_not_defined_exception : public invalid_request_exception {
public:
    keyspace_not_defined_exception(std::string cause) noexcept
        : invalid_request_exception(std::move(cause))
    { }
};

class overflow_error_exception : public invalid_request_exception {
public:
    overflow_error_exception(std::string msg) noexcept
        : invalid_request_exception(std::move(msg))
    { }
};

class prepared_query_not_found_exception : public request_validation_exception {
public:
    bytes id;

    prepared_query_not_found_exception(bytes id) noexcept
        : request_validation_exception{exception_code::UNPREPARED, prepare_message("No prepared statement with ID {} found.", id)}
        , id{id}
    { }
};

class syntax_exception : public request_validation_exception {
public:
    syntax_exception(sstring msg) noexcept
        : request_validation_exception(exception_code::SYNTAX_ERROR, std::move(msg))
    { }
};

class configuration_exception : public request_validation_exception {
public:
    configuration_exception(sstring msg) noexcept
        : request_validation_exception{exception_code::CONFIG_ERROR, std::move(msg)}
    { }

    configuration_exception(exception_code code, sstring msg) noexcept
        : request_validation_exception{code, std::move(msg)}
    { }
};

class already_exists_exception : public configuration_exception {
public:
    const sstring ks_name;
    const sstring cf_name;
private:
    already_exists_exception(sstring ks_name_, sstring cf_name_, sstring msg)
        : configuration_exception{exception_code::ALREADY_EXISTS, msg}
        , ks_name{ks_name_}
        , cf_name{cf_name_}
    { }
public:
    already_exists_exception(sstring ks_name_, sstring cf_name_)
        : already_exists_exception{ks_name_, cf_name_, format("Cannot add already existing table \"{}\" to keyspace \"{}\"", cf_name_, ks_name_)}
    { }

    already_exists_exception(sstring ks_name_)
        : already_exists_exception{ks_name_, "", format("Cannot add existing keyspace \"{}\"", ks_name_)}
    { }
};

class recognition_exception : public std::runtime_error {
public:
    recognition_exception(const std::string& msg) : std::runtime_error(msg) {};
};

class unsupported_operation_exception : public std::runtime_error {
public:
    unsupported_operation_exception() : std::runtime_error("unsupported operation") {}
    unsupported_operation_exception(const sstring& msg) : std::runtime_error("unsupported operation: " + msg) {}
};

class function_execution_exception : public cassandra_exception {
public:
    const sstring ks_name;
    const sstring func_name;
    const std::vector<sstring> args;
    function_execution_exception(sstring func_name_, sstring detail, sstring ks_name_, std::vector<sstring> args_) noexcept
        : cassandra_exception{exception_code::FUNCTION_FAILURE,
            format("execution of {} failed: {}", func_name_, detail)}
        , ks_name(std::move(ks_name_))
        , func_name(std::move(func_name_))
        , args(std::move(args_))
    { }
};

}
<commit_msg>exceptions: add coordinator_exception_container and coordinator_result<commit_after>/*
 */

/*
 * Copyright (C) 2015-present ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * SPDX-License-Identifier: (AGPL-3.0-or-later and Apache-2.0)
 */

#pragma once

#include "db/consistency_level_type.hh"
#include "db/write_type.hh"
#include <stdexcept>
#include <seastar/core/sstring.hh>
#include <seastar/core/print.hh>
#include "bytes.hh"
#include <boost/outcome/result.hpp>
#include "utils/exception_container.hh"
#include "utils/result.hh"

namespace exceptions {

enum class exception_code : int32_t {
    SERVER_ERROR    = 0x0000,
    PROTOCOL_ERROR  = 0x000A,

    BAD_CREDENTIALS = 0x0100,

    // 1xx: problem during request execution
    UNAVAILABLE     = 0x1000,
    OVERLOADED      = 0x1001,
    IS_BOOTSTRAPPING= 0x1002,
    TRUNCATE_ERROR  = 0x1003,
    WRITE_TIMEOUT   = 0x1100,
    READ_TIMEOUT    = 0x1200,
    READ_FAILURE    = 0x1300,
    FUNCTION_FAILURE= 0x1400,
    WRITE_FAILURE   = 0x1500,
    CDC_WRITE_FAILURE = 0x1600,

    // 2xx: problem validating the request
    SYNTAX_ERROR    = 0x2000,
    UNAUTHORIZED    = 0x2100,
    INVALID         = 0x2200,
    CONFIG_ERROR    = 0x2300,
    ALREADY_EXISTS  = 0x2400,
    UNPREPARED      = 0x2500
};

const std::unordered_map<exception_code, sstring>& exception_map();

class cassandra_exception : public std::exception {
private:
    exception_code _code;
    sstring _msg;
protected:
    template<typename... Args>
    static inline sstring prepare_message(const char* fmt, Args&&... args) noexcept {
        try {
            return format(fmt, std::forward<Args>(args)...);
        } catch (...) {
            return sstring();
        }
    }
public:
    cassandra_exception(exception_code code, sstring msg) noexcept
        : _code(code)
        , _msg(std::move(msg))
    { }
    virtual const char* what() const noexcept override { return _msg.c_str(); }
    exception_code code() const { return _code; }
    sstring get_message() const { return what(); }
};

class server_exception : public cassandra_exception {
public:
    server_exception(sstring msg) noexcept
        : exceptions::cassandra_exception{exceptions::exception_code::SERVER_ERROR, std::move(msg)}
    { }
};

class protocol_exception : public cassandra_exception {
public:
    protocol_exception(sstring msg) noexcept
        : exceptions::cassandra_exception{exceptions::exception_code::PROTOCOL_ERROR, std::move(msg)}
    { }
};

struct unavailable_exception : cassandra_exception {
    db::consistency_level consistency;
    int32_t required;
    int32_t alive;

    unavailable_exception(sstring msg, db::consistency_level cl, int32_t required, int32_t alive) noexcept
        : exceptions::cassandra_exception(exceptions::exception_code::UNAVAILABLE, std::move(msg))
        , consistency(cl)
        , required(required)
        , alive(alive)
    {}

    unavailable_exception(db::consistency_level cl, int32_t required, int32_t alive) noexcept
        : unavailable_exception(prepare_message("Cannot achieve consistency level for cl {}. Requires {}, alive {}", cl, required, alive),
                cl, required, alive)
    {}
};

class request_execution_exception : public cassandra_exception {
public:
    request_execution_exception(exception_code code, sstring msg) noexcept
        : cassandra_exception(code, std::move(msg))
    { }
};

class truncate_exception : public request_execution_exception
{
public:
    truncate_exception(std::exception_ptr ep);
};

class request_timeout_exception : public cassandra_exception {
public:
    db::consistency_level consistency;
    int32_t received;
    int32_t block_for;

    request_timeout_exception(exception_code code, const sstring& ks, const sstring& cf, db::consistency_level consistency, int32_t received, int32_t block_for) noexcept
        : cassandra_exception{code, prepare_message("Operation timed out for {}.{} - received only {} responses from {} CL={}.", ks, cf, received, block_for, consistency)}
        , consistency{consistency}
        , received{received}
        , block_for{block_for}
    { }
};

class read_timeout_exception : public request_timeout_exception {
public:
    bool data_present;

    read_timeout_exception(const sstring& ks, const sstring& cf, db::consistency_level consistency, int32_t received, int32_t block_for, bool data_present) noexcept
        : request_timeout_exception{exception_code::READ_TIMEOUT, ks, cf, consistency, received, block_for}
        , data_present{data_present}
    { }
};

struct mutation_write_timeout_exception : public request_timeout_exception {
    db::write_type type;
    mutation_write_timeout_exception(const sstring& ks, const sstring& cf, db::consistency_level consistency, int32_t received, int32_t block_for, db::write_type type) noexcept :
        request_timeout_exception(exception_code::WRITE_TIMEOUT, ks, cf, consistency, received, block_for)
        , type{std::move(type)}
    { }
};

class request_failure_exception : public cassandra_exception {
public:
    db::consistency_level consistency;
    int32_t received;
    int32_t failures;
    int32_t block_for;

protected:
    request_failure_exception(exception_code code, const sstring& ks, const sstring& cf, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_) noexcept
        : cassandra_exception{code, prepare_message("Operation failed for {}.{} - received {} responses and {} failures from {} CL={}.", ks, cf, received_, failures_, block_for_, consistency_)}
        , consistency{consistency_}
        , received{received_}
        , failures{failures_}
        , block_for{block_for_}
    {}

    request_failure_exception(exception_code code, const sstring& msg, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_) noexcept
        : cassandra_exception{code, msg}
        , consistency{consistency_}
        , received{received_}
        , failures{failures_}
        , block_for{block_for_}
    {}
};

struct mutation_write_failure_exception : public request_failure_exception {
    db::write_type type;
    mutation_write_failure_exception(const sstring& ks, const sstring& cf, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_, db::write_type type_) noexcept :
        request_failure_exception(exception_code::WRITE_FAILURE, ks, cf, consistency_, received_, failures_, block_for_)
        , type{std::move(type_)}
    { }

    mutation_write_failure_exception(const sstring& msg, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_, db::write_type type_) noexcept :
        request_failure_exception(exception_code::WRITE_FAILURE, msg, consistency_, received_, failures_, block_for_)
        , type{std::move(type_)}
    { }
};

struct read_failure_exception : public request_failure_exception {
    bool data_present;

    read_failure_exception(const sstring& ks, const sstring& cf, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_, bool data_present_) noexcept
        : request_failure_exception{exception_code::READ_FAILURE, ks, cf, consistency_, received_, failures_, block_for_}
        , data_present{data_present_}
    { }

    read_failure_exception(const sstring& msg, db::consistency_level consistency_, int32_t received_, int32_t failures_, int32_t block_for_, bool data_present_) noexcept
        : request_failure_exception{exception_code::READ_FAILURE, msg, consistency_, received_, failures_, block_for_}
        , data_present{data_present_}
    { }
};

struct overloaded_exception : public cassandra_exception {
    explicit overloaded_exception(size_t c) noexcept :
        cassandra_exception(exception_code::OVERLOADED, prepare_message("Too many in flight hints: {}", c)) {}
    explicit overloaded_exception(sstring msg) noexcept :
        cassandra_exception(exception_code::OVERLOADED, std::move(msg)) {}
};

class request_validation_exception : public cassandra_exception {
public:
    using cassandra_exception::cassandra_exception;
};

class invalidated_prepared_usage_attempt_exception : public exceptions::request_validation_exception {
public:
    invalidated_prepared_usage_attempt_exception() : request_validation_exception{exception_code::UNPREPARED, "Attempt to execute the invalidated prepared statement."} {}
};

class unauthorized_exception: public request_validation_exception {
public:
    unauthorized_exception(sstring msg) noexcept
                    : request_validation_exception(exception_code::UNAUTHORIZED,
                                    std::move(msg)) {
    }
};

class authentication_exception: public request_validation_exception {
public:
    authentication_exception(sstring msg) noexcept
                    : request_validation_exception(exception_code::BAD_CREDENTIALS,
                                    std::move(msg)) {
    }
};

class invalid_request_exception : public request_validation_exception {
public:
    invalid_request_exception(sstring cause) noexcept
        : request_validation_exception(exception_code::INVALID, std::move(cause))
    { }
};

class keyspace_not_defined_exception : public invalid_request_exception {
public:
    keyspace_not_defined_exception(std::string cause) noexcept
        : invalid_request_exception(std::move(cause))
    { }
};

class overflow_error_exception : public invalid_request_exception {
public:
    overflow_error_exception(std::string msg) noexcept
        : invalid_request_exception(std::move(msg))
    { }
};

class prepared_query_not_found_exception : public request_validation_exception {
public:
    bytes id;

    prepared_query_not_found_exception(bytes id) noexcept
        : request_validation_exception{exception_code::UNPREPARED, prepare_message("No prepared statement with ID {} found.", id)}
        , id{id}
    { }
};

class syntax_exception : public request_validation_exception {
public:
    syntax_exception(sstring msg) noexcept
        : request_validation_exception(exception_code::SYNTAX_ERROR, std::move(msg))
    { }
};

class configuration_exception : public request_validation_exception {
public:
    configuration_exception(sstring msg) noexcept
        : request_validation_exception{exception_code::CONFIG_ERROR, std::move(msg)}
    { }

    configuration_exception(exception_code code, sstring msg) noexcept
        : request_validation_exception{code, std::move(msg)}
    { }
};

class already_exists_exception : public configuration_exception {
public:
    const sstring ks_name;
    const sstring cf_name;
private:
    already_exists_exception(sstring ks_name_, sstring cf_name_, sstring msg)
        : configuration_exception{exception_code::ALREADY_EXISTS, msg}
        , ks_name{ks_name_}
        , cf_name{cf_name_}
    { }
public:
    already_exists_exception(sstring ks_name_, sstring cf_name_)
        : already_exists_exception{ks_name_, cf_name_, format("Cannot add already existing table \"{}\" to keyspace \"{}\"", cf_name_, ks_name_)}
    { }

    already_exists_exception(sstring ks_name_)
        : already_exists_exception{ks_name_, "", format("Cannot add existing keyspace \"{}\"", ks_name_)}
    { }
};

class recognition_exception : public std::runtime_error {
public:
    recognition_exception(const std::string& msg) : std::runtime_error(msg) {};
};

class unsupported_operation_exception : public std::runtime_error {
public:
    unsupported_operation_exception() : std::runtime_error("unsupported operation") {}
    unsupported_operation_exception(const sstring& msg) : std::runtime_error("unsupported operation: " + msg) {}
};

class function_execution_exception : public cassandra_exception {
public:
    const sstring ks_name;
    const sstring func_name;
    const std::vector<sstring> args;
    function_execution_exception(sstring func_name_, sstring detail, sstring ks_name_, std::vector<sstring> args_) noexcept
        : cassandra_exception{exception_code::FUNCTION_FAILURE,
            format("execution of {} failed: {}", func_name_, detail)}
        , ks_name(std::move(ks_name_))
        , func_name(std::move(func_name_))
        , args(std::move(args_))
    { }
};

// Allows to pass a coordinator exception as a value. With coordinator_result,
// it is possible to handle exceptions and inspect their type/value without
// resorting to costly rethrows. On the other hand, using them is more
// cumbersome than just using exceptions and exception futures.
//
// Not all exceptions are passed in this way, therefore the container
// does not allow all types of coordinator exceptions. On the other hand,
// an exception being listed here does not mean it is _always_ passed
// in an exception_container - it can be thrown in a regular fashion
// as well.
//
// It is advised to use this mechanism mainly for exceptions which can
// happen frequently, e.g. signalling timeouts, overloads or rate limits.
using coordinator_exception_container = utils::exception_container<
    mutation_write_timeout_exception
>;

template<typename T = void>
using coordinator_result = bo::result<T,
    coordinator_exception_container,
    utils::exception_container_throw_policy
>;

}
<|endoftext|>


<commit_before>// Copyright ***********************************************************
//
// File ecmdJtagUser.C
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 2003
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright *******************************************************
/* $Header$ */

// Module Description **************************************************
//
// Description:
//
// End Module Description **********************************************

//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define ecmdJtagUser_C
#include <ecmdCommandUtils.H>
#include <ecmdReturnCodes.H>
#include <ecmdClientCapi.H>
#include <ecmdUtils.H>
#include <ecmdDataBuffer.H>
#include <ecmdSharedUtils.H>
#include <stdio.h>

#undef ecmdJtagUser_C
//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------

uint32_t ecmdSendCmdUser(int argc, char * argv[]) {
  uint32_t rc = ECMD_SUCCESS;

/*  bool expectFlag = false; */
/*  bool xstateFlag = false; */
  ecmdLooperData looperdata;            ///< Store internal Looper data
  ecmdChipTarget target;                ///< Current target being operated on
  uint32_t instruction;                 ///< Instruction to send to chip
  uint32_t modifier;                    ///< Modifier to send to chip
  ecmdDataBuffer statusBuffer;          ///< Buffer to hold return status data
  bool validPosFound = false;           ///< Did the looper find something to run on?

  /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
  /* get format flag, if it's there */
  std::string format;
  char * formatPtr = ecmdParseOptionWithArgs(&argc, &argv, "-o");
  if (formatPtr == NULL) {
    format = "x";
  }
  else {
    format = formatPtr;
  }
  //Check verbose option
  bool verbose = ecmdParseOption(&argc, &argv, "-v");

  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;

  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  if (argc < 3) {  //chip + instruction + modifier
    ecmdOutputError("sendcmd - Too few arguments specified; you need at least a chip, instruction, and modifier.\n");
    ecmdOutputError("sendcmd - Type 'sendcmd -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }

  //Setup the target that will be used to query the system config
  target.chipType = argv[0];
  target.chipTypeState = ECMD_TARGET_FIELD_VALID;
  target.cageState = target.nodeState = target.slotState = target.posState = ECMD_TARGET_FIELD_WILDCARD;
  target.threadState = target.coreState = ECMD_TARGET_FIELD_UNUSED;

  // we need the instruction and modifier

  if (strlen(argv[1]) > 2) {
    ecmdOutputError("sendcmd - The instruction has to be <= 8 bits\n");
    return ECMD_INVALID_ARGS;
  } else if (!ecmdIsAllHex(argv[1])) {
    ecmdOutputError("sendcmd - Instruction data contained some non-hex characters\n");
    return ECMD_INVALID_ARGS;
  }
  ecmdGenB32FromHexRight(&instruction, argv[1], 32);

  if (strlen(argv[2]) > 6) {
    ecmdOutputError("sendcmd - The modifier has to be <= 24 bits\n");
    return ECMD_INVALID_ARGS;
  } else if (!ecmdIsAllHex(argv[2])) {
    ecmdOutputError("sendcmd - Modifier data contained some non-hex characters\n");
    return ECMD_INVALID_ARGS;
  }
  ecmdGenB32FromHexRight(&modifier, argv[2], 32);

  if (argc > 3) {
    ecmdOutputError("sendcmd - Too many arguments specified; you probably added an option that wasn't recognized.\n");
    ecmdOutputError("sendcmd - Type 'sendcmd -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }

  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP, looperdata);
  if (rc) return rc;
/*  char outstr[30]; */
  std::string printed;

  while ( ecmdConfigLooperNext(target, looperdata) ) {

    rc = sendCmd(target, instruction, modifier, statusBuffer);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc) {
        printed = "sendcmd - Error occured performing sendcmd on ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;
    }

    printed = ecmdWriteTarget(target) + "  ";
    std::string dataStr = ecmdWriteDataFormatted(statusBuffer, format);
    printed += dataStr;
    ecmdOutput( printed.c_str() );

    if ( verbose ) {

     ecmdChipData chipdata;
     rc = ecmdGetChipData (target, chipdata);

     if ( (!rc) && (chipdata.interfaceType == ECMD_INTERFACE_CFAM) ) {
      printed = "\n\t\tInstruction Status Register\n";
      printed += "\t\t---------------------------\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(0, 1) + " Attention Active" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(1, 1) + " Checkstop" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(2, 1) + " Special Attention" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(3, 1) + " Recoverable Error" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(4, 1) + " SCOM Attention" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(5, 1) + " CRC Miscompare on previous data scan-in" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(6, 1) + " Invalid Instruction" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(7, 1) + " PGOOD Indicator(set to '1' by flush, set to '0' by first JTAG instruction)" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(8, 4) + " JTAG Instruction count(Incremented following Shift-IR) Bits(8:11). (Hex Left)" + "\n";

      printed += "\t\t " + statusBuffer.genHexRightStr(12, 1) + " Data scan occured after the last instruction" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(13, 3) + " Reserved Bits(13:15). (Hex Left)" + "\n";

      printed += "\t      " + statusBuffer.genHexRightStr(16,14) + " Clock States(1 = running) Bits(16:29). (Hex Left)" + "\n";

      printed += "\t\t " + statusBuffer.genHexRightStr(30, 1) + " IEEE defined 0"  + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(31, 1) + " IEEE defined 1"  + "\n";
      ecmdOutput(printed.c_str());
    }
    else if (rc) {
      printed = "sendcmd - Error occured performing chipinfo query on ";
      printed += ecmdWriteTarget(target) + "\n";
      ecmdOutputError( printed.c_str() );
      return rc;
    }

   }
  }

  if (!validPosFound) {
    ecmdOutputError("Unable to find a valid chip to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  return rc;
}
<commit_msg>Data in sendcmd -v wasn't properly left aligned as the text said<commit_after>// Copyright ***********************************************************
//
// File ecmdJtagUser.C
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 2003
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright *******************************************************
/* $Header$ */

// Module Description **************************************************
//
// Description:
//
// End Module Description **********************************************

//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define ecmdJtagUser_C
#include <ecmdCommandUtils.H>
#include <ecmdReturnCodes.H>
#include <ecmdClientCapi.H>
#include <ecmdUtils.H>
#include <ecmdDataBuffer.H>
#include <ecmdSharedUtils.H>
#include <stdio.h>

#undef ecmdJtagUser_C
//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------

uint32_t ecmdSendCmdUser(int argc, char * argv[]) {
  uint32_t rc = ECMD_SUCCESS;

/*  bool expectFlag = false; */
/*  bool xstateFlag = false; */
  ecmdLooperData looperdata;            ///< Store internal Looper data
  ecmdChipTarget target;                ///< Current target being operated on
  uint32_t instruction;                 ///< Instruction to send to chip
  uint32_t modifier;                    ///< Modifier to send to chip
  ecmdDataBuffer statusBuffer;          ///< Buffer to hold return status data
  bool validPosFound = false;           ///< Did the looper find something to run on?

  /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
  /* get format flag, if it's there */
  std::string format;
  char * formatPtr = ecmdParseOptionWithArgs(&argc, &argv, "-o");
  if (formatPtr == NULL) {
    format = "x";
  }
  else {
    format = formatPtr;
  }
  //Check verbose option
  bool verbose = ecmdParseOption(&argc, &argv, "-v");

  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;

  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  if (argc < 3) {  //chip + instruction + modifier
    ecmdOutputError("sendcmd - Too few arguments specified; you need at least a chip, instruction, and modifier.\n");
    ecmdOutputError("sendcmd - Type 'sendcmd -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }

  //Setup the target that will be used to query the system config
  target.chipType = argv[0];
  target.chipTypeState = ECMD_TARGET_FIELD_VALID;
  target.cageState = target.nodeState = target.slotState = target.posState = ECMD_TARGET_FIELD_WILDCARD;
  target.threadState = target.coreState = ECMD_TARGET_FIELD_UNUSED;

  // we need the instruction and modifier

  if (strlen(argv[1]) > 2) {
    ecmdOutputError("sendcmd - The instruction has to be <= 8 bits\n");
    return ECMD_INVALID_ARGS;
  } else if (!ecmdIsAllHex(argv[1])) {
    ecmdOutputError("sendcmd - Instruction data contained some non-hex characters\n");
    return ECMD_INVALID_ARGS;
  }
  ecmdGenB32FromHexRight(&instruction, argv[1], 32);

  if (strlen(argv[2]) > 6) {
    ecmdOutputError("sendcmd - The modifier has to be <= 24 bits\n");
    return ECMD_INVALID_ARGS;
  } else if (!ecmdIsAllHex(argv[2])) {
    ecmdOutputError("sendcmd - Modifier data contained some non-hex characters\n");
    return ECMD_INVALID_ARGS;
  }
  ecmdGenB32FromHexRight(&modifier, argv[2], 32);

  if (argc > 3) {
    ecmdOutputError("sendcmd - Too many arguments specified; you probably added an option that wasn't recognized.\n");
    ecmdOutputError("sendcmd - Type 'sendcmd -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }

  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP, looperdata);
  if (rc) return rc;
/*  char outstr[30]; */
  std::string printed;

  while ( ecmdConfigLooperNext(target, looperdata) ) {

    rc = sendCmd(target, instruction, modifier, statusBuffer);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc) {
        printed = "sendcmd - Error occured performing sendcmd on ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;
    }

    printed = ecmdWriteTarget(target) + "  ";
    std::string dataStr = ecmdWriteDataFormatted(statusBuffer, format);
    printed += dataStr;
    ecmdOutput( printed.c_str() );

    if ( verbose ) {

     ecmdChipData chipdata;
     rc = ecmdGetChipData (target, chipdata);

     if ( (!rc) && (chipdata.interfaceType == ECMD_INTERFACE_CFAM) ) {
      printed = "\n\t\tInstruction Status Register\n";
      printed += "\t\t---------------------------\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(0, 1) + " Attention Active" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(1, 1) + " Checkstop" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(2, 1) + " Special Attention" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(3, 1) + " Recoverable Error" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(4, 1) + " SCOM Attention" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(5, 1) + " CRC Miscompare on previous data scan-in" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(6, 1) + " Invalid Instruction" + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(7, 1) + " PGOOD Indicator(set to '1' by flush, set to '0' by first JTAG instruction)" + "\n";
      printed += "\t\t " + statusBuffer.genHexLeftStr(8, 4) + " JTAG Instruction count(Incremented following Shift-IR) Bits(8:11). (Hex Left)" + "\n";

      printed += "\t\t " + statusBuffer.genHexRightStr(12, 1) + " Data scan occured after the last instruction" + "\n";
      printed += "\t\t " + statusBuffer.genHexLeftStr(13, 3) + " Reserved Bits(13:15). (Hex Left)" + "\n";

      printed += "\t      " + statusBuffer.genHexLeftStr(16,14) + " Clock States(1 = running) Bits(16:29). (Hex Left)" + "\n";

      printed += "\t\t " + statusBuffer.genHexRightStr(30, 1) + " IEEE defined 0"  + "\n";
      printed += "\t\t " + statusBuffer.genHexRightStr(31, 1) + " IEEE defined 1"  + "\n";
      ecmdOutput(printed.c_str());
    }
    else if (rc) {
      printed = "sendcmd - Error occured performing chipinfo query on ";
      printed += ecmdWriteTarget(target) + "\n";
      ecmdOutputError( printed.c_str() );
      return rc;
    }

   }
  }

  if (!validPosFound) {
    ecmdOutputError("Unable to find a valid chip to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  return rc;
}
<|endoftext|>