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

#ifndef CHROME_FRAME_UTILS_H_
#define CHROME_FRAME_UTILS_H_

#include <OAidl.h>
#include <objidl.h>
#include <windows.h>
#include <wininet.h>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/strings/string16.h"
#include "base/win/scoped_comptr.h"
#include "ui/gfx/rect.h"
#include "url/gurl.h"

class RegistryListPreferencesHolder;
interface IBrowserService;
interface IWebBrowser2;
struct ContextMenuModel;

namespace base {
class FilePath;
}

// utils.h : Various utility functions and classes
extern const char kGCFProtocol[];

extern const wchar_t kAllowUnsafeURLs[];
extern const wchar_t kChromeContentPrefix[];
extern const wchar_t kChromeFrameAccessibleMode[];
extern const wchar_t kChromeFrameAttachTabPattern[];
extern const wchar_t kChromeFrameConfigKey[];
extern const wchar_t kChromeFrameHeadlessMode[];
extern const wchar_t kChromeFrameUnpinnedMode[];
extern const wchar_t kChromeMimeType[];
extern const wchar_t kChromeProtocolPrefix[];
extern const wchar_t kEnableBuggyBhoIntercept[];
extern const wchar_t kEnableGCFRendererByDefault[];
extern const wchar_t kExcludeUAFromDomainList[];
extern const wchar_t kIexploreProfileName[];
extern const wchar_t kRenderInGCFUrlList[];
extern const wchar_t kRenderInHostUrlList[];
extern const wchar_t kRundllProfileName[];
extern const wchar_t kUseBackgroundThreadForSubResources[];

// This function is very similar to the AtlRegisterTypeLib function except
// that it takes a parameter that specifies whether to register the typelib
// for the current user only or on a machine-wide basis
// Refer to the MSDN documentation for AtlRegisterTypeLib for a description of
// the arguments
HRESULT UtilRegisterTypeLib(HINSTANCE tlb_instance,
                            LPCOLESTR index,
                            bool for_current_user_only);

// This function is very similar to the AtlUnRegisterTypeLib function except
// that it takes a parameter that specifies whether to unregister the typelib
// for the current user only or on a machine-wide basis
// Refer to the MSDN documentation for AtlUnRegisterTypeLib for a description
// of the arguments
HRESULT UtilUnRegisterTypeLib(HINSTANCE tlb_instance,
                              LPCOLESTR index,
                              bool for_current_user_only);

HRESULT UtilRegisterTypeLib(LPCWSTR typelib_path, bool for_current_user_only);

HRESULT UtilUnRegisterTypeLib(LPCWSTR typelib_path, bool for_current_user_only);

HRESULT UtilRegisterTypeLib(ITypeLib* typelib,
                            LPCWSTR typelib_path,
                            LPCWSTR help_dir,
                            bool for_current_user_only);

HRESULT UtilUnRegisterTypeLib(ITypeLib* typelib,
                              bool for_current_user_only);

// Clears a marker that causes legacy NPAPI registration to persist across
// updates. Returns false if the marker could not be removed.
bool UtilRemovePersistentNPAPIMarker();

// Given an HTML fragment, this function looks for the
// <meta http-equiv="X-UA-Compatible"> tag and extracts the value of the
// "content" attribute
// This method will currently return a false positive if the tag appears
// inside a string in a <SCRIPT> block.
HRESULT UtilGetXUACompatContentValue(const std::wstring& html_string,
                                     std::wstring* content_value);

// Returns a string from ChromeFrame's string table by resource. Must be
// provided with a valid resource id.
std::wstring GetResourceString(int resource_id);

// Displays a message box indicating that there was a version mismatch between
// ChromeFrame and the running instance of Chrome.
// server_version is the version of the running instance of Chrome.
void DisplayVersionMismatchWarning(HWND parent,
                                   const std::string& server_version);

// This class provides a base implementation for ATL modules which want to
// perform all their registration under HKCU. This class overrides the
// RegisterServer and UnregisterServer methods and registers the type libraries
// under HKCU (the rest of the registration is made under HKCU by changing the
// appropriate .RGS files)
template < class BaseAtlModule >
class AtlPerUserModule : public BaseAtlModule {
 public:
  HRESULT RegisterServer(BOOL reg_typelib = FALSE,
                         const CLSID* clsid = NULL) throw() {
    HRESULT hr = BaseAtlModule::RegisterServer(FALSE, clsid);
    if (FAILED(hr)) {
      return hr;
    }
    if (reg_typelib)  {
      hr = UtilRegisterTypeLib(_AtlComModule.m_hInstTypeLib, NULL, false);
    }
    return hr;
  }

