<commit_before>// 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.

#include "chrome/test/chrome_plugin/test_chrome_plugin.h"

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/common/chrome_plugin_api.h"
#include "googleurl/src/gurl.h"

static CPID g_cpid;
static CPBrowserFuncs g_cpbrowser_funcs;
static CPRequestFuncs g_cprequest_funcs;
static CPResponseFuncs g_cpresponse_funcs;
static TestFuncParams::BrowserFuncs g_cptest_funcs;

const TestResponsePayload* FindPayload(const char* url) {
  for (int i = 0; i < arraysize(kChromeTestPluginPayloads); ++i) {
    if (strcmp(kChromeTestPluginPayloads[i].url, url) == 0)
      return &kChromeTestPluginPayloads[i];
  }
  return NULL;
}

std::string GetPayloadHeaders(const TestResponsePayload* payload) {
  return StringPrintf(
    "HTTP/1.1 200 OK%c"
    "Content-type: %s%c"
    "%c", 0, payload->mime_type, 0, 0);
}

void STDCALL InvokeLaterCallback(void* data) {
  Task* task = static_cast<Task*>(data);
  task->Run();
  delete task;
}

// ResponseStream: Manages the streaming of the payload data.

class ResponseStream : public base::RefCounted<ResponseStream> {
public:
  ResponseStream(const TestResponsePayload* payload, CPRequest* request);
  ~ResponseStream() {
    request_->pdata = NULL;
  }

  void Init();
  int GetResponseInfo(CPResponseInfoType type, void* buf, uint32 buf_size);
  int ReadData(void* buf, uint32 buf_size);

private:
  // Called asynchronously via InvokeLater.
  void ResponseStarted();
  int ReadCompleted(void* buf, uint32 buf_size);

  enum ReadyStates {
    READY_INVALID = 0,
    READY_WAITING = 1,
    READY_GOT_HEADERS = 2,
    READY_GOT_DATA = 3,
  };
  const TestResponsePayload* payload_;
  uint32 offset_;
  int ready_state_;
  CPRequest* request_;
};

ResponseStream::ResponseStream(const TestResponsePayload* payload,
                               CPRequest* request)
    : payload_(payload), offset_(0), request_(request),
      ready_state_(READY_INVALID) {
}

void ResponseStream::Init() {
  if (payload_->async) {
    // simulate an asynchronous start complete
    ready_state_ = READY_WAITING;
    g_cptest_funcs.invoke_later(
        InvokeLaterCallback,
        // downcast to Task before void, since we upcast from void to Task.
        static_cast<Task*>(
            NewRunnableMethod(this, &ResponseStream::ResponseStarted)),
        500);
  } else {
    ready_state_ = READY_GOT_DATA;
  }
}

int ResponseStream::GetResponseInfo(CPResponseInfoType type, void* buf,
                                    uint32 buf_size) {
  if (ready_state_ < READY_GOT_HEADERS)
    return CPERR_FAILURE;

  switch (type) {
  case CPRESPONSEINFO_HTTP_STATUS:
    if (buf) {
      int status = payload_->status;
      memcpy(buf, &payload_->status, buf_size);
    }
    break;
  case CPRESPONSEINFO_HTTP_RAW_HEADERS: {
    std::string headers = GetPayloadHeaders(payload_);
    if (buf_size < headers.size()+1)
      return static_cast<int>(headers.size()+1);
    if (buf)
      memcpy(buf, headers.c_str(), headers.size()+1);
    break;
    }
  default:
    return CPERR_INVALID_VERSION;
  }

  return CPERR_SUCCESS;
}

int ResponseStream::ReadData(void* buf, uint32 buf_size) {
  if (ready_state_ < READY_GOT_DATA) {
    // simulate an asynchronous read complete
    g_cptest_funcs.invoke_later(
        InvokeLaterCallback,
        // downcast to Task before void, since we upcast from void to Task.
        static_cast<Task*>(
            NewRunnableMethod(this, &ResponseStream::ReadCompleted,
                              buf, buf_size)),
        500);
    return CPERR_IO_PENDING;
  }

  // synchronously complete the read
  return ReadCompleted(buf, buf_size);
}

void ResponseStream::ResponseStarted() {
  ready_state_ = READY_GOT_HEADERS;
  g_cpresponse_funcs.start_completed(request_, CPERR_SUCCESS);
}

int ResponseStream::ReadCompleted(void* buf, uint32 buf_size) {
  uint32 size = static_cast<uint32>(strlen(payload_->body));
  uint32 avail = size - offset_;
  uint32 count = buf_size;
  if (count > avail)
    count = avail;

  if (count) {
    memcpy(buf, payload_->body + offset_, count);
  }

  offset_ += count;

  if (ready_state_ < READY_GOT_DATA) {
    ready_state_ = READY_GOT_DATA;
    g_cpresponse_funcs.read_completed(request_, static_cast<int>(count));
  }

  return count;
}

// CPP Funcs

CPError STDCALL CPP_Shutdown() {
  return CPERR_SUCCESS;
}

CPBool STDCALL CPP_ShouldInterceptRequest(CPRequest* request) {
  DCHECK(StrNCaseCmp(request->url, kChromeTestPluginProtocol,
                     arraysize(kChromeTestPluginProtocol) - 1) == 0);
  return FindPayload(request->url) != NULL;
}

CPError STDCALL CPR_StartRequest(CPRequest* request) {
  const TestResponsePayload* payload = FindPayload(request->url);
  DCHECK(payload);
  ResponseStream* stream = new ResponseStream(payload, request);
  stream->AddRef();  // Released in CPR_EndRequest
  stream->Init();
  request->pdata = stream;
  return payload->async ? CPERR_IO_PENDING : CPERR_SUCCESS;
}

void STDCALL CPR_EndRequest(CPRequest* request, CPError reason) {
  ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
  request->pdata = NULL;
  stream->Release();  // balances AddRef in CPR_StartRequest
}

void STDCALL CPR_SetExtraRequestHeaders(CPRequest* request,
                                        const char* headers) {
  // doesn't affect us
}

void STDCALL CPR_SetRequestLoadFlags(CPRequest* request, uint32 flags) {
  // doesn't affect us
}

void STDCALL CPR_AppendDataToUpload(CPRequest* request, const char* bytes,
                                    int bytes_len) {
  // doesn't affect us
}

CPError STDCALL CPR_AppendFileToUpload(CPRequest* request, const char* filepath,
                                       uint64 offset, uint64 length) {
  // doesn't affect us
  return CPERR_FAILURE;
}

int STDCALL CPR_GetResponseInfo(CPRequest* request, CPResponseInfoType type,
                        void* buf, uint32 buf_size) {
  ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
  return stream->GetResponseInfo(type, buf, buf_size);
}

int STDCALL CPR_Read(CPRequest* request, void* buf, uint32 buf_size) {
  ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
  return stream->ReadData(buf, buf_size);
}

// RequestResponse: manages the retrieval of response data from the host

class RequestResponse {
public:
  RequestResponse(const std::string& raw_headers)
      : raw_headers_(raw_headers), offset_(0) {}
  void StartReading(CPRequest* request);
  void ReadCompleted(CPRequest* request, int bytes_read);

private:
  std::string raw_headers_;
  std::string body_;
  int offset_;
};

void RequestResponse::StartReading(CPRequest* request) {
  int rv = 0;
  const uint32 kReadSize = 4096;
  do {
    body_.resize(offset_ + kReadSize);
    rv = g_cprequest_funcs.read(request, &body_[offset_], kReadSize);
    if (rv > 0)
      offset_ += rv;
  } while (rv > 0);

  if (rv != CPERR_IO_PENDING) {
    // Either an error occurred, or we are done.
    ReadCompleted(request, rv);
  }
}

void RequestResponse::ReadCompleted(CPRequest* request, int bytes_read) {
  if (bytes_read > 0) {
    offset_ += bytes_read;
    StartReading(request);
    return;
  }

  body_.resize(offset_);
  bool success = (bytes_read == 0);
  g_cptest_funcs.test_complete(request, success, raw_headers_, body_);
  g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
  delete this;
}

void STDCALL CPRR_ReceivedRedirect(CPRequest* request, const char* new_url) {
}

void STDCALL CPRR_StartCompleted(CPRequest* request, CPError result) {
  DCHECK(!request->pdata);

  std::string raw_headers;
  int size = g_cprequest_funcs.get_response_info(
      request, CPRESPONSEINFO_HTTP_RAW_HEADERS, NULL, 0);
  int rv = size < 0 ? size : g_cprequest_funcs.get_response_info(
      request, CPRESPONSEINFO_HTTP_RAW_HEADERS,
      WriteInto(&raw_headers, size+1), size);
  if (rv != CPERR_SUCCESS) {
    g_cptest_funcs.test_complete(request, false, std::string(), std::string());
    g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
    return;
  }

  RequestResponse* response = new RequestResponse(raw_headers);
  request->pdata = response;
  response->StartReading(request);
}

void STDCALL CPRR_ReadCompleted(CPRequest* request, int bytes_read) {
  RequestResponse* response =
      reinterpret_cast<RequestResponse*>(request->pdata);
  response->ReadCompleted(request, bytes_read);
}

int STDCALL CPT_MakeRequest(const char* method, const GURL& url) {
  CPRequest* request = NULL;
  if (g_cpbrowser_funcs.create_request(g_cpid, NULL, method, url.spec().c_str(),
                                       &request) != CPERR_SUCCESS ||
      !request) {
    return CPERR_FAILURE;
  }

  g_cprequest_funcs.set_request_load_flags(request,
                                           CPREQUESTLOAD_DISABLE_INTERCEPT);

  if (strcmp(method, "POST") == 0) {
    g_cprequest_funcs.set_extra_request_headers(
        request, "Content-Type: text/plain");
    g_cprequest_funcs.append_data_to_upload(
        request, kChromeTestPluginPostData,
        arraysize(kChromeTestPluginPostData) - 1);
  }

  int rv = g_cprequest_funcs.start_request(request);
  if (rv == CPERR_SUCCESS) {
    CPRR_StartCompleted(request, CPERR_SUCCESS);
  } else if (rv != CPERR_IO_PENDING) {
    g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
    return CPERR_FAILURE;
  }

  return CPERR_SUCCESS;
}

// DLL entry points

