// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "CookieManager.h"

#include <UrlMon.h>
#include <wininet.h>

#include "errorcodes.h"
#include "logging.h"

#include "BrowserCookie.h"
#include "HookProcessor.h"
#include "messages.h"
#include "StringUtilities.h"

#define TICKS_PER_SECOND 10000000
#define UNIX_TIME_OFFSET_SECONDS 11644473600L

namespace webdriver {

struct CookieSendMessageInfo {
  HWND window_handle;
  unsigned int message;
};

CookieManager::CookieManager(void) {
  this->window_handle_ = NULL;
}

CookieManager::~CookieManager(void) {
}

void CookieManager::Initialize(HWND window_handle) {
  LOG(TRACE) << "Entering CookieManager::Initialize";
  this->window_handle_ = window_handle;
}

bool CookieManager::IsAdvancedCookiesApi() {
  FARPROC address = NULL;
  HMODULE wininet_handle = ::GetModuleHandle(L"wininet");
  if (wininet_handle) {
    address = ::GetProcAddress(wininet_handle, "InternetGetCookieEx2");
  }
  return address != NULL;
}

int CookieManager::SetCookie(const std::string& url, 
                             const BrowserCookie& cookie) {
  std::string full_data = url + "|" + cookie.ToString();
  WPARAM set_flags = 0;
  if (cookie.is_httponly()) {
    set_flags = INTERNET_COOKIE_HTTPONLY;
  }

  HookSettings hook_settings;
  hook_settings.hook_procedure_name = "CookieWndProc";
  hook_settings.hook_procedure_type = WH_CALLWNDPROC;
  hook_settings.window_handle = this->window_handle_;
  hook_settings.communication_type = OneWay;

  HookProcessor hook;
  if (!hook.CanSetWindowsHook(this->window_handle_)) {
    LOG(WARN) << "Cannot set cookie because driver and browser are not the "
              << "same bit-ness.";
    return EUNHANDLEDERROR;
  }
  hook.Initialize(hook_settings);
  hook.PushData(StringUtilities::ToWString(full_data));
  ::SendMessage(this->window_handle_, WD_SET_COOKIE, set_flags, NULL);
  int status = HookProcessor::GetDataBufferSize();
  if (status != 0) {
    LOG(WARN) << "Setting cookie encountered error " << status;
    return EINVALIDCOOKIEDOMAIN;
  }
  return WD_SUCCESS;
}

int CookieManager::GetCookies(const std::string& url,
                              std::vector<BrowserCookie>* all_cookies) {
  LOG(TRACE) << "Entering CookieManager::GetCookies";
  std::wstring wide_url = StringUtilities::ToWString(url);
  CComPtr<IUri> parsed_url;
  ::CreateUri(wide_url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &parsed_url);
  DWORD url_scheme = 0;
  parsed_url->GetScheme(&url_scheme);
  bool is_secure_url = URL_SCHEME_HTTPS == url_scheme;

  HookSettings hook_settings;
  hook_settings.hook_procedure_name = "CookieWndProc";
  hook_settings.hook_procedure_type = WH_CALLWNDPROC;
  hook_settings.window_handle = this->window_handle_;
  hook_settings.communication_type = TwoWay;

  HookProcessor hook;
  if (!hook.CanSetWindowsHook(this->window_handle_)) {
    LOG(WARN) << "Cannot get cookies because driver and browser are not the "
              << "same bit-ness.";
    return EUNHANDLEDERROR;
  }
  hook.Initialize(hook_settings);

  bool supports_advanced_api = this->IsAdvancedCookiesApi();
  if (supports_advanced_api) {
    // The version of WinINet installed supports the InternetGetCookieEx2
    // API, which gets all cookies (session and persistent) at once.
    std::wstring raw_cookie_data =
        this->SendGetCookieMessage(wide_url,
                                   WD_GET_ALL_COOKIES,
                                   &hook);
    std::string all_cookies_list = StringUtilities::ToString(raw_cookie_data);
    std::map<std::string, BrowserCookie> cookies;
    this->ParseCookieList(all_cookies_list,
                          is_secure_url,
                          &cookies);
    std::map<std::string, BrowserCookie>::const_iterator cookie_iterator;
    for (cookie_iterator = cookies.begin();
         cookie_iterator != cookies.end();
         ++cookie_iterator) {
      all_cookies->push_back(cookie_iterator->second);
    }
  } else {
    // Get all cookies for the current URL visible to JavaScript.
    std::wstring scriptable_cookie_string = 
        this->SendGetCookieMessage(wide_url,
                                   WD_GET_SCRIPTABLE_COOKIES,
                                   &hook);
    std::map<std::string, std::string> scriptable_cookies;
    this->ParseCookieString(scriptable_cookie_string, &scriptable_cookies);

    // Get all cookies for the insecure version of the current URL,
    // which will include HttpOnly cookies.
    std::wstring insecure_cookie_string = 
        this->SendGetCookieMessage(wide_url,
                                   WD_GET_HTTPONLY_COOKIES,
                                   &hook);
    std::map<std::string, std::string> insecure_cookies;  
    this->ParseCookieString(insecure_cookie_string, &insecure_cookies);

    // Get all cookies for the current secure URL. This will include
    // HttpOnly cookies.
    std::wstring secure_cookie_string = 
        this->SendGetCookieMessage(wide_url,
                                   WD_GET_SECURE_COOKIES,
                                   &hook);
    std::map<std::string, std::string> secure_cookies;  
    this->ParseCookieString(secure_cookie_string, &secure_cookies);

    // Get all of the persistent cookie files in the cache for the 
    // URL currently being browsed.
    std::wstring file_list =
        this->SendGetCookieMessage(wide_url,
                                   WD_GET_COOKIE_CACHE_FILES,
                                   &hook);
    std::vector<std::wstring> files;
    StringUtilities::Split(file_list, L"|", &files);

    // Parse the persistent cookie files to produce a list of
    // cookies.
    std::map<std::string, BrowserCookie> persistent_cookies;
    std::vector<std::wstring>::const_iterator file_iterator;
    for (file_iterator = files.begin();
         file_iterator != files.end();
         ++file_iterator) {
      std::string cookie_file_contents = this->ReadCookieFile(*file_iterator);
      this->ParseCookieList(cookie_file_contents,
                            is_secure_url,
                            &persistent_cookies);
    }

    // Loop through the entire list of cookies, including HttpOnly and secure
    // cookies. If the cookie exists as a persistent cookie, use its data from
    // the cache. If the cookie is found in the list of cookies visible to 
    // JavaScript, set the HttpOnly property of the cookie to false. If the
    // cookie is found in the list of cookies set on the insecure version of
    // the URL, set the Secure property of the cookie to false.
    std::map<std::string, std::string>::const_iterator it = secure_cookies.begin();
    for (; it != secure_cookies.end(); ++it) {
      BrowserCookie browser_cookie;
      if (persistent_cookies.find(it->first) != persistent_cookies.end()) {
        browser_cookie = persistent_cookies[it->first];
      } else {
        browser_cookie.set_name(it->first);
        browser_cookie.set_value(it->second);
        browser_cookie.set_is_httponly(scriptable_cookies.find(it->first) == scriptable_cookies.end());
        browser_cookie.set_is_secure(insecure_cookies.find(it->first) == insecure_cookies.end());
      }
      all_cookies->push_back(browser_cookie);
    }
  }
  return WD_SUCCESS;
}

bool CookieManager::DeleteCookie(const std::string& url,
                                 const BrowserCookie& cookie) {
  std::wstring wide_url = StringUtilities::ToWString(url);
  CComPtr<IUri> uri_pointer;
  ::CreateUri(wide_url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);

  CComBSTR host_bstr;
  uri_pointer->GetHost(&host_bstr);
  std::wstring wide_domain = host_bstr;
  
  CComBSTR path_bstr;
  uri_pointer->GetPath(&path_bstr);
  std::wstring wide_path = path_bstr;

  std::string domain = StringUtilities::ToString(wide_domain);
  std::string path = StringUtilities::ToString(wide_path);

  // N.B., We can hard-code the value and expiration time, since
  // we are deleting the cookie. So the value will be "deleted",
  // and the expiration time will be 1000 milliseconds after the
  // zero date (or Thu 1 Jan 1970 00:00:01 GMT).
  BrowserCookie recursive_cookie = cookie.Copy();
  recursive_cookie.set_domain(domain);
  recursive_cookie.set_path(path);
  recursive_cookie.set_value("deleted");
  recursive_cookie.set_expiration_time(1000);
  return this->RecursivelyDeleteCookie(url, recursive_cookie);
}

bool CookieManager::RecursivelyDeleteCookie(const std::string& url,
                                            const BrowserCookie& cookie) {
  // TODO: Optimize this path from the recursive to only
  // call setting the cookie as often as needed.
  BrowserCookie recursive_cookie = cookie.Copy();
  recursive_cookie.set_domain("." + cookie.domain());
  return this->RecurseCookiePath(url, recursive_cookie);
}

bool CookieManager::RecurseCookiePath(const std::string& url,
                                      const BrowserCookie& cookie) {
  size_t number_of_characters = 0;
  size_t slash_index = cookie.path().find_last_of('/');
  size_t final_index = cookie.path().size() - 1;
  if (slash_index == final_index) {
    number_of_characters = slash_index;
  }
  else {
    number_of_characters = slash_index + 1;
  }

  if (slash_index != std::string::npos) {
    BrowserCookie path_cookie = cookie.Copy();
    path_cookie.set_path(cookie.path().substr(0, number_of_characters));
    bool deleted = this->RecurseCookiePath(url, path_cookie);
  }
  return this->RecurseCookieDomain(url, cookie);
}

bool CookieManager::RecurseCookieDomain(const std::string& url,
                                        const BrowserCookie& cookie) {
  int status = this->SetCookie(url, cookie);

  size_t dot_index = cookie.domain().find_first_of('.');
  if (dot_index == 0) {
    BrowserCookie first_dot_cookie = cookie.Copy();
    first_dot_cookie.set_domain(cookie.domain().substr(1));
    return this->RecurseCookieDomain(url, first_dot_cookie);
  } else if (dot_index != std::string::npos) {
    BrowserCookie no_dot_cookie = cookie.Copy();
    no_dot_cookie.set_domain(cookie.domain().substr(dot_index));
    return this->RecurseCookieDomain(url, no_dot_cookie);
  }

  BrowserCookie no_domain_cookie = cookie.Copy();
  no_domain_cookie.set_domain("");
  status = this->SetCookie(url, no_domain_cookie);
  return status == WD_SUCCESS;
}

std::string CookieManager::ReadCookieFile(const std::wstring& file_name) {
  LOG(TRACE) << "Entering CookieManager::ReadCookieFile";
  HANDLE file_handle = ::CreateFile(file_name.c_str(),
                                    GENERIC_READ,
                                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                                    NULL,
                                    OPEN_EXISTING,
                                    0,
                                    NULL);
  // Read the cookie file. Hopefully, we will never have a 2GB cookie file.
  DWORD file_size_high = 0;
  DWORD file_size_low = ::GetFileSize(file_handle, &file_size_high);
  std::vector<char> file_content(file_size_low + 1);
  DWORD bytes_read = 0;
  ::ReadFile(file_handle, &file_content[0], file_size_low, &bytes_read, NULL);
  ::CloseHandle(file_handle);

  // Null-terminate and convert to a string for easier manipulation.
  file_content[bytes_read - 1] = '\0';
  std::string cookie_file_contents = &file_content[0];
  return cookie_file_contents;
}

void CookieManager::ParseCookieList(const std::string& cookie_file_contents,
                                    const bool include_secure_cookies,
                                    std::map<std::string, BrowserCookie>* cookies) {
  LOG(TRACE) << "Entering CookieManager::ParseCookieList";

  // Each cookie in the file is a record structure separated by
  // a line containing a single asterisk ('*'). Split the file 
  // content on this delimiter, and parse each record.
  std::vector<std::string> persistent_cookie_strings;
  StringUtilities::Split(cookie_file_contents,
                         "\n*\n",
                         &persistent_cookie_strings);
  std::vector<std::string>::const_iterator cookie_string_iterator;
  for (cookie_string_iterator = persistent_cookie_strings.begin();
       cookie_string_iterator != persistent_cookie_strings.end();
       ++cookie_string_iterator) {
    BrowserCookie persistent_cookie = 
        this->ParseSingleCookie(*cookie_string_iterator);
    if (include_secure_cookies || !persistent_cookie.is_secure()) {
      // Omit the cookie if it's 'secure' flag is set and we are *not*
      // browsing using SSL.
      cookies->insert(
          std::pair<std::string, BrowserCookie>(persistent_cookie.name(),
          persistent_cookie));
    }
  }
}

BrowserCookie CookieManager::ParseSingleCookie(const std::string& cookie) {
  LOG(TRACE) << "Entering CookieManager::ParsePersistentCookieInfo";
  // Cookies represented by a structured string record type.
  // This structure is modeled after how some versions of IE
  // stored perisitent cookeis as files on disk. Each cookie
  // is represented by 8 lines in the file separated by line
  // feed (0xA) characters, with the following format:
  //
  //     cookie_name
  //     cookie_value
  //     cookie.domain.value/cookie/path/value/
  //     <integer representing cookie flags>
  //     <unsigned long representing the low 32 bits of expiration time>
  //     <unsigned long representing the high 32 bits of expiration time>
  //     <unsigned long representing the low 32 bits of last-modified time>
  //     <unsigned long representing the high 32 bits of last-modified time>
  //
  // Read each of these lines and set the appropriate values
  // in the resulting cookie object.
  std::vector<std::string> cookie_parts;
  StringUtilities::Split(cookie, "\n", &cookie_parts);

  BrowserCookie cookie_to_return;
  cookie_to_return.set_name(cookie_parts[0]);
  cookie_to_return.set_value(cookie_parts[1]);

  size_t position = cookie_parts[2].find_first_of("/");
  cookie_to_return.set_domain(cookie_parts[2].substr(0, position));
  cookie_to_return.set_path(cookie_parts[2].substr(position));

  int flags = atoi(cookie_parts[3].c_str());
  cookie_to_return.set_is_secure(INTERNET_COOKIE_IS_SECURE == (INTERNET_COOKIE_IS_SECURE & flags));
  cookie_to_return.set_is_httponly(INTERNET_COOKIE_HTTPONLY == (INTERNET_COOKIE_HTTPONLY & flags));

  if (cookie_parts[4].size() > 0 && cookie_parts[5].size() > 0) {
    unsigned long expiry_time_low = strtoul(cookie_parts[4].c_str(), NULL, 10);
    unsigned long expiry_time_high = strtoul(cookie_parts[5].c_str(), NULL, 10);
    unsigned long long expiration_time = (expiry_time_high * static_cast<long long>(pow(2.0, 32))) + expiry_time_low;

    // Cookie expiration time is stored in the file as the number
    // of 100-nanosecond ticks since 1 January 1601 12:00:00 AM GMT.
    // We need the number of seconds since 1 January 1970 12:00:00 AM GMT.
    // This is the conversion.
    unsigned long cookie_expiration_time = static_cast<unsigned long>((expiration_time / TICKS_PER_SECOND) - UNIX_TIME_OFFSET_SECONDS);
    cookie_to_return.set_expiration_time(cookie_expiration_time);
  }
  return cookie_to_return;
}

void CookieManager::ParseCookieString(const std::wstring& cookie_string,
                                      std::map<std::string, std::string>* cookies) {
  LOG(TRACE) << "Entering CookieManager::ParseCookieString";
  std::wstring cookie_string_copy = cookie_string;
  while (cookie_string_copy.size() > 0) {
    size_t cookie_delimiter_pos = cookie_string_copy.find(L"; ");
    std::wstring cookie = cookie_string_copy.substr(0, cookie_delimiter_pos);
    if (cookie_delimiter_pos == std::wstring::npos) {
      cookie_string_copy = L"";
    } else {
      cookie_string_copy = cookie_string_copy.substr(cookie_delimiter_pos + 2);
    }
    size_t cookie_separator_pos(cookie.find_first_of(L"="));
    std::string cookie_name(StringUtilities::ToString(cookie.substr(0, cookie_separator_pos)));
    std::string cookie_value(StringUtilities::ToString(cookie.substr(cookie_separator_pos + 1)));
    cookies->insert(std::pair<std::string, std::string>(cookie_name, cookie_value));
  }
}

std::wstring CookieManager::SendGetCookieMessage(const std::wstring& url, 
                                                 const unsigned int message,
                                                 HookProcessor* hook) {
  LOG(TRACE) << "Entering CookieManager::SendGetCookieMessage";
  hook->PushData(url);

  // Since the named pipe server has to wait for the named pipe client
  // injected into the browser to connect to it before reading the data,
  // and since SendMessage is synchronous, we need to send the message
  // from a different thread to avoid a deadlock.
  CookieSendMessageInfo info;
  info.window_handle = this->window_handle_;
  info.message = message;
  unsigned int thread_id = 0;
  HANDLE thread_handle = reinterpret_cast<HANDLE>(_beginthreadex(NULL,
                                                  0,
                                                  &CookieManager::ThreadProc,
                                                  reinterpret_cast<void*>(&info),
                                                  0,
                                                  &thread_id));
  if (thread_handle != NULL) {
    ::CloseHandle(thread_handle);
  } else {
    LOGERR(DEBUG) << "Unable to create thread";
  }
  std::vector<char> buffer(0);
  int bytes = hook->PullData(&buffer);
  std::wstring cookies = reinterpret_cast<const wchar_t*>(&buffer[0]);
  return cookies;
}

unsigned int WINAPI CookieManager::ThreadProc(LPVOID lpParameter) {
  LOG(TRACE) << "Entering CookieManager::ThreadProc";

  CookieSendMessageInfo* info = reinterpret_cast<CookieSendMessageInfo*>(lpParameter);
  DWORD process_id = ::GetCurrentProcessId();
  LRESULT result = ::SendMessage(info->window_handle,
                                 info->message,
                                 process_id,
                                 NULL);
  return 0;
}

} // namespace webdriver