  HRESULT UnregisterServer(BOOL unreg_typelib,
                           const CLSID* clsid = NULL) throw() {
    HRESULT hr = BaseAtlModule::UnregisterServer(FALSE, clsid);
    if (FAILED(hr)) {
      return hr;
    }
    if (unreg_typelib)  {
      hr = UtilUnRegisterTypeLib(_AtlComModule.m_hInstTypeLib, NULL, false);
    }
    return hr;
  }
};

// Creates a javascript statement for execution from the function name and
// arguments passed in.
std::string CreateJavascript(const std::string& function_name,
                             const std::string args);

// Use to prevent the DLL from being unloaded while there are still living
// objects with outstanding references.
class AddRefModule {
 public:
  AddRefModule();
  ~AddRefModule();
};

// Retrieves the executable name of the process hosting us. If
// |include_extension| is false, then we strip the extension from the name.
std::wstring GetHostProcessName(bool include_extension);

typedef enum BrowserType {
  BROWSER_INVALID = -1,
  BROWSER_UNKNOWN,
  BROWSER_IE,
};

BrowserType GetBrowserType();

typedef enum IEVersion {
  IE_INVALID,
  NON_IE,
  IE_UNSUPPORTED,
  IE_6,
  IE_7,
  IE_8,
  IE_9,
  IE_10,
};

// The renderer to be used for a page.  Values for Chrome also convey the
// reason why Chrome is used.
enum RendererType {
  RENDERER_TYPE_UNDETERMINED = 0,
  RENDERER_TYPE_CHROME_MIN,
  // NOTE: group all _CHROME_ values together below here, as they are used for
  // generating metrics reported via UMA (adjust MIN/MAX as needed).
  RENDERER_TYPE_CHROME_GCF_PROTOCOL = RENDERER_TYPE_CHROME_MIN,
  RENDERER_TYPE_CHROME_HTTP_EQUIV,
  RENDERER_TYPE_CHROME_RESPONSE_HEADER,
  RENDERER_TYPE_CHROME_DEFAULT_RENDERER,
  RENDERER_TYPE_CHROME_OPT_IN_URL,
  RENDERER_TYPE_CHROME_WIDGET,
  // NOTE: all _CHOME_ values must go above here (adjust MIN/MAX as needed).
  RENDERER_TYPE_CHROME_MAX = RENDERER_TYPE_CHROME_WIDGET,
  RENDERER_TYPE_OTHER,
};

// Returns true if the given RendererType represents Chrome.
bool IsChrome(RendererType renderer_type);

// Convenience macro for logging a sample for the launch type metric.
#define UMA_LAUNCH_TYPE_COUNT(sample) \
  UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.LaunchType", sample, \
  RENDERER_TYPE_CHROME_MIN, RENDERER_TYPE_CHROME_MAX, \
  RENDERER_TYPE_CHROME_MAX + 1 - RENDERER_TYPE_CHROME_MIN)

// To get the IE version when Chrome Frame is hosted in IE.  Make sure that
// the hosting browser is IE before calling this function, otherwise NON_IE
// will be returned.
//
// Versions newer than the newest supported version are reported as the newest
// supported version.
IEVersion GetIEVersion();

// Returns the actual major version of the IE in which the current process is
// hosted. Returns 0 if the current process is not IE or any other error occurs.
uint32 GetIEMajorVersion();

base::FilePath GetIETemporaryFilesFolder();

// Retrieves the file version from a module handle without extra round trips
// to the disk (as happens with the regular GetFileVersionInfo API).
//
// @param module A handle to the module for which to retrieve the version info.
// @param high On successful return holds the most significant part of the file
// version.  Must be non-null.
// @param low On successful return holds the least significant part of the file
// version.  May be NULL.
// @returns true if the version info was successfully retrieved.
bool GetModuleVersion(HMODULE module, uint32* high, uint32* low);

// Return if the IEXPLORE is in private mode. The IEIsInPrivateBrowsing() checks
// whether current process is IEXPLORE.
bool IsIEInPrivate();

// Calls [ieframe|shdocvw]!DoFileDownload to initiate a download.
HRESULT DoFileDownloadInIE(const wchar_t* url);

// Construct a menu from the model sent from Chrome.
HMENU BuildContextMenu(const ContextMenuModel& menu_model);

// Uses GURL internally to append 'relative' to 'document'
std::string ResolveURL(const std::string& document,
                       const std::string& relative);

// Returns true iff the two urls have the same scheme, same host and same port.
bool HaveSameOrigin(const std::string& url1, const std::string& url2);

