// 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,
  IE_11,
};

// 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();

// Returns true if the presence of
// <meta http-equiv="X-UA-Compatible" content="chrome=1">
// in HTML pages should be ignored
bool SkipMetadataCheck();

// 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_