#ifdef __cplusplus
extern "C" {
#endif

// In order to run the IE driver against versions of IE that do not include
// a version of WinINet.dll that supports the InternetGetCookiesEx2 API,
// we must access the API in a way that does not import it into our DLL.
// To that end, we duplicate the INTERNET_COOKIE2 structure here, and will
// call the API (if it exists) via GetModuleHandle and GetProcAddress.
typedef struct {
  PWSTR pwszName;
  PWSTR pwszValue;
  PWSTR pwszDomain;
  PWSTR pwszPath;
  DWORD dwFlags;
  FILETIME ftExpires;
  BOOL fExpiresSet;
} INTERNETCOOKIE2;

typedef void* (__stdcall *InternetFreeCookiesProc)(INTERNETCOOKIE2*, DWORD);
typedef DWORD(__stdcall *InternetGetCookieEx2Proc)(PCWSTR, PCWSTR, DWORD, INTERNETCOOKIE2**, PDWORD);

LRESULT CALLBACK CookieWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
  CWPSTRUCT* call_window_proc_struct = reinterpret_cast<CWPSTRUCT*>(lParam);
  if (WM_COPYDATA == call_window_proc_struct->message) {
    COPYDATASTRUCT* data = reinterpret_cast<COPYDATASTRUCT*>(call_window_proc_struct->lParam);
    webdriver::HookProcessor::CopyDataToBuffer(data->cbData, data->lpData);
  } else if (WD_GET_ALL_COOKIES == call_window_proc_struct->message) {
    std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer();
    int driver_process_id = static_cast<int>(call_window_proc_struct->wParam);

    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    DWORD scheme = 0;
    uri_pointer->GetScheme(&scheme);
    CComBSTR scheme_bstr;
    uri_pointer->GetSchemeName(&scheme_bstr);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    CComBSTR path_bstr;
    uri_pointer->GetPath(&path_bstr);
    
    std::wstring parsed_uri = scheme_bstr;
    parsed_uri.append(L"://");
    parsed_uri.append(host_bstr);
    parsed_uri.append(path_bstr);

    InternetGetCookieEx2Proc get_cookie_proc = NULL;
    InternetFreeCookiesProc free_cookies_proc = NULL;
    HMODULE wininet_handle = ::GetModuleHandle(L"wininet");
    if (wininet_handle) {
      get_cookie_proc = reinterpret_cast<InternetGetCookieEx2Proc>(::GetProcAddress(wininet_handle, "InternetGetCookieEx2"));
      free_cookies_proc = reinterpret_cast<InternetFreeCookiesProc>(::GetProcAddress(wininet_handle, "InternetFreeCookies"));
    }

    DWORD cookie_count = 0;
    INTERNETCOOKIE2* cookie_pointer = NULL;
    DWORD success = 1;
    if (get_cookie_proc) {
      success = get_cookie_proc(parsed_uri.c_str(),
                                NULL,
                                INTERNET_COOKIE_NON_SCRIPT,
                                &cookie_pointer,
                                &cookie_count);
    }

    if (success == 0) {
      // Mimic the format of the old persistent cookie files for ease of
      // transmission back to the driver and parsing.
      std::wstring all_cookies = L"";
      for (DWORD cookie_index = 0; cookie_index < cookie_count; ++cookie_index) {
        if (all_cookies.size() > 0) {
          all_cookies.append(L"\n*\n");
        }
        INTERNETCOOKIE2* current_cookie = cookie_pointer + cookie_index;
        std::wstring cookie_name = L"";
        if (current_cookie->pwszName) {
          // Note that the spec appears to allow "nameless" cookies,
          // which clients like Selenium may not support.
          cookie_name = current_cookie->pwszName;
        }
        std::wstring cookie_value = L"";
        if (current_cookie->pwszValue) {
          cookie_value = current_cookie->pwszValue;
        }

        // TODO: The spec does not allow a cookie with an empty name
        // and value. It's unclear what the driver could do in this
        // case, but we should probably handle it somehow in the off
        // chance it ever comes up.
        std::wstring cookie_domain = L"";
        if (current_cookie->pwszDomain) {
          cookie_domain = current_cookie->pwszDomain;
        }
        std::wstring cookie_path = L"";
        if (current_cookie->pwszPath) {
          cookie_path = current_cookie->pwszPath;
        }
        DWORD flags = current_cookie->dwFlags;
        FILETIME expires = current_cookie->ftExpires;
        all_cookies.append(cookie_name).append(L"\n");
        all_cookies.append(cookie_value).append(L"\n");
        all_cookies.append(cookie_domain).append(L"/").append(cookie_path).append(L"\n");
        all_cookies.append(std::to_wstring(flags)).append(L"\n");
        // If the expiration time is set, add it to the string for the cookie.
        // If not, append empty fields to the record so subsequent parsing
        // of the string will still work.
        if (current_cookie->fExpiresSet) {
          all_cookies.append(std::to_wstring(expires.dwLowDateTime)).append(L"\n");
          all_cookies.append(std::to_wstring(expires.dwHighDateTime)).append(L"\n");
        } else {
          all_cookies.append(L"\n\n");
        }
      }
      free_cookies_proc(cookie_pointer, cookie_count);
      webdriver::HookProcessor::CopyWStringToBuffer(all_cookies);
    } else {
      webdriver::HookProcessor::SetDataBufferSize(sizeof(wchar_t));
    }
    webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
  } else if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ||
             WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message ||
             WD_GET_SECURE_COOKIES == call_window_proc_struct->message) {
    std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer();
    int driver_process_id = static_cast<int>(call_window_proc_struct->wParam);

    DWORD get_cookie_flags = 0;
    if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ||
      WD_GET_SECURE_COOKIES == call_window_proc_struct->message) {
      get_cookie_flags = INTERNET_COOKIE_HTTPONLY;
    }

    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    DWORD scheme = 0;
    uri_pointer->GetScheme(&scheme);
    CComBSTR scheme_bstr;
    uri_pointer->GetSchemeName(&scheme_bstr);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    CComBSTR path_bstr;
    uri_pointer->GetPath(&path_bstr);

    // Get only the cookies for the base URL, omitting port, if there is one.
    // N.B., we only return cookies secure cookies when browsing a site using
    // SSL. The browser won't see cookies with the 'secure' flag for sites
    // visited using plain http.
    std::wstring parsed_uri = L"http";
    if ((WD_GET_SECURE_COOKIES == call_window_proc_struct->message ||
         WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message) &&
        URL_SCHEME_HTTPS == scheme) {
      parsed_uri.append(L"s");
    }
    parsed_uri.append(L"://");
    parsed_uri.append(host_bstr);
    parsed_uri.append(path_bstr);

    // Call InternetGetCookieEx once to get the size of the buffer needed,
    // then call again with the appropriately sized buffer allocated.
    DWORD buffer_size = 0;
    BOOL success = ::InternetGetCookieEx(parsed_uri.c_str(),
                                         NULL,
                                         NULL,
                                         &buffer_size,
                                         get_cookie_flags,
                                         NULL);
    if (success) {
      webdriver::HookProcessor::SetDataBufferSize(buffer_size);
      ::InternetGetCookieEx(parsed_uri.c_str(),
                            NULL,
                            reinterpret_cast<LPTSTR>(webdriver::HookProcessor::GetDataBufferAddress()),
                            &buffer_size,
                            get_cookie_flags,
                            NULL);

      webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
    } else {
      if (ERROR_NO_MORE_ITEMS == ::GetLastError()) {
        webdriver::HookProcessor::SetDataBufferSize(sizeof(wchar_t));
        webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
      }
    }
  } else if (WD_GET_COOKIE_CACHE_FILES == call_window_proc_struct->message) {
    int driver_process_id = static_cast<int>(call_window_proc_struct->wParam);
    std::wstring file_list = L"";
    std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer();

    // We need to remove the port to find the entry in the cache.
    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    CComBSTR path_bstr;
    uri_pointer->GetPath(&path_bstr);
    std::wstring parsed_uri = host_bstr;
    parsed_uri.append(path_bstr);

    // A 2048-byte buffer should be large enough to handle cookie
    // cache entries in all but the most extreme cases.
    HANDLE cache_enum_handle = NULL;
    DWORD entry_size = 2048;
    LPINTERNET_CACHE_ENTRY_INFO entry = NULL;
    std::vector<char> entry_buffer(entry_size);
    entry = reinterpret_cast<INTERNET_CACHE_ENTRY_INFO*>(&entry_buffer[0]);
    cache_enum_handle = ::FindFirstUrlCacheEntry(L"cookie:",
                                                 entry,
                                                 &entry_size);
    if (cache_enum_handle == NULL &&
        ERROR_INSUFFICIENT_BUFFER == ::GetLastError()) {
      entry_buffer.resize(entry_size);
      entry = reinterpret_cast<INTERNET_CACHE_ENTRY_INFO*>(&entry_buffer[0]);
      cache_enum_handle = ::FindFirstUrlCacheEntry(L"cookie:",
                                                   entry,
                                                   &entry_size);
    }
    while (cache_enum_handle != NULL) {
      if (COOKIE_CACHE_ENTRY == (entry->CacheEntryType & COOKIE_CACHE_ENTRY)) {
        std::wstring name = entry->lpszSourceUrlName;
        size_t name_separator_pos(name.find_first_of(L"@"));
        std::wstring domain = name.substr(name_separator_pos + 1);
        if (parsed_uri.find(domain) != std::wstring::npos) {
          if (file_list.size() > 0) {
            file_list.append(L"|");
          }
          file_list.append(entry->lpszLocalFileName);
        }
      }
      BOOL success = ::FindNextUrlCacheEntry(cache_enum_handle,
                                             entry,
                                             &entry_size);
      if (!success) {
        DWORD error = ::GetLastError();
        if (ERROR_INSUFFICIENT_BUFFER == error) {
          entry_buffer.resize(entry_size);
          BOOL other_success = ::FindNextUrlCacheEntry(cache_enum_handle,
                                                       entry,
                                                       &entry_size);
        } else if (ERROR_NO_MORE_ITEMS == error) {
          ::FindCloseUrlCache(cache_enum_handle);
          cache_enum_handle = NULL;
        }
      }
    }
    webdriver::HookProcessor::CopyWStringToBuffer(file_list);
    webdriver::HookProcessor::WriteBufferToPipe(driver_process_id);
  } else if (WD_SET_COOKIE == call_window_proc_struct->message) {
    DWORD set_cookie_flags = static_cast<DWORD>(call_window_proc_struct->wParam);
    std::wstring cookie_data = webdriver::HookProcessor::CopyWStringFromBuffer();
    size_t url_separator_pos = cookie_data.find_first_of(L"|");
    std::wstring url = cookie_data.substr(0, url_separator_pos);
    std::wstring cookie = cookie_data.substr(url_separator_pos + 1);

    CComPtr<IUri> uri_pointer;
    HRESULT hr = ::CreateUri(url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &uri_pointer);
    CComBSTR scheme_bstr;
    uri_pointer->GetSchemeName(&scheme_bstr);
    CComBSTR host_bstr;
    uri_pointer->GetHost(&host_bstr);
    std::wstring parsed_uri = scheme_bstr;
    parsed_uri.append(L"://");
    parsed_uri.append(host_bstr);

    // Leverage the shared data buffer size to return the error code
    // back to the driver, if necessary.
    DWORD cookie_set = ::InternetSetCookieEx(parsed_uri.c_str(),
                                             NULL,
                                             cookie.c_str(),
                                             set_cookie_flags,
                                             NULL);
    if (cookie_set) {
      webdriver::HookProcessor::SetDataBufferSize(0);
    } else {
      DWORD error = ::GetLastError();
      webdriver::HookProcessor::SetDataBufferSize(error);
    }
  }
  return ::CallNextHookEx(NULL, nCode, wParam, lParam);
}

#ifdef __cplusplus
}
#endif