CPError STDCALL CP_Initialize(CPID id, const CPBrowserFuncs* bfuncs,
                              CPPluginFuncs* pfuncs) {
  if (bfuncs == NULL || pfuncs == NULL)
    return CPERR_FAILURE;

  if (CP_GET_MAJOR_VERSION(bfuncs->version) > CP_MAJOR_VERSION)
    return CPERR_INVALID_VERSION;

  if (bfuncs->size < sizeof(CPBrowserFuncs) ||
      pfuncs->size < sizeof(CPPluginFuncs))
    return CPERR_INVALID_VERSION;

  pfuncs->version = CP_VERSION;
  pfuncs->shutdown = CPP_Shutdown;
  pfuncs->should_intercept_request = CPP_ShouldInterceptRequest;

  static CPRequestFuncs request_funcs;
  request_funcs.start_request = CPR_StartRequest;
  request_funcs.end_request = CPR_EndRequest;
  request_funcs.set_extra_request_headers = CPR_SetExtraRequestHeaders;
  request_funcs.set_request_load_flags = CPR_SetRequestLoadFlags;
  request_funcs.append_data_to_upload = CPR_AppendDataToUpload;
  request_funcs.get_response_info = CPR_GetResponseInfo;
  request_funcs.read = CPR_Read;
  request_funcs.append_file_to_upload = CPR_AppendFileToUpload;
  pfuncs->request_funcs = &request_funcs;

  static CPResponseFuncs response_funcs;
  response_funcs.received_redirect = CPRR_ReceivedRedirect;
  response_funcs.start_completed = CPRR_StartCompleted;
  response_funcs.read_completed = CPRR_ReadCompleted;
  pfuncs->response_funcs = &response_funcs;

  g_cpid = id;
  g_cpbrowser_funcs = *bfuncs;
  g_cprequest_funcs = *bfuncs->request_funcs;
  g_cpresponse_funcs = *bfuncs->response_funcs;
  g_cpbrowser_funcs = *bfuncs;

  const char* protocols[] = {kChromeTestPluginProtocol};
  g_cpbrowser_funcs.enable_request_intercept(g_cpid, protocols, 1);
  return CPERR_SUCCESS;
}

int STDCALL CP_Test(void* vparam) {
  TestFuncParams* param = reinterpret_cast<TestFuncParams*>(vparam);
  param->pfuncs.test_make_request = CPT_MakeRequest;

  g_cptest_funcs = param->bfuncs;
  return CPERR_SUCCESS;
}

<commit_msg>Add an AtExitManager to test_chrome_plugin.  It uses Time::Now(), which now uses a Singleton. Review URL: http://codereview.chromium.org/1843<commit_after>// 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.

#include "chrome/test/chrome_plugin/test_chrome_plugin.h"

#include "base/at_exit.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/common/chrome_plugin_api.h"
#include "googleurl/src/gurl.h"

static CPID g_cpid;
static CPBrowserFuncs g_cpbrowser_funcs;
static CPRequestFuncs g_cprequest_funcs;
static CPResponseFuncs g_cpresponse_funcs;
static TestFuncParams::BrowserFuncs g_cptest_funcs;

// Create a global AtExitManager so that our code can use code from base that
// uses Singletons, for example.  We don't care about static constructors here.
static base::AtExitManager global_at_exit_manager;

const TestResponsePayload* FindPayload(const char* url) {
  for (int i = 0; i < arraysize(kChromeTestPluginPayloads); ++i) {
    if (strcmp(kChromeTestPluginPayloads[i].url, url) == 0)
      return &kChromeTestPluginPayloads[i];
  }
  return NULL;
}

std::string GetPayloadHeaders(const TestResponsePayload* payload) {
  return StringPrintf(
    "HTTP/1.1 200 OK%c"
    "Content-type: %s%c"
    "%c", 0, payload->mime_type, 0, 0);
}

void STDCALL InvokeLaterCallback(void* data) {
  Task* task = static_cast<Task*>(data);
  task->Run();
  delete task;
}

// ResponseStream: Manages the streaming of the payload data.

class ResponseStream : public base::RefCounted<ResponseStream> {
public:
  ResponseStream(const TestResponsePayload* payload, CPRequest* request);
  ~ResponseStream() {
    request_->pdata = NULL;
  }

  void Init();
  int GetResponseInfo(CPResponseInfoType type, void* buf, uint32 buf_size);
  int ReadData(void* buf, uint32 buf_size);

private:
  // Called asynchronously via InvokeLater.
  void ResponseStarted();
  int ReadCompleted(void* buf, uint32 buf_size);

  enum ReadyStates {
    READY_INVALID = 0,
    READY_WAITING = 1,
    READY_GOT_HEADERS = 2,
    READY_GOT_DATA = 3,
  };
  const TestResponsePayload* payload_;
  uint32 offset_;
  int ready_state_;
  CPRequest* request_;
};

ResponseStream::ResponseStream(const TestResponsePayload* payload,
                               CPRequest* request)
    : payload_(payload), offset_(0), request_(request),
      ready_state_(READY_INVALID) {
}

void ResponseStream::Init() {
  if (payload_->async) {
    // simulate an asynchronous start complete
    ready_state_ = READY_WAITING;
    g_cptest_funcs.invoke_later(
        InvokeLaterCallback,
        // downcast to Task before void, since we upcast from void to Task.
        static_cast<Task*>(
            NewRunnableMethod(this, &ResponseStream::ResponseStarted)),
        500);
  } else {
    ready_state_ = READY_GOT_DATA;
  }
}

int ResponseStream::GetResponseInfo(CPResponseInfoType type, void* buf,
                                    uint32 buf_size) {
  if (ready_state_ < READY_GOT_HEADERS)
    return CPERR_FAILURE;

  switch (type) {
  case CPRESPONSEINFO_HTTP_STATUS:
    if (buf) {
      int status = payload_->status;
      memcpy(buf, &payload_->status, buf_size);
    }
    break;
  case CPRESPONSEINFO_HTTP_RAW_HEADERS: {
    std::string headers = GetPayloadHeaders(payload_);
    if (buf_size < headers.size()+1)
      return static_cast<int>(headers.size()+1);
    if (buf)
      memcpy(buf, headers.c_str(), headers.size()+1);
    break;
    }
  default:
    return CPERR_INVALID_VERSION;
  }

  return CPERR_SUCCESS;
}

int ResponseStream::ReadData(void* buf, uint32 buf_size) {
  if (ready_state_ < READY_GOT_DATA) {
    // simulate an asynchronous read complete
    g_cptest_funcs.invoke_later(
        InvokeLaterCallback,
        // downcast to Task before void, since we upcast from void to Task.
        static_cast<Task*>(
            NewRunnableMethod(this, &ResponseStream::ReadCompleted,
                              buf, buf_size)),
        500);
    return CPERR_IO_PENDING;
  }

  // synchronously complete the read
  return ReadCompleted(buf, buf_size);
}

void ResponseStream::ResponseStarted() {
  ready_state_ = READY_GOT_HEADERS;
  g_cpresponse_funcs.start_completed(request_, CPERR_SUCCESS);
}

int ResponseStream::ReadCompleted(void* buf, uint32 buf_size) {
  uint32 size = static_cast<uint32>(strlen(payload_->body));
  uint32 avail = size - offset_;
  uint32 count = buf_size;
  if (count > avail)
    count = avail;

  if (count) {
    memcpy(buf, payload_->body + offset_, count);
  }

  offset_ += count;

  if (ready_state_ < READY_GOT_DATA) {
    ready_state_ = READY_GOT_DATA;
    g_cpresponse_funcs.read_completed(request_, static_cast<int>(count));
  }

  return count;
}

// CPP Funcs

CPError STDCALL CPP_Shutdown() {
  return CPERR_SUCCESS;
}

CPBool STDCALL CPP_ShouldInterceptRequest(CPRequest* request) {
  DCHECK(StrNCaseCmp(request->url, kChromeTestPluginProtocol,
                     arraysize(kChromeTestPluginProtocol) - 1) == 0);
  return FindPayload(request->url) != NULL;
}

CPError STDCALL CPR_StartRequest(CPRequest* request) {
  const TestResponsePayload* payload = FindPayload(request->url);
  DCHECK(payload);
  ResponseStream* stream = new ResponseStream(payload, request);
  stream->AddRef();  // Released in CPR_EndRequest
  stream->Init();
  request->pdata = stream;
  return payload->async ? CPERR_IO_PENDING : CPERR_SUCCESS;
}

void STDCALL CPR_EndRequest(CPRequest* request, CPError reason) {
  ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
  request->pdata = NULL;
  stream->Release();  // balances AddRef in CPR_StartRequest
}

void STDCALL CPR_SetExtraRequestHeaders(CPRequest* request,
                                        const char* headers) {
  // doesn't affect us
}

void STDCALL CPR_SetRequestLoadFlags(CPRequest* request, uint32 flags) {
  // doesn't affect us
}

void STDCALL CPR_AppendDataToUpload(CPRequest* request, const char* bytes,
                                    int bytes_len) {
  // doesn't affect us
}

CPError STDCALL CPR_AppendFileToUpload(CPRequest* request, const char* filepath,
                                       uint64 offset, uint64 length) {
  // doesn't affect us
  return CPERR_FAILURE;
}

int STDCALL CPR_GetResponseInfo(CPRequest* request, CPResponseInfoType type,
                        void* buf, uint32 buf_size) {
  ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
  return stream->GetResponseInfo(type, buf, buf_size);
}

int STDCALL CPR_Read(CPRequest* request, void* buf, uint32 buf_size) {
  ResponseStream* stream = static_cast<ResponseStream*>(request->pdata);
  return stream->ReadData(buf, buf_size);
}

// RequestResponse: manages the retrieval of response data from the host

class RequestResponse {
public:
  RequestResponse(const std::string& raw_headers)
      : raw_headers_(raw_headers), offset_(0) {}
  void StartReading(CPRequest* request);
  void ReadCompleted(CPRequest* request, int bytes_read);

private:
  std::string raw_headers_;
  std::string body_;
  int offset_;
};

void RequestResponse::StartReading(CPRequest* request) {
  int rv = 0;
  const uint32 kReadSize = 4096;
  do {
    body_.resize(offset_ + kReadSize);
    rv = g_cprequest_funcs.read(request, &body_[offset_], kReadSize);
    if (rv > 0)
      offset_ += rv;
  } while (rv > 0);

  if (rv != CPERR_IO_PENDING) {
    // Either an error occurred, or we are done.
    ReadCompleted(request, rv);
  }
}

