// Copyright (c) 2011 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 <windows.h>  // NOLINT
#include <fcntl.h>  // for _O_* constants
#include <fdi.h>

#include "chrome/installer/mini_installer/decompress.h"

namespace {

FNALLOC(Alloc) {
  return ::HeapAlloc(::GetProcessHeap(), 0, cb);
}

FNFREE(Free) {
  ::HeapFree(::GetProcessHeap(), 0, pv);
}

// Converts a wide string to utf8.  Set |len| to -1 if |str| is zero terminated
// and you want to convert the entire string.
// The returned string will have been allocated with Alloc(), so free it
// with a call to Free().
char* WideToUtf8(const wchar_t* str, int len) {
  char* ret = NULL;
  int size = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
  if (size) {
    if (len != -1)
      ++size;  // include space for the terminator.
    ret = reinterpret_cast<char*>(Alloc(size * sizeof(ret[0])));
    if (ret) {
      WideCharToMultiByte(CP_UTF8, 0, str, len, ret, size, NULL, NULL);
      if (len != -1)
        ret[size - 1] = '\0';  // terminate the string
    }
  }
  return ret;
}

wchar_t* Utf8ToWide(const char* str) {
  wchar_t* ret = NULL;
  int size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
  if (size) {
    ret = reinterpret_cast<wchar_t*>(Alloc(size * sizeof(ret[0])));
    if (ret)
      MultiByteToWideChar(CP_UTF8, 0, str, -1, ret, size);
  }
  return ret;
}

template <typename T>
class scoped_ptr {
 public:
  explicit scoped_ptr(T* a) : a_(a) {
  }
  ~scoped_ptr() {
    if (a_)
      Free(a_);
  }
  operator T*() {
    return a_;
  }
 private:
  T* a_;
};

FNOPEN(Open) {
  DWORD access = 0;
  DWORD disposition = 0;

  if (oflag & _O_RDWR) {
    access = GENERIC_READ | GENERIC_WRITE;
  } else if (oflag & _O_WRONLY) {
    access = GENERIC_WRITE;
  } else {
    access = GENERIC_READ;
  }

  if (oflag & _O_CREAT) {
    disposition = CREATE_ALWAYS;
  } else {
    disposition = OPEN_EXISTING;
  }

  scoped_ptr<wchar_t> path(Utf8ToWide(pszFile));
  HANDLE file = CreateFileW(path, access, FILE_SHARE_READ, NULL, disposition,
                            FILE_ATTRIBUTE_NORMAL, NULL);
  return reinterpret_cast<INT_PTR>(file);
}

FNREAD(Read) {
  DWORD read = 0;
  if (!::ReadFile(reinterpret_cast<HANDLE>(hf), pv, cb, &read, NULL))
    read = static_cast<DWORD>(-1L);
  return read;
}

FNWRITE(Write) {
  DWORD written = 0;
  if (!::WriteFile(reinterpret_cast<HANDLE>(hf), pv, cb, &written, NULL))
    written = static_cast<DWORD>(-1L);
  return written;
}

FNCLOSE(Close) {
  return ::CloseHandle(reinterpret_cast<HANDLE>(hf)) ? 0 : -1;
}

FNSEEK(Seek) {
  return ::SetFilePointer(reinterpret_cast<HANDLE>(hf), dist, NULL, seektype);
}

FNFDINOTIFY(Notify) {
  INT_PTR result = 0;

  // Since we will only ever be decompressing a single file at a time
  // we take a shortcut and provide a pointer to the wide destination file
  // of the file we want to write.  This way we don't have to bother with
  // utf8/wide conversion and concatenation of directory and file name.
  const wchar_t* destination = reinterpret_cast<const wchar_t*>(pfdin->pv);

  switch (fdint) {
    case fdintCOPY_FILE: {
      result = reinterpret_cast<INT_PTR>(::CreateFileW(destination,
          GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
          FILE_ATTRIBUTE_NORMAL, NULL));
      break;
    }

    case fdintCLOSE_FILE_INFO: {
      FILETIME file_time;
      FILETIME local;
      // Converts MS-DOS date and time values to a file time
      if (DosDateTimeToFileTime(pfdin->date, pfdin->time, &file_time) &&
          LocalFileTimeToFileTime(&file_time, &local)) {
        SetFileTime(reinterpret_cast<HANDLE>(pfdin->hf), &local, NULL, NULL);
      }

      result = !Close(pfdin->hf);
      pfdin->attribs &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN |
                        FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE;
      ::SetFileAttributes(destination, pfdin->attribs);
      break;
    }

    case fdintCABINET_INFO:
    case fdintENUMERATE:
      // OK. continue as normal.
      result = 0;
      break;

    case fdintPARTIAL_FILE:
    case fdintNEXT_CABINET:
    default:
      // Error case.
      result = -1;
      break;
  }

  return result;
}

// Module handle of cabinet.dll
HMODULE g_fdi = NULL;

// API prototypes.
typedef HFDI (DIAMONDAPI* FDICreateFn)(PFNALLOC alloc, PFNFREE free,
                                       PFNOPEN open, PFNREAD read,
                                       PFNWRITE write, PFNCLOSE close,
                                       PFNSEEK seek, int cpu_type, PERF perf);
typedef BOOL (DIAMONDAPI* FDIDestroyFn)(HFDI fdi);
typedef BOOL (DIAMONDAPI* FDICopyFn)(HFDI fdi, char* cab, char* cab_path,
                                     int flags, PFNFDINOTIFY notify,
                                     PFNFDIDECRYPT decrypt, void* context);
FDICreateFn g_FDICreate = NULL;
FDIDestroyFn g_FDIDestroy = NULL;
FDICopyFn g_FDICopy = NULL;

bool InitializeFdi() {
  if (!g_fdi) {
    // It has been observed that some users do not have the expected
    // environment variables set, so we try a couple that *should* always be
    // present and fallback to the default Windows install path if all else
    // fails.
    // The cabinet.dll should be available on all supported versions of Windows.
    static const wchar_t* const candidate_paths[] = {
      L"%WINDIR%\\system32\\cabinet.dll",
      L"%SYSTEMROOT%\\system32\\cabinet.dll",
      L"C:\\Windows\\system32\\cabinet.dll",
    };

    wchar_t path[MAX_PATH] = {0};
    for (int i = 0; i < arraysize(candidate_paths); ++i) {
      path[0] = L'\0';
      DWORD result = ::ExpandEnvironmentStringsW(candidate_paths[i],
                                                 path, arraysize(path));

      if (result > 0 && result <= arraysize(path))
        g_fdi = ::LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);

      if (g_fdi)
        break;
    }
  }

