/******************************************************************************
 *
 * File-based ILockBytes implementation
 *
 * Copyright 1999 Thuy Nguyen
 * Copyright 2010 Vincent Povirk for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "objbase.h"
#include "ole2.h"

#include "storage32.h"

#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(storage);

typedef struct FileLockBytesImpl
{
    ILockBytes ILockBytes_iface;
    LONG ref;
    HANDLE hfile;
    DWORD flProtect;
    LPWSTR pwcsName;
} FileLockBytesImpl;

static const ILockBytesVtbl FileLockBytesImpl_Vtbl;

static inline FileLockBytesImpl *impl_from_ILockBytes(ILockBytes *iface)
{
    return CONTAINING_RECORD(iface, FileLockBytesImpl, ILockBytes_iface);
}

/***********************************************************
 * Prototypes for private methods
 */

/* Note that this evaluates a and b multiple times, so don't
 * pass expressions with side effects. */
#define ROUND_UP(a, b) ((((a) + (b) - 1)/(b))*(b))

/****************************************************************************
 *      GetProtectMode
 *
 * This function will return a protection mode flag for a file-mapping object
 * from the open flags of a file.
 */
static DWORD GetProtectMode(DWORD openFlags)
{
    switch(STGM_ACCESS_MODE(openFlags))
    {
    case STGM_WRITE:
    case STGM_READWRITE:
        return PAGE_READWRITE;
    }
    return PAGE_READONLY;
}

/******************************************************************************
 *      FileLockBytesImpl_Construct
 *
 * Initialize a big block object supported by a file.
 */
HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes)
{
  FileLockBytesImpl *This;
  WCHAR fullpath[MAX_PATH];

  if (hFile == INVALID_HANDLE_VALUE)
    return E_FAIL;

  This = HeapAlloc(GetProcessHeap(), 0, sizeof(FileLockBytesImpl));

  if (!This)
    return E_OUTOFMEMORY;

  This->ILockBytes_iface.lpVtbl = &FileLockBytesImpl_Vtbl;
  This->ref = 1;
  This->hfile = hFile;
  This->flProtect = GetProtectMode(openFlags);

  if(pwcsName) {
    if (!GetFullPathNameW(pwcsName, MAX_PATH, fullpath, NULL))
    {
      lstrcpynW(fullpath, pwcsName, MAX_PATH);
    }
    This->pwcsName = HeapAlloc(GetProcessHeap(), 0,
                              (lstrlenW(fullpath)+1)*sizeof(WCHAR));
    if (!This->pwcsName)
    {
       HeapFree(GetProcessHeap(), 0, This);
       return E_OUTOFMEMORY;
    }
    strcpyW(This->pwcsName, fullpath);
  }
  else
    This->pwcsName = NULL;

  *pLockBytes = &This->ILockBytes_iface;

  return S_OK;
}

/* ILockByte Interfaces */

static HRESULT WINAPI FileLockBytesImpl_QueryInterface(ILockBytes *iface, REFIID riid,
    void **ppvObject)
{
    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ILockBytes))
        *ppvObject = iface;
    else
    {
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppvObject);

    return S_OK;
}

static ULONG WINAPI FileLockBytesImpl_AddRef(ILockBytes *iface)
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI FileLockBytesImpl_Release(ILockBytes *iface)
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);
    ULONG ref;

    ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
    {
        CloseHandle(This->hfile);
        HeapFree(GetProcessHeap(), 0, This->pwcsName);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * It reads a block of information from the byte array at the specified
 * offset.
 *
 * See the documentation of ILockBytes for more info.
 */
static HRESULT WINAPI FileLockBytesImpl_ReadAt(
      ILockBytes* iface,
      ULARGE_INTEGER ulOffset,  /* [in] */
      void*          pv,        /* [length_is][size_is][out] */
      ULONG          cb,        /* [in] */
      ULONG*         pcbRead)   /* [out] */
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);
    ULONG bytes_left = cb;
    LPBYTE readPtr = pv;
    BOOL ret;
    LARGE_INTEGER offset;
    ULONG cbRead;

    TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbRead);

    /* verify a sane environment */
    if (!This) return E_FAIL;

    if (pcbRead)
        *pcbRead = 0;

    offset.QuadPart = ulOffset.QuadPart;

    ret = SetFilePointerEx(This->hfile, offset, NULL, FILE_BEGIN);

    if (!ret)
        return STG_E_READFAULT;

    while (bytes_left)
    {
        ret = ReadFile(This->hfile, readPtr, bytes_left, &cbRead, NULL);

        if (!ret || cbRead == 0)
            return STG_E_READFAULT;

        if (pcbRead)
            *pcbRead += cbRead;

        bytes_left -= cbRead;
        readPtr += cbRead;
    }

    TRACE("finished\n");
    return S_OK;
}

/******************************************************************************
 * This method is part of the ILockBytes interface.
 *
 * It writes the specified bytes at the specified offset.
 * position. If the file is too small, it will be resized.
 *
 * See the documentation of ILockBytes for more info.
 */