void RequestResponse::ReadCompleted(CPRequest* request, int bytes_read) {
  if (bytes_read > 0) {
    offset_ += bytes_read;
    StartReading(request);
    return;
  }

  body_.resize(offset_);
  bool success = (bytes_read == 0);
  g_cptest_funcs.test_complete(request, success, raw_headers_, body_);
  g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
  delete this;
}

void STDCALL CPRR_ReceivedRedirect(CPRequest* request, const char* new_url) {
}

void STDCALL CPRR_StartCompleted(CPRequest* request, CPError result) {
  DCHECK(!request->pdata);

  std::string raw_headers;
  int size = g_cprequest_funcs.get_response_info(
      request, CPRESPONSEINFO_HTTP_RAW_HEADERS, NULL, 0);
  int rv = size < 0 ? size : g_cprequest_funcs.get_response_info(
      request, CPRESPONSEINFO_HTTP_RAW_HEADERS,
      WriteInto(&raw_headers, size+1), size);
  if (rv != CPERR_SUCCESS) {
    g_cptest_funcs.test_complete(request, false, std::string(), std::string());
    g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
    return;
  }

  RequestResponse* response = new RequestResponse(raw_headers);
  request->pdata = response;
  response->StartReading(request);
}

void STDCALL CPRR_ReadCompleted(CPRequest* request, int bytes_read) {
  RequestResponse* response =
      reinterpret_cast<RequestResponse*>(request->pdata);
  response->ReadCompleted(request, bytes_read);
}

int STDCALL CPT_MakeRequest(const char* method, const GURL& url) {
  CPRequest* request = NULL;
  if (g_cpbrowser_funcs.create_request(g_cpid, NULL, method, url.spec().c_str(),
                                       &request) != CPERR_SUCCESS ||
      !request) {
    return CPERR_FAILURE;
  }

  g_cprequest_funcs.set_request_load_flags(request,
                                           CPREQUESTLOAD_DISABLE_INTERCEPT);

  if (strcmp(method, "POST") == 0) {
    g_cprequest_funcs.set_extra_request_headers(
        request, "Content-Type: text/plain");
    g_cprequest_funcs.append_data_to_upload(
        request, kChromeTestPluginPostData,
        arraysize(kChromeTestPluginPostData) - 1);
  }

  int rv = g_cprequest_funcs.start_request(request);
  if (rv == CPERR_SUCCESS) {
    CPRR_StartCompleted(request, CPERR_SUCCESS);
  } else if (rv != CPERR_IO_PENDING) {
    g_cprequest_funcs.end_request(request, CPERR_CANCELLED);
    return CPERR_FAILURE;
  }

  return CPERR_SUCCESS;
}

// DLL entry points

CPError STDCALL CP_Initialize(CPID id, const CPBrowserFuncs* bfuncs,
                              CPPluginFuncs* pfuncs) {
  if (bfuncs == NULL || pfuncs == NULL)
    return CPERR_FAILURE;

  if (CP_GET_MAJOR_VERSION(bfuncs->version) > CP_MAJOR_VERSION)
    return CPERR_INVALID_VERSION;

  if (bfuncs->size < sizeof(CPBrowserFuncs) ||
      pfuncs->size < sizeof(CPPluginFuncs))
    return CPERR_INVALID_VERSION;

  pfuncs->version = CP_VERSION;
  pfuncs->shutdown = CPP_Shutdown;
  pfuncs->should_intercept_request = CPP_ShouldInterceptRequest;

  static CPRequestFuncs request_funcs;
  request_funcs.start_request = CPR_StartRequest;
  request_funcs.end_request = CPR_EndRequest;
  request_funcs.set_extra_request_headers = CPR_SetExtraRequestHeaders;
  request_funcs.set_request_load_flags = CPR_SetRequestLoadFlags;
  request_funcs.append_data_to_upload = CPR_AppendDataToUpload;
  request_funcs.get_response_info = CPR_GetResponseInfo;
  request_funcs.read = CPR_Read;
  request_funcs.append_file_to_upload = CPR_AppendFileToUpload;
  pfuncs->request_funcs = &request_funcs;

  static CPResponseFuncs response_funcs;
  response_funcs.received_redirect = CPRR_ReceivedRedirect;
  response_funcs.start_completed = CPRR_StartCompleted;
  response_funcs.read_completed = CPRR_ReadCompleted;
  pfuncs->response_funcs = &response_funcs;

  g_cpid = id;
  g_cpbrowser_funcs = *bfuncs;
  g_cprequest_funcs = *bfuncs->request_funcs;
  g_cpresponse_funcs = *bfuncs->response_funcs;
  g_cpbrowser_funcs = *bfuncs;

  const char* protocols[] = {kChromeTestPluginProtocol};
  g_cpbrowser_funcs.enable_request_intercept(g_cpid, protocols, 1);
  return CPERR_SUCCESS;
}