// Get a boolean configuration value from registry.
bool GetConfigBool(bool default_value, const wchar_t* value_name);

// Gets an integer configuration value from the registry.
int GetConfigInt(int default_value, const wchar_t* value_name);

// Gets a 64-bit integer configuration value from the registry.
int64 GetConfigInt64(int64 default_value, const wchar_t* value_name);

// Sets an integer configuration value in the registry.
bool SetConfigInt(const wchar_t* value_name, int value);

// Sets a boolean integer configuration value in the registry.
bool SetConfigBool(const wchar_t* value_name, bool value);

// Sets a 64-bit integer configuration value in the registry.
bool SetConfigInt64(const wchar_t* value_name, int64 value);

// Deletes the configuration value passed in.
bool DeleteConfigValue(const wchar_t* value_name);

// Returns true if we are running in headless mode in which case we need to
// gather crash dumps, etc to send them to the crash server.
bool IsHeadlessMode();

// Returns true if we are running in accessible mode in which we need to enable
// renderer accessibility for use in automation.
bool IsAccessibleMode();

// Returns true if we are running in unpinned mode in which case DLL
// eviction should be possible.
bool IsUnpinnedMode();

// Returns true if all HTML pages should be rendered in GCF by default.
bool IsGcfDefaultRenderer();

// Check if this url is opting into Chrome Frame based on static settings.
// Returns one of:
// - RENDERER_TYPE_UNDETERMINED if not opt-in or if explicit opt-out
// - RENDERER_TYPE_CHROME_DEFAULT_RENDERER
// - RENDERER_TYPE_CHROME_OPT_IN_URL
RendererType RendererTypeForUrl(const std::wstring& url);

// Check if we should try to remove the CF user agent based on registry
// settings.
bool ShouldRemoveUAForUrl(const string16& url);

// Testing methods that return the backing stores behind RendererTypeForUrl and
// ShouldRemoveUAForUrl. Intended to allow unit testing code that calls the
// above methods.
// TODO(robertshield): All of the FooForUrl code should be removed from here
// and further refactored.
RegistryListPreferencesHolder& GetRendererTypePreferencesHolderForTesting();
RegistryListPreferencesHolder& GetUserAgentPreferencesHolderForTesting();

// A shortcut for QueryService
template <typename T>
HRESULT DoQueryService(const IID& service_id, IUnknown* unk, T** service) {
  DCHECK(service);
  if (!unk)
    return E_INVALIDARG;

  base::win::ScopedComPtr<IServiceProvider> service_provider;
  HRESULT hr = service_provider.QueryFrom(unk);
  if (service_provider)
    hr = service_provider->QueryService(service_id, service);

  DCHECK(FAILED(hr) || *service);
  return hr;
}

// Navigates an IWebBrowser2 object to a moniker.
// |headers| can be NULL.
HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
                                 const wchar_t* headers, IBindCtx* bind_ctx,
                                 const wchar_t* fragment, IStream* post_data,
                                 VARIANT* flags);

// Raises a flag on the current thread (using TLS) to indicate that an
// in-progress navigation should be rendered in chrome frame.
void MarkBrowserOnThreadForCFNavigation(IBrowserService* browser);

// Checks if this browser instance has been marked as currently navigating
// to a CF document.  If clear_flag is set to true, the tls flag is cleared but
// only if the browser has been marked.
bool CheckForCFNavigation(IBrowserService* browser, bool clear_flag);

// Returns true if the URL passed in is something which can be handled by
// Chrome. If this function returns false then we should fail the navigation.
// When is_privileged is true, chrome extension URLs will be considered valid.
bool IsValidUrlScheme(const GURL& url, bool is_privileged);

// Returns the raw http headers for the current request given an
// IWinInetHttpInfo pointer.
std::string GetRawHttpHeaders(IWinInetHttpInfo* info);

// Can be used to determine whether a given request is being performed for
// a sub-frame or iframe in Internet Explorer. This can be called
// from various places, notably in request callbacks and the like.
//
// |service_provider| must not be NULL and should be a pointer to something
// that implements IServiceProvider (if it isn't this method returns false).
//
// Returns true if this method can determine with some certainty that the
// request did NOT originate from a top level frame, returns false otherwise.
bool IsSubFrameRequest(IUnknown* service_provider);