static HRESULT WINAPI FileLockBytesImpl_WriteAt(
      ILockBytes* iface,
      ULARGE_INTEGER ulOffset,    /* [in] */
      const void*    pv,          /* [size_is][in] */
      ULONG          cb,          /* [in] */
      ULONG*         pcbWritten)  /* [out] */
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);
    ULONG bytes_left = cb;
    const BYTE *writePtr = pv;
    BOOL ret;
    LARGE_INTEGER offset;
    ULONG cbWritten;

    TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbWritten);

    /* verify a sane environment */
    if (!This) return E_FAIL;

    if (This->flProtect != PAGE_READWRITE)
        return STG_E_ACCESSDENIED;

    if (pcbWritten)
        *pcbWritten = 0;

    offset.QuadPart = ulOffset.QuadPart;

    ret = SetFilePointerEx(This->hfile, offset, NULL, FILE_BEGIN);

    if (!ret)
        return STG_E_WRITEFAULT;

    while (bytes_left)
    {
        ret = WriteFile(This->hfile, writePtr, bytes_left, &cbWritten, NULL);

        if (!ret)
            return STG_E_WRITEFAULT;

        if (pcbWritten)
            *pcbWritten += cbWritten;

        bytes_left -= cbWritten;
        writePtr += cbWritten;
    }

    TRACE("finished\n");
    return S_OK;
}

static HRESULT WINAPI FileLockBytesImpl_Flush(ILockBytes* iface)
{
    return S_OK;
}

/******************************************************************************
 *      ILockBytes_SetSize
 *
 * Sets the size of the file.
 *
 */
static HRESULT WINAPI FileLockBytesImpl_SetSize(ILockBytes* iface, ULARGE_INTEGER newSize)
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);
    HRESULT hr = S_OK;
    LARGE_INTEGER newpos;

    TRACE("new size %u\n", newSize.u.LowPart);

    newpos.QuadPart = newSize.QuadPart;
    if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN))
    {
        SetEndOfFile(This->hfile);
    }

    return hr;
}

static HRESULT get_lock_error(void)
{
    switch (GetLastError())
    {
    case ERROR_LOCK_VIOLATION: return STG_E_LOCKVIOLATION; break;
    case ERROR_ACCESS_DENIED:  return STG_E_ACCESSDENIED; break;
    case ERROR_NOT_SUPPORTED:  return STG_E_INVALIDFUNCTION; break;
    default:
        FIXME("no mapping for error %d\n", GetLastError());
        return STG_E_INVALIDFUNCTION;
    }
}

static HRESULT WINAPI FileLockBytesImpl_LockRegion(ILockBytes* iface,
    ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);
    OVERLAPPED ol;
    DWORD lock_flags = LOCKFILE_FAIL_IMMEDIATELY;

    TRACE("ofs %u count %u flags %x\n", libOffset.u.LowPart, cb.u.LowPart, dwLockType);

    if (dwLockType & LOCK_WRITE)
        return STG_E_INVALIDFUNCTION;

    if (dwLockType & (LOCK_EXCLUSIVE|LOCK_ONLYONCE))
        lock_flags |= LOCKFILE_EXCLUSIVE_LOCK;

    ol.hEvent = 0;
    ol.u.s.Offset = libOffset.u.LowPart;
    ol.u.s.OffsetHigh = libOffset.u.HighPart;

    if (LockFileEx(This->hfile, lock_flags, 0, cb.u.LowPart, cb.u.HighPart, &ol))
        return S_OK;
    return get_lock_error();
}

HRESULT FileLockBytesImpl_LockRegionSync(ILockBytes* iface,
    ULARGE_INTEGER libOffset, ULARGE_INTEGER cb)
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);
    OVERLAPPED ol;

    if (iface->lpVtbl != &FileLockBytesImpl_Vtbl)
        return E_NOTIMPL;

    ol.hEvent = 0;
    ol.u.s.Offset = libOffset.u.LowPart;
    ol.u.s.OffsetHigh = libOffset.u.HighPart;

    if (LockFileEx(This->hfile, LOCKFILE_EXCLUSIVE_LOCK, 0, cb.u.LowPart, cb.u.HighPart, &ol))
        return S_OK;
    return get_lock_error();
}

static HRESULT WINAPI FileLockBytesImpl_UnlockRegion(ILockBytes* iface,
    ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);
    OVERLAPPED ol;

    TRACE("ofs %u count %u flags %x\n", libOffset.u.LowPart, cb.u.LowPart, dwLockType);

    if (dwLockType & LOCK_WRITE)
        return STG_E_INVALIDFUNCTION;

    ol.hEvent = 0;
    ol.u.s.Offset = libOffset.u.LowPart;
    ol.u.s.OffsetHigh = libOffset.u.HighPart;

    if (UnlockFileEx(This->hfile, 0, cb.u.LowPart, cb.u.HighPart, &ol))
        return S_OK;
    return get_lock_error();
}

static HRESULT WINAPI FileLockBytesImpl_Stat(ILockBytes* iface,
    STATSTG *pstatstg, DWORD grfStatFlag)
{
    FileLockBytesImpl* This = impl_from_ILockBytes(iface);

    if (!(STATFLAG_NONAME & grfStatFlag) && This->pwcsName)
    {
        pstatstg->pwcsName =
          CoTaskMemAlloc((lstrlenW(This->pwcsName)+1)*sizeof(WCHAR));

        strcpyW(pstatstg->pwcsName, This->pwcsName);
    }
    else
        pstatstg->pwcsName = NULL;

    pstatstg->type = STGTY_LOCKBYTES;

    pstatstg->cbSize.u.LowPart = GetFileSize(This->hfile, &pstatstg->cbSize.u.HighPart);
    /* FIXME: If the implementation is exported, we'll need to set other fields. */

    return S_OK;
}

static const ILockBytesVtbl FileLockBytesImpl_Vtbl = {
    FileLockBytesImpl_QueryInterface,
    FileLockBytesImpl_AddRef,
    FileLockBytesImpl_Release,
    FileLockBytesImpl_ReadAt,
    FileLockBytesImpl_WriteAt,
    FileLockBytesImpl_Flush,
    FileLockBytesImpl_SetSize,
    FileLockBytesImpl_LockRegion,
    FileLockBytesImpl_UnlockRegion,
    FileLockBytesImpl_Stat
};