int STDCALL CP_Test(void* vparam) {
  TestFuncParams* param = reinterpret_cast<TestFuncParams*>(vparam);
  param->pfuncs.test_make_request = CPT_MakeRequest;

  g_cptest_funcs = param->bfuncs;
  return CPERR_SUCCESS;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fieldmappingpage.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-06 18:38:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#ifndef EXTENSIONS_ABP_FIELDMAPPINGPAGE_HXX
#include "fieldmappingpage.hxx"
#endif
#ifndef EXTENSIONS_ABP_FIELDMAPPINGIMPL_HXX
#include "fieldmappingimpl.hxx"
#endif
#ifndef EXTENSIONS_ABP_ADDRESSSETTINGS_HXX
#include "addresssettings.hxx"
#endif
#ifndef EXTENSIONS_ABSPILOT_HXX
#include "abspilot.hxx"
#endif

//.........................................................................
namespace abp
{
//.........................................................................

    //=====================================================================
    //= FieldMappingPage
    //=====================================================================
    //---------------------------------------------------------------------
    FieldMappingPage::FieldMappingPage( OAddessBookSourcePilot* _pParent )
        :AddressBookSourcePage( _pParent, ModuleRes( RID_PAGE_FIELDMAPPING ) )
        ,m_aExplanation     ( this, ModuleRes( FT_FIELDASSIGMENTEXPL ) )
        ,m_aInvokeDialog    ( this, ModuleRes( PB_INVOKE_FIELDS_DIALOG ) )
        ,m_aHint            ( this, ModuleRes( FT_ASSIGNEDFIELDS ) )
    {
        FreeResource();

        m_aInvokeDialog.SetClickHdl( LINK( this, FieldMappingPage, OnInvokeDialog ) );

        // check the size of the InvokeDialog button - some languages are very ... gossipy here ....
        // 96349 - 09.01.2002 - fs@openoffice.org
        sal_Int32 nTextWidth = m_aInvokeDialog.GetTextWidth( m_aInvokeDialog.GetText() );

        sal_Int32 nBorderSpace = m_aInvokeDialog.LogicToPixel( Point( 4, 0 ), MAP_APPFONT ).X();
        sal_Int32 nSpace = m_aInvokeDialog.GetOutputSizePixel().Width() - 2 * nBorderSpace;

        if ( nSpace < nTextWidth )
        {
            Size aButtonSize = m_aInvokeDialog.GetSizePixel();
            aButtonSize.Width() += nTextWidth - nSpace;
            m_aInvokeDialog.SetSizePixel( aButtonSize );
        }
    }

    //---------------------------------------------------------------------
    void FieldMappingPage::ActivatePage()
    {
        AddressBookSourcePage::ActivatePage();
        m_aInvokeDialog.GrabFocus();
    }

    //---------------------------------------------------------------------
    void FieldMappingPage::DeactivatePage()
    {
        AddressBookSourcePage::DeactivatePage();
    }

    //---------------------------------------------------------------------
    void FieldMappingPage::initializePage()
    {
        AddressBookSourcePage::initializePage();
        implUpdateHint();
    }

    //---------------------------------------------------------------------
    void FieldMappingPage::implUpdateHint()
    {
        const AddressSettings& rSettings = getSettings();
        String sHint;
        if ( 0 == rSettings.aFieldMapping.size() )
            sHint = String( ModuleRes( RID_STR_NOFIELDSASSIGNED ) );
        m_aHint.SetText( sHint );
    }

    //---------------------------------------------------------------------
    IMPL_LINK( FieldMappingPage, OnInvokeDialog, void*, /*NOTINTERESTEDIN*/ )
    {
        AddressSettings& rSettings = getSettings();

        // invoke the dialog doing the mapping
        if ( fieldmapping::invokeDialog( getORB(), this, getDialog()->getDataSource().getDataSource(), rSettings ) )
        {
            if ( rSettings.aFieldMapping.size() )
                getDialog()->travelNext();
            else
                implUpdateHint();
        }

        return 0L;
    }

//.........................................................................
}   // namespace abp
//.........................................................................

<commit_msg>INTEGRATION: CWS changefileheader (1.12.14); FILE MERGED 2008/04/01 12:29:40 thb 1.12.14.2: #i85898# Stripping all external header guards 2008/03/31 12:31:20 rt 1.12.14.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: fieldmappingpage.cxx,v $
 * $Revision: 1.13 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"
#include "fieldmappingpage.hxx"
#include "fieldmappingimpl.hxx"
#include "addresssettings.hxx"
#include "abspilot.hxx"

//.........................................................................
namespace abp
{
//.........................................................................

    //=====================================================================
    //= FieldMappingPage
    //=====================================================================
    //---------------------------------------------------------------------
    FieldMappingPage::FieldMappingPage( OAddessBookSourcePilot* _pParent )
        :AddressBookSourcePage( _pParent, ModuleRes( RID_PAGE_FIELDMAPPING ) )
        ,m_aExplanation     ( this, ModuleRes( FT_FIELDASSIGMENTEXPL ) )
        ,m_aInvokeDialog    ( this, ModuleRes( PB_INVOKE_FIELDS_DIALOG ) )
        ,m_aHint            ( this, ModuleRes( FT_ASSIGNEDFIELDS ) )
    {
        FreeResource();

        m_aInvokeDialog.SetClickHdl( LINK( this, FieldMappingPage, OnInvokeDialog ) );

        // check the size of the InvokeDialog button - some languages are very ... gossipy here ....
        // 96349 - 09.01.2002 - fs@openoffice.org
        sal_Int32 nTextWidth = m_aInvokeDialog.GetTextWidth( m_aInvokeDialog.GetText() );

        sal_Int32 nBorderSpace = m_aInvokeDialog.LogicToPixel( Point( 4, 0 ), MAP_APPFONT ).X();
        sal_Int32 nSpace = m_aInvokeDialog.GetOutputSizePixel().Width() - 2 * nBorderSpace;

        if ( nSpace < nTextWidth )
        {
            Size aButtonSize = m_aInvokeDialog.GetSizePixel();
            aButtonSize.Width() += nTextWidth - nSpace;
            m_aInvokeDialog.SetSizePixel( aButtonSize );
        }
    }

    //---------------------------------------------------------------------
    void FieldMappingPage::ActivatePage()
    {
        AddressBookSourcePage::ActivatePage();
        m_aInvokeDialog.GrabFocus();
    }

    //---------------------------------------------------------------------
    void FieldMappingPage::DeactivatePage()
    {
        AddressBookSourcePage::DeactivatePage();
    }

    //---------------------------------------------------------------------
    void FieldMappingPage::initializePage()
    {
        AddressBookSourcePage::initializePage();
        implUpdateHint();
    }

    //---------------------------------------------------------------------
    void FieldMappingPage::implUpdateHint()
    {
        const AddressSettings& rSettings = getSettings();
        String sHint;
        if ( 0 == rSettings.aFieldMapping.size() )
            sHint = String( ModuleRes( RID_STR_NOFIELDSASSIGNED ) );
        m_aHint.SetText( sHint );
    }

    //---------------------------------------------------------------------
    IMPL_LINK( FieldMappingPage, OnInvokeDialog, void*, /*NOTINTERESTEDIN*/ )
    {
        AddressSettings& rSettings = getSettings();

        // invoke the dialog doing the mapping
        if ( fieldmapping::invokeDialog( getORB(), this, getDialog()->getDataSource().getDataSource(), rSettings ) )
        {
            if ( rSettings.aFieldMapping.size() )
                getDialog()->travelNext();
            else
                implUpdateHint();
        }

        return 0L;
    }

//.........................................................................
}   // namespace abp
//.........................................................................

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ldapuserprof.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-15 14:14:09 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef EXTENSIONS_CONFIG_LDAP_LDAPUSERPROF_HXX_
#define EXTENSIONS_CONFIG_LDAP_LDAPUSERPROF_HXX_

#ifdef WITH_OPENLDAP
#include <ldap.h>
#else
#ifndef LDAP_INCLUDED
#define LDAP_INCLUDED
#include <ldap/ldap.h>
#endif // LDAP_INCLUDED
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif // _RTL_USTRING_HXX_

#ifndef _RTL_STRING_HXX_
#include <rtl/string.hxx>
#endif // _RTL_STRING_HXX_

#ifndef VECTOR_INCLUDED
#define VECTOR_INCLUDED
#include <vector>
#endif // VECTOR_INCLUDED

#ifndef SET_INCLUDED
#define SET_INCLUDED
#include <set>
#endif // SET_INCLUDED

namespace extensions { namespace config { namespace ldap {

/** Struct containing the data associated to a UserProfile */
struct LdapUserProfile {
    /** Struct defining an entry in the profile */
    struct ProfileEntry {
        rtl::OUString mAttribute ;
        rtl::OUString mValue ;
    } ;
    /** List of attribute/value pairs */
    std::vector<ProfileEntry> mProfile ;

    typedef std::vector<ProfileEntry>::const_iterator Iterator;
} ;

/** Provider of UserProfile mapping services */
class LdapUserProfileMap
{
    public :
        /** Default constructor, doesn't do much. */
        LdapUserProfileMap() : mAttributes(NULL) {}
        /** Destructor */
        ~LdapUserProfileMap() ;

        /**
          Fills the map using a string description of the mapping.
          Each possible UserProfile attribute is mapped to a list
          of LDAP attributes, in order of priority.
          The entry is formatted as:
          <UP Attribute>=<LDAP Attr1>,...,<LDAP AttrN>

          @param aMap   string description of the mapping
          */
        void source(const rtl::OString& aMap) ;
        /**
          Returns an array of all the LDAP attribute names that may
          be relevant for UserProfile mapping.

          @return   array of LDAP attribute names
          */
        const sal_Char **getLdapAttributes(void) const { return mAttributes ; }
          /**
          Returns the component name that holds the data
          when presented to the outside.

          @return component name
          */
        const rtl::OUString& getComponentName(void) const {
            return mComponentName ;
        }
        /**
          Returns the group name that holds the data when
          presented to the outside world.

          @return   group name
          */
        const rtl::OUString& getGroupName(void) const {
            return mGroupName ;
        }
        /**
          Struct defining the mapping between UserProfile attributes
          and LDAP ones. It also serves as a crude "schema" of the
          UserProfile component, as the list of profile elements
          is the list of properties in the component and the presence
          or absence of LDAP mapping indicates whether the property
          should be made writable or kept read-only.
          */
        struct Mapping {
            /** Name of the UserProfile element */
            rtl::OString mProfileElement ;
            /** Corresponding LDAP attributes in order of priority */
            std::vector<rtl::OString> mLdapAttributes ;

            /** Utility to fill the mapping from a <Prof>=<Ldap1>;...;<LdapN>
                description */
            sal_Bool parse(const rtl::OString& aDescription) ;
        } ;

        /**
          Maps an LDAP entry to a UserProfile.

          @param aConnection    LDAP connection to the repository
          @param aEntry         entry containing the data
          @param aProfile       user profile struct to fill up
          */
        void ldapToUserProfile(LDAP *aConnection,
                               LDAPMessage *aEntry,
                               LdapUserProfile& aProfile) const ;

    private :
        /** Contains the mapping entries */
        std::vector<Mapping> mMapping ;
        /** Contains the LDAP attributes used in a NULL terminated array */
        const sal_Char **mAttributes ;
        /** User profile component name */
        rtl::OUString mComponentName ;
        /** User profile storage group name */
        rtl::OUString mGroupName ;

        /**
          Adds a new mapping entry to the list, and collects the
          LDAP attributes involved in the mapping.

          @param aMappingDescription    string describing the mapping
          @param aLdapAttributes        collection of LDAP attributes
          @param aPrefix                common prefix to the attributes
                                        containing the component and group
                                        name, used for validation
         */
        void addNewMapping(const rtl::OString& aMappingDescription,
                           std::set<rtl::OString>& aLdapAttributes,
                           rtl::OString& aPrefix) ;
} ;

} } } // extensions.config.ldap

#endif // EXTENSIONS_CONFIG_LDAP_LDAPUSERPROF_HXX_
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.172); FILE MERGED 2005/09/05 12:58:52 rt 1.4.172.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ldapuserprof.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:23:22 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef EXTENSIONS_CONFIG_LDAP_LDAPUSERPROF_HXX_
#define EXTENSIONS_CONFIG_LDAP_LDAPUSERPROF_HXX_

#ifdef WITH_OPENLDAP
#include <ldap.h>
#else
#ifndef LDAP_INCLUDED
#define LDAP_INCLUDED
#include <ldap/ldap.h>
#endif // LDAP_INCLUDED
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif // _RTL_USTRING_HXX_

#ifndef _RTL_STRING_HXX_
#include <rtl/string.hxx>
#endif // _RTL_STRING_HXX_

#ifndef VECTOR_INCLUDED
#define VECTOR_INCLUDED
#include <vector>
#endif // VECTOR_INCLUDED

#ifndef SET_INCLUDED
#define SET_INCLUDED
#include <set>
#endif // SET_INCLUDED

namespace extensions { namespace config { namespace ldap {

/** Struct containing the data associated to a UserProfile */
struct LdapUserProfile {
    /** Struct defining an entry in the profile */
    struct ProfileEntry {
        rtl::OUString mAttribute ;
        rtl::OUString mValue ;
    } ;
    /** List of attribute/value pairs */
    std::vector<ProfileEntry> mProfile ;

    typedef std::vector<ProfileEntry>::const_iterator Iterator;
} ;

/** Provider of UserProfile mapping services */
class LdapUserProfileMap
{
    public :
        /** Default constructor, doesn't do much. */
        LdapUserProfileMap() : mAttributes(NULL) {}
        /** Destructor */
        ~LdapUserProfileMap() ;

        /**
          Fills the map using a string description of the mapping.
          Each possible UserProfile attribute is mapped to a list
          of LDAP attributes, in order of priority.
          The entry is formatted as:
          <UP Attribute>=<LDAP Attr1>,...,<LDAP AttrN>

          @param aMap   string description of the mapping
          */
        void source(const rtl::OString& aMap) ;
        /**
          Returns an array of all the LDAP attribute names that may
          be relevant for UserProfile mapping.

          @return   array of LDAP attribute names
          */
        const sal_Char **getLdapAttributes(void) const { return mAttributes ; }
          /**
          Returns the component name that holds the data
          when presented to the outside.

          @return component name
          */
        const rtl::OUString& getComponentName(void) const {
            return mComponentName ;
        }
        /**
          Returns the group name that holds the data when
          presented to the outside world.

          @return   group name
          */
        const rtl::OUString& getGroupName(void) const {
            return mGroupName ;
        }
        /**
          Struct defining the mapping between UserProfile attributes
          and LDAP ones. It also serves as a crude "schema" of the
          UserProfile component, as the list of profile elements
          is the list of properties in the component and the presence
          or absence of LDAP mapping indicates whether the property
          should be made writable or kept read-only.
          */
        struct Mapping {
            /** Name of the UserProfile element */
            rtl::OString mProfileElement ;
            /** Corresponding LDAP attributes in order of priority */
            std::vector<rtl::OString> mLdapAttributes ;

            /** Utility to fill the mapping from a <Prof>=<Ldap1>;...;<LdapN>
                description */
            sal_Bool parse(const rtl::OString& aDescription) ;
        } ;