  if (g_fdi) {
    g_FDICreate =
        reinterpret_cast<FDICreateFn>(::GetProcAddress(g_fdi, "FDICreate"));
    g_FDIDestroy =
        reinterpret_cast<FDIDestroyFn>(::GetProcAddress(g_fdi, "FDIDestroy"));
    g_FDICopy =
        reinterpret_cast<FDICopyFn>(::GetProcAddress(g_fdi, "FDICopy"));
  }

  return g_FDICreate && g_FDIDestroy && g_FDICopy;
}

}  // namespace

namespace mini_installer {

bool Expand(const wchar_t* source, const wchar_t* destination) {
  if (!InitializeFdi())
    return false;

  // Start by splitting up the source path and convert to utf8 since the
  // cabinet API doesn't support wide strings.
  const wchar_t* source_name = source + lstrlenW(source);
  while (source_name > source && *source_name != L'\\')
    --source_name;
  if (source_name == source)
    return false;

  // Convert the name to utf8.
  source_name++;
  scoped_ptr<char> source_name_utf8(WideToUtf8(source_name, -1));
  // The directory part is assumed to have a trailing backslash.
  scoped_ptr<char> source_path_utf8(WideToUtf8(source, source_name - source));

  scoped_ptr<char> dest_utf8(WideToUtf8(destination, -1));
  if (!dest_utf8 || !source_name_utf8 || !source_path_utf8)
    return false;

  bool success = false;

  ERF erf = {0};
  HFDI fdi = g_FDICreate(&Alloc, &Free, &Open, &Read, &Write, &Close, &Seek,
                         cpuUNKNOWN, &erf);
  if (fdi) {
    if (g_FDICopy(fdi, source_name_utf8, source_path_utf8, 0,
                  &Notify, NULL, const_cast<wchar_t*>(destination))) {
      success = true;
    }
    g_FDIDestroy(fdi);
  }

  return success;
}

}  // namespace mini_installer