// See COM_INTERFACE_BLIND_DELEGATE below for details.
template <class T>
STDMETHODIMP CheckOutgoingInterface(void* obj, REFIID iid, void** ret,
                                    DWORD cookie) {
  T* instance = reinterpret_cast<T*>(obj);
  HRESULT hr = E_NOINTERFACE;
  IUnknown* delegate = instance ? instance->delegate() : NULL;
  if (delegate) {
    hr = delegate->QueryInterface(iid, ret);
#if !defined(NDEBUG)
    if (SUCCEEDED(hr)) {
      wchar_t iid_string[64] = {0};
      StringFromGUID2(iid, iid_string, arraysize(iid_string));
      DVLOG(1) << __FUNCTION__ << " Giving out wrapped interface: "
               << iid_string;
    }
#endif
  }

  return hr;
}

// See COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS below for details.
template <class T>
STDMETHODIMP QueryInterfaceIfDelegateSupports(void* obj, REFIID iid,
                                              void** ret, DWORD cookie) {
  HRESULT hr = E_NOINTERFACE;
  T* instance = reinterpret_cast<T*>(obj);
  IUnknown* delegate = instance ? instance->delegate() : NULL;
  if (delegate) {
    base::win::ScopedComPtr<IUnknown> original;
    hr = delegate->QueryInterface(iid,
                                  reinterpret_cast<void**>(original.Receive()));
    if (original) {
      IUnknown* supported_interface = reinterpret_cast<IUnknown*>(
          reinterpret_cast<DWORD_PTR>(obj) + cookie);
      supported_interface->AddRef();
      *ret = supported_interface;
      hr = S_OK;
    }
  }

  return hr;
}

// Same as COM_INTERFACE_ENTRY but relies on the class to implement a
// delegate() method that returns a pointer to the delegated COM object.
#define COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(x) \
    COM_INTERFACE_ENTRY_FUNC(_ATL_IIDOF(x), \
        offsetofclass(x, _ComMapClass), \
        QueryInterfaceIfDelegateSupports<_ComMapClass>)

// Queries the delegated COM object for an interface, bypassing the wrapper.
#define COM_INTERFACE_BLIND_DELEGATE() \
    COM_INTERFACE_ENTRY_FUNC_BLIND(0, CheckOutgoingInterface<_ComMapClass>)

std::wstring GuidToString(const GUID& guid);

// The urls retrieved from the IMoniker interface don't contain the anchor
// portion of the actual url navigated to. This function checks whether the
// url passed in the bho_url parameter contains an anchor and if yes checks
// whether it matches the url retrieved from the moniker. If yes it returns
// the bho url, if not the moniker url.
std::wstring GetActualUrlFromMoniker(IMoniker* moniker,
                                     IBindCtx* bind_context,
                                     const std::wstring& bho_url);

// Checks if a window is a top level window
bool IsTopLevelWindow(HWND window);

// Seeks a stream back to position 0.
HRESULT RewindStream(IStream* stream);

// Fired when we want to notify IE about privacy changes.
#define WM_FIRE_PRIVACY_CHANGE_NOTIFICATION (WM_APP + 1)

// Sent (not posted) when a request needs to be downloaded in the host browser
// instead of Chrome.  WPARAM is 0 and LPARAM is a pointer to an IMoniker
// object.
// NOTE: Since the message is sent synchronously, the handler should only
// start asynchronous operations in order to not block the sender unnecessarily.
#define WM_DOWNLOAD_IN_HOST (WM_APP + 2)

// This structure contains the parameters sent over to initiate a download
// request in the host browser.
struct DownloadInHostParams {
  base::win::ScopedComPtr<IBindCtx> bind_ctx;
  base::win::ScopedComPtr<IMoniker> moniker;
  base::win::ScopedComPtr<IStream> post_data;
  std::string request_headers;
};

// Maps the InternetCookieState enum to the corresponding CookieAction values
// used for IE privacy stuff.
int32 MapCookieStateToCookieAction(InternetCookieState cookie_state);

// Parses the url passed in and returns a GURL instance without the fragment.
GURL GetUrlWithoutFragment(const wchar_t* url);

// Compares the URLs passed in after removing the fragments from them.
bool CompareUrlsWithoutFragment(const wchar_t* url1, const wchar_t* url2);

// Returns the Referrer from the HTTP headers and additional headers.
std::string FindReferrerFromHeaders(const wchar_t* headers,
                                     const wchar_t* additional_headers);

// Returns the HTTP headers from the binding passed in.
std::string GetHttpHeadersFromBinding(IBinding* binding);

// Returns the HTTP response code from the binding passed in.
int GetHttpResponseStatusFromBinding(IBinding* binding);

// Returns the clipboard format for text/html.
CLIPFORMAT GetTextHtmlClipboardFormat();

// Returns true iff the mime type is text/html.
bool IsTextHtmlMimeType(const wchar_t* mime_type);