        /**
          Maps an LDAP entry to a UserProfile.

          @param aConnection    LDAP connection to the repository
          @param aEntry         entry containing the data
          @param aProfile       user profile struct to fill up
          */
        void ldapToUserProfile(LDAP *aConnection,
                               LDAPMessage *aEntry,
                               LdapUserProfile& aProfile) const ;

    private :
        /** Contains the mapping entries */
        std::vector<Mapping> mMapping ;
        /** Contains the LDAP attributes used in a NULL terminated array */
        const sal_Char **mAttributes ;
        /** User profile component name */
        rtl::OUString mComponentName ;
        /** User profile storage group name */
        rtl::OUString mGroupName ;

        /**
          Adds a new mapping entry to the list, and collects the
          LDAP attributes involved in the mapping.

          @param aMappingDescription    string describing the mapping
          @param aLdapAttributes        collection of LDAP attributes
          @param aPrefix                common prefix to the attributes
                                        containing the component and group
                                        name, used for validation
         */
        void addNewMapping(const rtl::OString& aMappingDescription,
                           std::set<rtl::OString>& aLdapAttributes,
                           rtl::OString& aPrefix) ;
} ;

} } } // extensions.config.ldap

#endif // EXTENSIONS_CONFIG_LDAP_LDAPUSERPROF_HXX_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: formcontroller.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2006-03-14 11:23:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef EXTENSIONS_SOURCE_PROPCTRLR_FORMCONTROLLER_HXX
#define EXTENSIONS_SOURCE_PROPCTRLR_FORMCONTROLLER_HXX

#ifndef _EXTENSIONS_PROPCTRLR_PROPCONTROLLER_HXX_
#include "propcontroller.hxx"
#endif

/** === begin UNO includes === **/
/** === end UNO includes === **/

#ifndef _CPPUHELPER_PROPSHLP_HXX
#include <cppuhelper/propshlp.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
#include <comphelper/proparrhlp.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

//........................................................................
namespace pcr
{
//........................................................................

    //====================================================================
    //= ServiceDescriptor
    //====================================================================
    struct ServiceDescriptor
    {
        ::rtl::OUString
            ( *GetImplementationName )( void );
        ::com::sun::star::uno::Sequence< ::rtl::OUString >
            ( *GetSupportedServiceNames )( void );
    };

    //====================================================================
    //= FormController
    //====================================================================
    class FormController;
    typedef ::cppu::OPropertySetHelper                                  FormController_PropertyBase1;
    typedef ::comphelper::OPropertyArrayUsageHelper< FormController >   FormController_PropertyBase2;

    /** Legacy implementation of com.sun.star.form.PropertyBrowserController

        Nowadays only a wrapper around an ObjectInspector using a
        DefaultFormComponentInspectorModel.
    */
    class FormController    :public OPropertyBrowserController
                            ,public FormController_PropertyBase1
                            ,public FormController_PropertyBase2
    {
    private:
        ServiceDescriptor           m_aServiceDescriptor;
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
                                    m_xCurrentInspectee;
        bool                        m_bUseFormComponentHandlers;
    public:
        FormController(
            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext,
            ServiceDescriptor _aServiceDescriptor,
            bool _bUseFormFormComponentHandlers
        );

        // XServiceInfo - static versions
        static ::rtl::OUString getImplementationName_static(  ) throw(::com::sun::star::uno::RuntimeException);
        static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(  ) throw(::com::sun::star::uno::RuntimeException);
        static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
                        Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);

    protected:
        ~FormController();

        DECLARE_XINTERFACE()
        DECLARE_XTYPEPROVIDER()

        // XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);

        // XPropertySet and friends
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
        virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;

        virtual sal_Bool SAL_CALL convertFastPropertyValue(
                ::com::sun::star::uno::Any & rConvertedValue, ::com::sun::star::uno::Any & rOldValue, sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue
            )   throw (::com::sun::star::lang::IllegalArgumentException);
        virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
                sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue
            ) throw (::com::sun::star::uno::Exception);
        virtual void SAL_CALL getFastPropertyValue(
                ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle
            ) const;
    };

    //====================================================================
    //= DialogController
    //====================================================================
    /** Legacy implementation of com.sun.star.awt.PropertyBrowserController
    */
    class DialogController
    {
    public:
        // XServiceInfo - static versions
        static ::rtl::OUString getImplementationName_static(  ) throw(::com::sun::star::uno::RuntimeException);
        static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(  ) throw(::com::sun::star::uno::RuntimeException);
        static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
                        Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);

    private:
        DialogController();                                     // never implemented
        DialogController( const DialogController& );            // never implemented
        DialogController& operator=( const DialogController& ); // never implemented
    };
//........................................................................
} // namespace pcr
//........................................................................

#endif // EXTENSIONS_SOURCE_PROPCTRLR_FORMCONTROLLER_HXX

<commit_msg>INTEGRATION: CWS wae4extensions (1.2.296); FILE MERGED 2007/09/27 07:18:25 fs 1.2.296.1: #i81612# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: formcontroller.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: ihi $ $Date: 2008-01-14 14:58:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef EXTENSIONS_SOURCE_PROPCTRLR_FORMCONTROLLER_HXX
#define EXTENSIONS_SOURCE_PROPCTRLR_FORMCONTROLLER_HXX

#ifndef _EXTENSIONS_PROPCTRLR_PROPCONTROLLER_HXX_
#include "propcontroller.hxx"
#endif

/** === begin UNO includes === **/
/** === end UNO includes === **/

#ifndef _CPPUHELPER_PROPSHLP_HXX
#include <cppuhelper/propshlp.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
#include <comphelper/proparrhlp.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

//........................................................................
namespace pcr
{
//........................................................................

    //====================================================================
    //= ServiceDescriptor
    //====================================================================
    struct ServiceDescriptor
    {
        ::rtl::OUString
            ( *GetImplementationName )( void );
        ::com::sun::star::uno::Sequence< ::rtl::OUString >
            ( *GetSupportedServiceNames )( void );
    };

    //====================================================================
    //= FormController
    //====================================================================
    class FormController;
    typedef ::cppu::OPropertySetHelper                                  FormController_PropertyBase1;
    typedef ::comphelper::OPropertyArrayUsageHelper< FormController >   FormController_PropertyBase2;

    /** Legacy implementation of com.sun.star.form.PropertyBrowserController

        Nowadays only a wrapper around an ObjectInspector using a
        DefaultFormComponentInspectorModel.
    */
    class FormController    :public OPropertyBrowserController
                            ,public FormController_PropertyBase1
                            ,public FormController_PropertyBase2
    {
    private:
        ServiceDescriptor           m_aServiceDescriptor;
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
                                    m_xCurrentInspectee;
        bool                        m_bUseFormComponentHandlers;
    public:
        FormController(
            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext,
            ServiceDescriptor _aServiceDescriptor,
            bool _bUseFormFormComponentHandlers
        );

        // XServiceInfo - static versions
        static ::rtl::OUString getImplementationName_static(  ) throw(::com::sun::star::uno::RuntimeException);
        static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(  ) throw(::com::sun::star::uno::RuntimeException);
        static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
                        Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);

    protected:
        ~FormController();

        DECLARE_XINTERFACE()
        DECLARE_XTYPEPROVIDER()

        // XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);

        // XPropertySet and friends
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
        virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;

        virtual sal_Bool SAL_CALL convertFastPropertyValue(
                ::com::sun::star::uno::Any & rConvertedValue, ::com::sun::star::uno::Any & rOldValue, sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue
            )   throw (::com::sun::star::lang::IllegalArgumentException);
        virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
                sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue
            ) throw (::com::sun::star::uno::Exception);
        virtual void SAL_CALL getFastPropertyValue(
                ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle
            ) const;
    private:
        using FormController_PropertyBase1::getFastPropertyValue;
    };

    //====================================================================
    //= DialogController
    //====================================================================
    /** Legacy implementation of com.sun.star.awt.PropertyBrowserController
    */
    class DialogController
    {
    public:
        // XServiceInfo - static versions
        static ::rtl::OUString getImplementationName_static(  ) throw(::com::sun::star::uno::RuntimeException);
        static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(  ) throw(::com::sun::star::uno::RuntimeException);
        static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
                        Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);

    private:
        DialogController();                                     // never implemented
        DialogController( const DialogController& );            // never implemented
        DialogController& operator=( const DialogController& ); // never implemented
    };
//........................................................................
} // namespace pcr
//........................................................................

#endif // EXTENSIONS_SOURCE_PROPCTRLR_FORMCONTROLLER_HXX

<|endoftext|>


<commit_before>// Copyright 2013 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.
//
// Implementation of NtMapViewOfSection intercept for 32 bit builds.
//
// TODO(robertshield): Implement the 64 bit intercept.

#include "chrome_elf/blacklist/blacklist_interceptions.h"

#include <string>
#include <vector>

// Note that only #includes from base that are either header-only or built into
// base_static (see base/base.gyp) are allowed here.
#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "base/win/pe_image.h"
#include "chrome_elf/blacklist/blacklist.h"
#include "chrome_elf/breakpad.h"
#include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sandbox_types.h"

namespace {

NtQuerySectionFunction g_nt_query_section_func = NULL;
NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func = NULL;
NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func = NULL;

// TODO(robertshield): Merge with ntdll exports cache.
FARPROC GetNtDllExportByName(const char* export_name) {
  HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName);
  return ::GetProcAddress(ntdll, export_name);
}

int DllMatch(const base::string16& module_name) {
  for (int i = 0; blacklist::g_troublesome_dlls[i] != NULL; ++i) {
    if (_wcsicmp(module_name.c_str(), blacklist::g_troublesome_dlls[i]) == 0)
      return i;
  }
  return -1;
}

// TODO(robertshield): Some of the helper functions below overlap somewhat with
// code in sandbox_nt_util.cc. See if they can be unified.

// Native reimplementation of PSAPIs GetMappedFileName.
base::string16 GetBackingModuleFilePath(PVOID address) {
  DCHECK_NT(g_nt_query_virtual_memory_func);

  // We'll start with something close to max_path characters for the name.
  ULONG buffer_bytes = MAX_PATH * 2;
  std::vector<BYTE> buffer_data(buffer_bytes);

  for (;;) {
    MEMORY_SECTION_NAME* section_name =
        reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]);

    if (!section_name)
      break;

    ULONG returned_bytes;
    NTSTATUS ret = g_nt_query_virtual_memory_func(
        NtCurrentProcess, address, MemorySectionName, section_name,
        buffer_bytes, &returned_bytes);

    if (STATUS_BUFFER_OVERFLOW == ret) {
      // Retry the call with the given buffer size.
      buffer_bytes = returned_bytes + 1;
      buffer_data.resize(buffer_bytes);
      section_name = NULL;
      continue;
    }
    if (!NT_SUCCESS(ret))
      break;

    UNICODE_STRING* section_string =
        reinterpret_cast<UNICODE_STRING*>(section_name);
    return base::string16(section_string->Buffer,
                          section_string->Length / sizeof(wchar_t));
  }

  return base::string16();
}

bool IsModuleValidImageSection(HANDLE section,
                               PVOID *base,
                               PLARGE_INTEGER offset,
                               PSIZE_T view_size) {
  DCHECK_NT(g_nt_query_section_func);

  if (!section || !base || !view_size || offset)
    return false;

  SECTION_BASIC_INFORMATION basic_info;
  SIZE_T bytes_returned;
  NTSTATUS ret = g_nt_query_section_func(section, SectionBasicInformation,
                                         &basic_info, sizeof(basic_info),
                                         &bytes_returned);

  if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned)
    return false;

  if (!(basic_info.Attributes & SEC_IMAGE))
    return false;

  return true;
}

base::string16 ExtractLoadedModuleName(const base::string16& module_path) {
  if (module_path.empty() || module_path[module_path.size() - 1] == L'\\')
    return base::string16();

  size_t sep = module_path.find_last_of(L'\\');
  if (sep == base::string16::npos)
    return module_path;
  else
    return module_path.substr(sep+1);
}

// Fills |out_name| with the image name from the given |pe| image and |flags|
// with additional info about the image.
void SafeGetImageInfo(const base::win::PEImage& pe,
                      std::string* out_name,
                      uint32* flags) {
  out_name->clear();
  out_name->reserve(MAX_PATH);
  *flags = 0;
  __try {
    if (pe.VerifyMagic()) {
      *flags |= sandbox::MODULE_IS_PE_IMAGE;

      PIMAGE_EXPORT_DIRECTORY exports = pe.GetExportDirectory();
      if (exports) {
        const char* image_name = reinterpret_cast<const char*>(
            pe.RVAToAddr(exports->Name));
        size_t i = 0;
        for (; i < MAX_PATH && *image_name; ++i, ++image_name)
          out_name->push_back(*image_name);
      }

      PIMAGE_NT_HEADERS headers = pe.GetNTHeaders();
      if (headers) {
        if (headers->OptionalHeader.AddressOfEntryPoint)
          *flags |= sandbox::MODULE_HAS_ENTRY_POINT;
        if (headers->OptionalHeader.SizeOfCode)
          *flags |= sandbox::MODULE_HAS_CODE;
      }
    }
  } __except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
              GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR) ?
             EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    out_name->clear();
  }
}

base::string16 GetImageInfoFromLoadedModule(HMODULE module, uint32* flags) {
  std::string out_name;
  base::win::PEImage pe(module);
  SafeGetImageInfo(pe, &out_name, flags);
  return base::string16(out_name.begin(), out_name.end());
}

bool IsSameAsCurrentProcess(HANDLE process) {
  return  (NtCurrentProcess == process) ||
          (::GetProcessId(process) == ::GetCurrentProcessId());
}

NTSTATUS BlNtMapViewOfSectionImpl(
    NtMapViewOfSectionFunction orig_MapViewOfSection,
    HANDLE section,
    HANDLE process,
    PVOID *base,
    ULONG_PTR zero_bits,
    SIZE_T commit_size,
    PLARGE_INTEGER offset,
    PSIZE_T view_size,
    SECTION_INHERIT inherit,
    ULONG allocation_type,
    ULONG protect) {
  NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits,
                                       commit_size, offset, view_size, inherit,
                                       allocation_type, protect);

  if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) ||
      !IsModuleValidImageSection(section, base, offset, view_size)) {
    return ret;
  }

  HMODULE module = reinterpret_cast<HMODULE>(*base);
  if (module) {
    UINT image_flags;

    base::string16 module_name(GetImageInfoFromLoadedModule(
        reinterpret_cast<HMODULE>(*base), &image_flags));
    base::string16 file_name(GetBackingModuleFilePath(*base));

    if (module_name.empty() && (image_flags & sandbox::MODULE_HAS_CODE)) {
      // If the module has no exports we retrieve the module name from the
      // full path of the mapped section.
      module_name = ExtractLoadedModuleName(file_name);
    }

    if (!module_name.empty()) {
      int blocked_index = DllMatch(module_name);
      if (blocked_index != -1) {
        DCHECK_NT(g_nt_unmap_view_of_section_func);
        g_nt_unmap_view_of_section_func(process, *base);
        ret = STATUS_UNSUCCESSFUL;

        blacklist::BlockedDll(blocked_index);
      }
    }
  }

  return ret;
}

}  // namespace

namespace blacklist {

bool InitializeInterceptImports() {
  g_nt_query_section_func =
      reinterpret_cast<NtQuerySectionFunction>(
          GetNtDllExportByName("NtQuerySection"));
  g_nt_query_virtual_memory_func =
      reinterpret_cast<NtQueryVirtualMemoryFunction>(
          GetNtDllExportByName("NtQueryVirtualMemory"));
  g_nt_unmap_view_of_section_func =
      reinterpret_cast<NtUnmapViewOfSectionFunction>(
          GetNtDllExportByName("NtUnmapViewOfSection"));

  return (g_nt_query_section_func && g_nt_query_virtual_memory_func &&
          g_nt_unmap_view_of_section_func);
}

SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection(
    NtMapViewOfSectionFunction orig_MapViewOfSection,
    HANDLE section,
    HANDLE process,
    PVOID *base,
    ULONG_PTR zero_bits,
    SIZE_T commit_size,
    PLARGE_INTEGER offset,
    PSIZE_T view_size,
    SECTION_INHERIT inherit,
    ULONG allocation_type,
    ULONG protect) {
  NTSTATUS ret = STATUS_UNSUCCESSFUL;

  __try {
    ret = BlNtMapViewOfSectionImpl(orig_MapViewOfSection, section, process,
                                   base, zero_bits, commit_size, offset,
                                   view_size, inherit, allocation_type,
                                   protect);
  } __except(GenerateCrashDump(GetExceptionInformation())) {
  }

  return ret;
}

#if defined(_WIN64)
NTSTATUS WINAPI BlNtMapViewOfSection64(
    HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits,
    SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size,
    SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) {
  return BlNtMapViewOfSection(g_nt_map_view_of_section_func, section, process,
                              base, zero_bits, commit_size, offset, view_size,
                              inherit, allocation_type, protect);
}
#endif
}  // namespace blacklist
<commit_msg>Catch EXCEPTION_GUARD_PAGE in SafeGetImageInfo<commit_after>// Copyright 2013 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.
//
// Implementation of NtMapViewOfSection intercept for 32 bit builds.
//
// TODO(robertshield): Implement the 64 bit intercept.

#include "chrome_elf/blacklist/blacklist_interceptions.h"

#include <string>
#include <vector>

// Note that only #includes from base that are either header-only or built into
// base_static (see base/base.gyp) are allowed here.
#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "base/win/pe_image.h"
#include "chrome_elf/blacklist/blacklist.h"
#include "chrome_elf/breakpad.h"
#include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sandbox_types.h"

namespace {

NtQuerySectionFunction g_nt_query_section_func = NULL;
NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func = NULL;
NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func = NULL;

// TODO(robertshield): Merge with ntdll exports cache.
FARPROC GetNtDllExportByName(const char* export_name) {
  HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName);
  return ::GetProcAddress(ntdll, export_name);
}

int DllMatch(const base::string16& module_name) {
  for (int i = 0; blacklist::g_troublesome_dlls[i] != NULL; ++i) {
    if (_wcsicmp(module_name.c_str(), blacklist::g_troublesome_dlls[i]) == 0)
      return i;
  }
  return -1;
}

// TODO(robertshield): Some of the helper functions below overlap somewhat with
// code in sandbox_nt_util.cc. See if they can be unified.

// Native reimplementation of PSAPIs GetMappedFileName.
base::string16 GetBackingModuleFilePath(PVOID address) {
  DCHECK_NT(g_nt_query_virtual_memory_func);

  // We'll start with something close to max_path characters for the name.
  ULONG buffer_bytes = MAX_PATH * 2;
  std::vector<BYTE> buffer_data(buffer_bytes);

  for (;;) {
    MEMORY_SECTION_NAME* section_name =
        reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]);

    if (!section_name)
      break;

    ULONG returned_bytes;
    NTSTATUS ret = g_nt_query_virtual_memory_func(
        NtCurrentProcess, address, MemorySectionName, section_name,
        buffer_bytes, &returned_bytes);

    if (STATUS_BUFFER_OVERFLOW == ret) {
      // Retry the call with the given buffer size.
      buffer_bytes = returned_bytes + 1;
      buffer_data.resize(buffer_bytes);
      section_name = NULL;
      continue;
    }
    if (!NT_SUCCESS(ret))
      break;

    UNICODE_STRING* section_string =
        reinterpret_cast<UNICODE_STRING*>(section_name);
    return base::string16(section_string->Buffer,
                          section_string->Length / sizeof(wchar_t));
  }

  return base::string16();
}

bool IsModuleValidImageSection(HANDLE section,
                               PVOID *base,
                               PLARGE_INTEGER offset,
                               PSIZE_T view_size) {
  DCHECK_NT(g_nt_query_section_func);

  if (!section || !base || !view_size || offset)
    return false;

  SECTION_BASIC_INFORMATION basic_info;
  SIZE_T bytes_returned;
  NTSTATUS ret = g_nt_query_section_func(section, SectionBasicInformation,
                                         &basic_info, sizeof(basic_info),
                                         &bytes_returned);

  if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned)
    return false;

  if (!(basic_info.Attributes & SEC_IMAGE))
    return false;

  return true;
}

base::string16 ExtractLoadedModuleName(const base::string16& module_path) {
  if (module_path.empty() || module_path[module_path.size() - 1] == L'\\')
    return base::string16();

  size_t sep = module_path.find_last_of(L'\\');
  if (sep == base::string16::npos)
    return module_path;
  else
    return module_path.substr(sep+1);
}