// Returns true iff the clipboard format is text/html.
bool IsTextHtmlClipFormat(CLIPFORMAT cf);

// Returns true if we can detect that we are running as SYSTEM, false otherwise.
bool IsSystemProcess();

// STL helper class that implements a functor to delete objects.
// E.g: std::for_each(v.begin(), v.end(), utils::DeleteObject());
namespace utils {
class DeleteObject {
 public:
  template <typename T>
  void operator()(T* obj) {
    delete obj;
  }
};
}

// Convert various protocol flags to text representation. Used for logging.
std::string BindStatus2Str(ULONG bind_status);
std::string PiFlags2Str(DWORD flags);
std::string Bscf2Str(DWORD flags);

// Reads data from a stream into a string.
HRESULT ReadStream(IStream* stream, size_t size, std::string* data);

// Parses urls targeted at ChromeFrame. This class maintains state like
// whether a url is prefixed with the gcf: prefix, whether it is being
// attached to an existing external tab, etc.
class ChromeFrameUrl {
 public:
  ChromeFrameUrl();

  // Parses the url passed in. Returns true on success.
  bool Parse(const std::wstring& url);

  bool is_chrome_protocol() const {
    return is_chrome_protocol_;
  }

  bool attach_to_external_tab() const {
    return attach_to_external_tab_;
  }

  uint64 cookie() const {
    return cookie_;
  }

  int disposition() const {
    return disposition_;
  }

  const gfx::Rect& dimensions() const {
    return dimensions_;
  }

  const GURL& gurl() const {
    return parsed_url_;
  }

  const std::string& profile_name() const {
    return profile_name_;
  }

 private:
  // If we are attaching to an existing external tab, this function parses the
  // suffix portion of the URL which contains the attach_external_tab prefix.
  bool ParseAttachExternalTabUrl();

  // Clear state.
  void Reset();

  bool attach_to_external_tab_;
  bool is_chrome_protocol_;
  uint64 cookie_;
  gfx::Rect dimensions_;
  int disposition_;

  GURL parsed_url_;
  std::string profile_name_;
};

class NavigationConstraints;
// Returns true if we can navigate to this URL.
// These decisions are controlled by the NavigationConstraints object passed
// in.
bool CanNavigate(const GURL& url,
                 NavigationConstraints* navigation_constraints);

// Helper function to spin a message loop and dispatch messages while waiting
// for a handle to be signaled.
void WaitWithMessageLoop(HANDLE* handles, int count, DWORD timeout);

// Enumerates values in a key and adds them to an array.
// The names of the values are not returned.
void EnumerateKeyValues(HKEY parent_key, const wchar_t* sub_key_name,
                        std::vector<std::wstring>* values);

// Interprets the value of an X-UA-Compatible header (or <meta> tag equivalent)
// and indicates whether the header value contains a Chrome Frame directive
// matching a given host browser version.
//
// The header is a series of name-value pairs, with the names being HTTP tokens
// and the values being either tokens or quoted-strings. Names and values are
// joined by '=' and pairs are delimited by either ';' or ','. LWS may be used
// liberally before and between names, values, '=', and ';' or ','. See RFC 2616
// for definitions of token, quoted-string, and LWS. See Microsoft's
// documentation of the X-UA-COMPATIBLE header here:
// http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx
//
// At most one 'Chrome=<FILTER>' entry is expected in the header value. The
// first valid instance is used. The value of "<FILTER>" (possibly after
// unquoting) is interpreted as follows:
//
// "1"   - Always active
// "IE7" - Active for IE major version 7 or lower
//
// For example:
// X-UA-Compatible: IE=8; Chrome=IE6
//
// The string is first interpreted using ';' as a delimiter. It is reevaluated
// using ',' iff no valid 'chrome=' value is found.
bool CheckXUaCompatibleDirective(const std::string& directive,
                                 int ie_major_version);

// Returns the version of the current module as a string.
std::wstring GetCurrentModuleVersion();

// Returns true if ChromeFrame is the currently loaded document.
bool IsChromeFrameDocument(IWebBrowser2* web_browser);

// Increases the wininet connection limit for HTTP 1.0/1.1 connections to the
// value passed in. This is only done if the existing connection limit is
// lesser than the connection limit passed in. This function attempts to
// increase the connection count once per process.
// Returns true on success.
bool IncreaseWinInetConnections(DWORD connections);

// Sets |profile_path| to the path for the Chrome Frame |profile_name|
// profile.
void GetChromeFrameProfilePath(const string16& profile_name,
                               base::FilePath* profile_path);

#endif  // CHROME_FRAME_UTILS_H_