// Fills |out_name| with the image name from the given |pe| image and |flags|
// with additional info about the image.
void SafeGetImageInfo(const base::win::PEImage& pe,
                      std::string* out_name,
                      uint32* flags) {
  out_name->clear();
  out_name->reserve(MAX_PATH);
  *flags = 0;
  __try {
    if (pe.VerifyMagic()) {
      *flags |= sandbox::MODULE_IS_PE_IMAGE;

      PIMAGE_EXPORT_DIRECTORY exports = pe.GetExportDirectory();
      if (exports) {
        const char* image_name = reinterpret_cast<const char*>(
            pe.RVAToAddr(exports->Name));
        size_t i = 0;
        for (; i < MAX_PATH && *image_name; ++i, ++image_name)
          out_name->push_back(*image_name);
      }

      PIMAGE_NT_HEADERS headers = pe.GetNTHeaders();
      if (headers) {
        if (headers->OptionalHeader.AddressOfEntryPoint)
          *flags |= sandbox::MODULE_HAS_ENTRY_POINT;
        if (headers->OptionalHeader.SizeOfCode)
          *flags |= sandbox::MODULE_HAS_CODE;
      }
    }
  } __except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
              GetExceptionCode() == EXCEPTION_GUARD_PAGE ||
              GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR) ?
             EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    out_name->clear();
  }
}

base::string16 GetImageInfoFromLoadedModule(HMODULE module, uint32* flags) {
  std::string out_name;
  base::win::PEImage pe(module);
  SafeGetImageInfo(pe, &out_name, flags);
  return base::string16(out_name.begin(), out_name.end());
}

bool IsSameAsCurrentProcess(HANDLE process) {
  return  (NtCurrentProcess == process) ||
          (::GetProcessId(process) == ::GetCurrentProcessId());
}

NTSTATUS BlNtMapViewOfSectionImpl(
    NtMapViewOfSectionFunction orig_MapViewOfSection,
    HANDLE section,
    HANDLE process,
    PVOID *base,
    ULONG_PTR zero_bits,
    SIZE_T commit_size,
    PLARGE_INTEGER offset,
    PSIZE_T view_size,
    SECTION_INHERIT inherit,
    ULONG allocation_type,
    ULONG protect) {
  NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits,
                                       commit_size, offset, view_size, inherit,
                                       allocation_type, protect);

  if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) ||
      !IsModuleValidImageSection(section, base, offset, view_size)) {
    return ret;
  }

  HMODULE module = reinterpret_cast<HMODULE>(*base);
  if (module) {
    UINT image_flags;

    base::string16 module_name(GetImageInfoFromLoadedModule(
        reinterpret_cast<HMODULE>(*base), &image_flags));
    base::string16 file_name(GetBackingModuleFilePath(*base));

    if (module_name.empty() && (image_flags & sandbox::MODULE_HAS_CODE)) {
      // If the module has no exports we retrieve the module name from the
      // full path of the mapped section.
      module_name = ExtractLoadedModuleName(file_name);
    }

    if (!module_name.empty()) {
      int blocked_index = DllMatch(module_name);
      if (blocked_index != -1) {
        DCHECK_NT(g_nt_unmap_view_of_section_func);
        g_nt_unmap_view_of_section_func(process, *base);
        ret = STATUS_UNSUCCESSFUL;

        blacklist::BlockedDll(blocked_index);
      }
    }
  }

  return ret;
}

}  // namespace

namespace blacklist {

bool InitializeInterceptImports() {
  g_nt_query_section_func =
      reinterpret_cast<NtQuerySectionFunction>(
          GetNtDllExportByName("NtQuerySection"));
  g_nt_query_virtual_memory_func =
      reinterpret_cast<NtQueryVirtualMemoryFunction>(
          GetNtDllExportByName("NtQueryVirtualMemory"));
  g_nt_unmap_view_of_section_func =
      reinterpret_cast<NtUnmapViewOfSectionFunction>(
          GetNtDllExportByName("NtUnmapViewOfSection"));

  return (g_nt_query_section_func && g_nt_query_virtual_memory_func &&
          g_nt_unmap_view_of_section_func);
}

SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection(
    NtMapViewOfSectionFunction orig_MapViewOfSection,
    HANDLE section,
    HANDLE process,
    PVOID *base,
    ULONG_PTR zero_bits,
    SIZE_T commit_size,
    PLARGE_INTEGER offset,
    PSIZE_T view_size,
    SECTION_INHERIT inherit,
    ULONG allocation_type,
    ULONG protect) {
  NTSTATUS ret = STATUS_UNSUCCESSFUL;

  __try {
    ret = BlNtMapViewOfSectionImpl(orig_MapViewOfSection, section, process,
                                   base, zero_bits, commit_size, offset,
                                   view_size, inherit, allocation_type,
                                   protect);
  } __except(GenerateCrashDump(GetExceptionInformation())) {
  }

  return ret;
}

#if defined(_WIN64)
NTSTATUS WINAPI BlNtMapViewOfSection64(
    HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits,
    SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size,
    SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) {
  return BlNtMapViewOfSection(g_nt_map_view_of_section_func, section, process,
                              base, zero_bits, commit_size, offset, view_size,
                              inherit, allocation_type, protect);
}
#endif
}  // namespace blacklist
<|endoftext|>


<commit_before>/*
 * =====================================================================================
 *
 *       Filename:  main.cc
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  05/18/2007 06:21:53 PM EDT
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Nikolaos Vasiloglou (NV), nvasil@ieee.org
 *        Company:  Georgia Tech Fastlab-ESP Lab
 *
 * =====================================================================================
 */
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include "fastlib/fastlib.h"
#include "u/nvasil/mmanager/memory_manager.h"
#include "u/nvasil/mmanager_with_tpie/memory_manager.h"
#include "u/nvasil/dataset/binary_dataset.h"
#include "u/nvasil/tree/tree_definitions.h"

struct Parameters {
  int32 dimension_;
	int64 num_of_points_;
	std::string data_file_;
	std::string out_file_;
	std::string temp_dir_;
	std::string memory_engine_;
	int32 page_size_;
	int32 knns_;
	std::string memory_file_;
  BinaryDataset<float32> data_;
	uint64 capacity_;
  bool specialized_for_knns_;
};

template<typename TREE>
void DuallTreeAllNearestNeighbors(Parameters &args);
template<typename TREE>
void DuallTreeAllNearestNeighborsSpecializedForKnn(Parameters &args);

int main(int argc, char *argv[]) {
  MM_manager.ignore_memory_limit();
	Parameters args;
	// initialize command line parameter
	fx_init(argc, argv);
	args.temp_dir_=fx_param_str(NULL, "temp_dir", "./");
  if (fx_param_exists(NULL, "data_file")==1) {
	  args.data_file_=fx_param_str(NULL, "data_file", NULL);
		args.data_.Init(args.data_file_);
		args.num_of_points_= args.data_.get_num_of_points();
		args.dimension_= args.data_.get_dimension();
	} else {
		// if data file is not specified use random points
		printf("Generating random points...\n");
	  args.data_file_= args.temp_dir_+string("temp");
		args.dimension_= fx_param_int_req(NULL, "dimension");
		args.num_of_points_= fx_param_int_req(NULL, "num_of_points");
		args.data_.Init(args.data_file_, args.num_of_points_, args.dimension_);
		for(int64 i=0; i<args.num_of_points_; i++) {
		  for(int32 j=0; j<args.dimension_; j++) {
			  args.data_.At(i,j) = 1.0*rand()/RAND_MAX;
				args.data_.set_id(i,i);
			}
		}
	}
	args.out_file_ = fx_param_str(fx_root, "out_file", "allnn");
  args.capacity_ = fx_param_int(fx_root, "capacity", 134217728);
	args.knns_ = fx_param_int(fx_root, "knns", 2);
	args.page_size_ = fx_param_int(fx_root, "page_size", 4096);
  args.memory_file_ = fx_param_str(fx_root, "memory_file", "temp_mem");
  args.memory_engine_ = fx_param_str(fx_root, "memory_engine", "mmapmm");
	args.specialized_for_knns_ = fx_param_bool(fx_root, "specialized_for_knns", false);
	printf("Creating swap file...\n");
 	if (sizeof(index_t)==sizeof(int32)) {
	  NONFATAL("index_t is int32, good for small scale problems");
	} else {
		if (sizeof(index_t)==sizeof(int64)) {
	    NONFATAL("index_t is int64, good for large scale problems");
		}
	}
	if (args.memory_engine_ == "mmapmm") {
		mmapmm::MemoryManager<false>::allocator_ =
		    new mmapmm::MemoryManager<false>();
    mmapmm::MemoryManager<false>::
			  allocator_->set_capacity(args.capacity_);

		mmapmm::MemoryManager<false>::
			  allocator_->set_pool_name(args.memory_file_);

		mmapmm::MemoryManager<false>::allocator_->Init();
		if (args.specialized_for_knns_==true) {
      DuallTreeAllNearestNeighborsSpecializedForKnn<
			    BinaryKdTreeMMAPMMKnnNode_t>(args);
		} else {
		  DuallTreeAllNearestNeighbors<BinaryKdTreeMMAPMM_t>(args);
		}
    if (!fx_param_exists(fx_root, "data_file")) {
		  unlink(args.data_file_.c_str());
		}
	} else {
	  if (args.memory_engine_ == "tpiemm"){
      tpiemm::MemoryManager<false>::allocator_ =
		      new tpiemm::MemoryManager<false>();
      tpiemm::MemoryManager<false>::
			    allocator_->set_cache_size(args.capacity_);

		  tpiemm::MemoryManager<false>::
			    allocator_->set_page_size(args.page_size_);

		  tpiemm::MemoryManager<false>::
			  allocator_->set_cache_file(args.memory_file_);

		  tpiemm::MemoryManager<false>::allocator_->Init();
     if (args.specialized_for_knns_==true) {
       DuallTreeAllNearestNeighborsSpecializedForKnn<
				 BinaryKdTreeTPIEMMKnnNode_t>(args);
		 } else {
	     DuallTreeAllNearestNeighbors<BinaryKdTreeTPIEMM_t>(args);
		 }
      if (!fx_param_exists(fx_root, "data_file")) {
		    unlink(args.data_file_.c_str());
		  }
		} else {
		  FATAL("%s for memory_engine is not a valid option\n",
					  args.memory_engine_.c_str());
		}
	}
	fx_format_result(fx_root, "success", "%d", 1);
	fx_done();
  unlink(args.memory_file_.c_str());
}

template<typename TREE>
void DuallTreeAllNearestNeighbors(Parameters &args) {
  TREE tree;
	printf("Building the tree...");
	fflush(stdout);
	tree.Init(&args.data_);

	fx_timer_start(fx_root, "build");
	tree.BuildDepthFirst();
	fx_timer_stop(fx_root, "build");
  printf("Memory usage: %llu\n",
	        (unsigned long long)TREE::Allocator_t::allocator_->get_usage());
	printf("%s\n", tree.Statistics().c_str());
	fflush(stdout);
	args.data_.Destruct();
	printf("Initializing all nearest neighbor output...\n");
  tree.InitAllKNearestNeighborOutput(args.out_file_,
				                              args.knns_);
	printf("Computing all nearest neighbors...\n");
	fflush(stdout);
  fx_timer_start(fx_root, "dualltree");
	tree.AllNearestNeighbors(tree.get_parent(), args.knns_);
	fx_timer_stop(fx_root, "dualltree");
	tree.CloseAllKNearestNeighborOutput(args.knns_);
  unlink(args.out_file_.c_str());
}

template<typename TREE>
void DuallTreeAllNearestNeighborsSpecializedForKnn(Parameters &args) {
  TREE tree;
	printf("Procceding with the specialized method for knn node..\n");
	printf("Building the tree...");
	tree.Init(&args.data_);
	tree.set_knns(args.knns_);
	fx_timer_start(fx_root, "build");
	tree.BuildDepthFirst();
	fx_timer_stop(fx_root, "build");
  printf("Memory usage: %llu\n",
	        (unsigned long long)TREE::Allocator_t::allocator_->get_usage());
	printf("%s\n", tree.Statistics().c_str());
	args.data_.Destruct();
	printf("Computing all nearest neighbors...\n");
	fflush(stdout);
  fx_timer_start(fx_root, "dualltree");
	tree.AllNearestNeighbors(tree.get_parent(), args.knns_);
	fx_timer_stop(fx_root, "dualltree");
	printf("Collecting results....\n");
	fx_timer_start(fx_root, "collecting_results");
  tree.CollectKNearestNeighborWithMMAP(args.out_file_.c_str());
	fx_timer_stop(fx_root, "collecting_results");
	unlink(args.out_file_.c_str());
}

<commit_msg>minor changes<commit_after>/*
 * =====================================================================================
 *
 *       Filename:  main.cc
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  05/18/2007 06:21:53 PM EDT
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Nikolaos Vasiloglou (NV), nvasil@ieee.org
 *        Company:  Georgia Tech Fastlab-ESP Lab
 *
 * =====================================================================================
 */
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include "fastlib/fastlib.h"
#include "u/nvasil/mmanager/memory_manager.h"
#include "u/nvasil/mmanager_with_tpie/memory_manager.h"
#include "u/nvasil/dataset/binary_dataset.h"
#include "u/nvasil/tree/tree_definitions.h"

struct Parameters {
  int32 dimension_;
	int64 num_of_points_;
	std::string data_file_;
	std::string out_file_;
	std::string temp_dir_;
	std::string memory_engine_;
	int32 page_size_;
	int32 knns_;
	std::string memory_file_;
  BinaryDataset<float32> data_;
	uint64 capacity_;
  bool specialized_for_knns_;
};

template<typename TREE>
void DuallTreeAllNearestNeighbors(Parameters &args);
template<typename TREE>
void DuallTreeAllNearestNeighborsSpecializedForKnn(Parameters &args);

int main(int argc, char *argv[]) {
  MM_manager.ignore_memory_limit();
	Parameters args;
	// initialize command line parameter
	fx_init(argc, argv);
	args.temp_dir_=fx_param_str(NULL, "temp_dir", "./");
  if (fx_param_exists(NULL, "data_file")==1) {
	  args.data_file_=fx_param_str(NULL, "data_file", NULL);
		args.data_.Init(args.data_file_);
		args.num_of_points_= args.data_.get_num_of_points();
		args.dimension_= args.data_.get_dimension();
	} else {
		// if data file is not specified use random points
		printf("Generating random points...\n");
	  args.data_file_= args.temp_dir_+string("temp");
		args.dimension_= fx_param_int_req(NULL, "dimension");
		args.num_of_points_= fx_param_int_req(NULL, "num_of_points");
		args.data_.Init(args.data_file_, args.num_of_points_, args.dimension_);
		for(int64 i=0; i<args.num_of_points_; i++) {
		  for(int32 j=0; j<args.dimension_; j++) {
			  args.data_.At(i,j) = 1.0*rand()/RAND_MAX;
				args.data_.set_id(i,i);
			}
		}
	}
	args.out_file_ = fx_param_str(fx_root, "out_file", "allnn");
  args.capacity_ = fx_param_int(fx_root, "capacity", 134217728);
	args.knns_ = fx_param_int(fx_root, "knns", 2);
	args.page_size_ = fx_param_int(fx_root, "page_size", 4096);
  args.memory_file_ = fx_param_str(fx_root, "memory_file", "temp_mem");
  args.memory_engine_ = fx_param_str(fx_root, "memory_engine", "mmapmm");
	args.specialized_for_knns_ = fx_param_bool(fx_root, "specialized_for_knns", false);

	if (args.memory_engine_=="tpiemm") {
	 	unlink(args.memory_file_.c_str());
	}

	printf("Creating swap file...\n");
 	if (sizeof(index_t)==sizeof(int32)) {
	  NONFATAL("index_t is int32, good for small scale problems");
	} else {
		if (sizeof(index_t)==sizeof(int64)) {
	    NONFATAL("index_t is int64, good for large scale problems");
		}
	}
	if (args.memory_engine_ == "mmapmm") {
		mmapmm::MemoryManager<false>::allocator_ =
		    new mmapmm::MemoryManager<false>();
    mmapmm::MemoryManager<false>::
			  allocator_->set_capacity(args.capacity_);

		mmapmm::MemoryManager<false>::
			  allocator_->set_pool_name(args.memory_file_);

		mmapmm::MemoryManager<false>::allocator_->Init();
		if (args.specialized_for_knns_==true) {
      DuallTreeAllNearestNeighborsSpecializedForKnn<
			    BinaryKdTreeMMAPMMKnnNode_t>(args);
		} else {
		  DuallTreeAllNearestNeighbors<BinaryKdTreeMMAPMM_t>(args);
		}
    if (!fx_param_exists(fx_root, "data_file")) {
		  unlink(args.data_file_.c_str());
		}
	} else {
	  if (args.memory_engine_ == "tpiemm"){
      tpiemm::MemoryManager<false>::allocator_ =
		      new tpiemm::MemoryManager<false>();
      tpiemm::MemoryManager<false>::
			    allocator_->set_cache_size(args.capacity_);

		  tpiemm::MemoryManager<false>::
			    allocator_->set_page_size(args.page_size_);

		  tpiemm::MemoryManager<false>::
			  allocator_->set_cache_file(args.memory_file_);

		  tpiemm::MemoryManager<false>::allocator_->Init();
     if (args.specialized_for_knns_==true) {
       DuallTreeAllNearestNeighborsSpecializedForKnn<
				 BinaryKdTreeTPIEMMKnnNode_t>(args);
		 } else {
	     DuallTreeAllNearestNeighbors<BinaryKdTreeTPIEMM_t>(args);
		 }
      if (!fx_param_exists(fx_root, "data_file")) {
		    unlink(args.data_file_.c_str());
		  }
		} else {
		  FATAL("%s for memory_engine is not a valid option\n",
					  args.memory_engine_.c_str());
		}
	}
	fx_format_result(fx_root, "success", "%d", 1);
	fx_done();
	if (args.memory_engine_=="tpiemm") {
	 	unlink(args.memory_file_.c_str());
	}

}

template<typename TREE>
void DuallTreeAllNearestNeighbors(Parameters &args) {
  TREE tree;
	printf("Building the tree...");
	fflush(stdout);
	tree.Init(&args.data_);

	fx_timer_start(fx_root, "build");
	tree.BuildDepthFirst();
	fx_timer_stop(fx_root, "build");
  printf("Memory usage: %llu\n",
	        (unsigned long long)TREE::Allocator_t::allocator_->get_usage());
	printf("%s\n", tree.Statistics().c_str());
	fflush(stdout);
	args.data_.Destruct();
	printf("Initializing all nearest neighbor output...\n");
  tree.InitAllKNearestNeighborOutput(args.out_file_,
				                              args.knns_);
	printf("Computing all nearest neighbors...\n");
	fflush(stdout);
  fx_timer_start(fx_root, "dualltree");
	tree.AllNearestNeighbors(tree.get_parent(), args.knns_);
	fx_timer_stop(fx_root, "dualltree");
	tree.CloseAllKNearestNeighborOutput(args.knns_);
  unlink(args.out_file_.c_str());
}

template<typename TREE>
void DuallTreeAllNearestNeighborsSpecializedForKnn(Parameters &args) {
  TREE tree;
	printf("Procceding with the specialized method for knn node..\n");
	printf("Building the tree...");
	tree.Init(&args.data_);
	tree.set_knns(args.knns_);
	fx_timer_start(fx_root, "build");
	tree.BuildDepthFirst();
	fx_timer_stop(fx_root, "build");
  printf("Memory usage: %llu\n",
	        (unsigned long long)TREE::Allocator_t::allocator_->get_usage());
	printf("%s\n", tree.Statistics().c_str());
	args.data_.Destruct();
	printf("Computing all nearest neighbors...\n");
	fflush(stdout);
  fx_timer_start(fx_root, "dualltree");
	tree.AllNearestNeighbors(tree.get_parent(), args.knns_);
	fx_timer_stop(fx_root, "dualltree");
	printf("Collecting results....\n");
	fx_timer_start(fx_root, "collecting_results");
  tree.CollectKNearestNeighborWithMMAP(args.out_file_.c_str());
	fx_timer_stop(fx_root, "collecting_results");
	unlink(args.out_file_.c_str());
}

<|endoftext|>