/*
 * QEMU Guest Agent win32 VSS Provider implementations
 *
 * Copyright Hitachi Data Systems Corp. 2013
 *
 * Authors:
 *  Tomoki Sekiyama   <tomoki.sekiyama@hds.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "vss-common.h"
#include "vss-debug.h"
#ifdef HAVE_VSS_SDK
#include <vscoordint.h>
#else
#include <vsadmin.h>
#endif
#include <vsprov.h>

#define VSS_TIMEOUT_MSEC (60*1000)

static long g_nComObjsInUse;
HINSTANCE g_hinstDll;

/* VSS common GUID's */

const CLSID CLSID_VSSCoordinator = { 0xE579AB5F, 0x1CC4, 0x44b4,
    {0xBE, 0xD9, 0xDE, 0x09, 0x91, 0xFF, 0x06, 0x23} };
const IID IID_IVssAdmin = { 0x77ED5996, 0x2F63, 0x11d3,
    {0x8A, 0x39, 0x00, 0xC0, 0x4F, 0x72, 0xD8, 0xE3} };

const IID IID_IVssHardwareSnapshotProvider = { 0x9593A157, 0x44E9, 0x4344,
    {0xBB, 0xEB, 0x44, 0xFB, 0xF9, 0xB0, 0x6B, 0x10} };
const IID IID_IVssSoftwareSnapshotProvider = { 0x609e123e, 0x2c5a, 0x44d3,
    {0x8f, 0x01, 0x0b, 0x1d, 0x9a, 0x47, 0xd1, 0xff} };
const IID IID_IVssProviderCreateSnapshotSet = { 0x5F894E5B, 0x1E39, 0x4778,
    {0x8E, 0x23, 0x9A, 0xBA, 0xD9, 0xF0, 0xE0, 0x8C} };
const IID IID_IVssProviderNotifications = { 0xE561901F, 0x03A5, 0x4afe,
    {0x86, 0xD0, 0x72, 0xBA, 0xEE, 0xCE, 0x70, 0x04} };

const IID IID_IVssEnumObject = { 0xAE1C7110, 0x2F60, 0x11d3,
    {0x8A, 0x39, 0x00, 0xC0, 0x4F, 0x72, 0xD8, 0xE3} };


static void LockModule(BOOL lock)
{
    if (lock) {
        InterlockedIncrement(&g_nComObjsInUse);
    } else {
        InterlockedDecrement(&g_nComObjsInUse);
    }
}

/* Empty enumerator for VssObject */

class CQGAVSSEnumObject : public IVssEnumObject
{
public:
    STDMETHODIMP QueryInterface(REFIID riid, void **ppObj);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    /* IVssEnumObject Methods */
    STDMETHODIMP Next(
        ULONG celt, VSS_OBJECT_PROP *rgelt, ULONG *pceltFetched);
    STDMETHODIMP Skip(ULONG celt);
    STDMETHODIMP Reset(void);
    STDMETHODIMP Clone(IVssEnumObject **ppenum);

    /* CQGAVSSEnumObject Methods */
    CQGAVSSEnumObject();
    ~CQGAVSSEnumObject();

private:
    long m_nRefCount;
};

CQGAVSSEnumObject::CQGAVSSEnumObject()
{
    m_nRefCount = 0;
    LockModule(TRUE);
}

CQGAVSSEnumObject::~CQGAVSSEnumObject()
{
    LockModule(FALSE);
}

STDMETHODIMP CQGAVSSEnumObject::QueryInterface(REFIID riid, void **ppObj)
{
    if (riid == IID_IUnknown || riid == IID_IVssEnumObject) {
        *ppObj = static_cast<void*>(static_cast<IVssEnumObject*>(this));
        AddRef();
        return S_OK;
    }
    *ppObj = NULL;
    return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) CQGAVSSEnumObject::AddRef()
{
    return InterlockedIncrement(&m_nRefCount);
}

STDMETHODIMP_(ULONG) CQGAVSSEnumObject::Release()
{
    long nRefCount = InterlockedDecrement(&m_nRefCount);
    if (m_nRefCount == 0) {
        delete this;
    }
    return nRefCount;
}

STDMETHODIMP CQGAVSSEnumObject::Next(
    ULONG celt, VSS_OBJECT_PROP *rgelt, ULONG *pceltFetched)
{
    *pceltFetched = 0;
    return S_FALSE;
}

STDMETHODIMP CQGAVSSEnumObject::Skip(ULONG celt)
{
    return S_FALSE;
}

STDMETHODIMP CQGAVSSEnumObject::Reset(void)
{
    return S_OK;
}

STDMETHODIMP CQGAVSSEnumObject::Clone(IVssEnumObject **ppenum)
{
    return E_NOTIMPL;
}


/* QGAVssProvider */

class CQGAVssProvider :
    public IVssSoftwareSnapshotProvider,
    public IVssProviderCreateSnapshotSet,
    public IVssProviderNotifications
{
public:
    STDMETHODIMP QueryInterface(REFIID riid, void **ppObj);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    /* IVssSoftwareSnapshotProvider Methods */
    STDMETHODIMP SetContext(LONG lContext);
    STDMETHODIMP GetSnapshotProperties(
        VSS_ID SnapshotId, VSS_SNAPSHOT_PROP *pProp);
    STDMETHODIMP Query(
        VSS_ID QueriedObjectId, VSS_OBJECT_TYPE eQueriedObjectType,
        VSS_OBJECT_TYPE eReturnedObjectsType, IVssEnumObject **ppEnum);
    STDMETHODIMP DeleteSnapshots(
        VSS_ID SourceObjectId, VSS_OBJECT_TYPE eSourceObjectType,
        BOOL bForceDelete, LONG *plDeletedSnapshots,
        VSS_ID *pNondeletedSnapshotID);
    STDMETHODIMP BeginPrepareSnapshot(
        VSS_ID SnapshotSetId, VSS_ID SnapshotId,
        VSS_PWSZ pwszVolumeName, LONG lNewContext);
    STDMETHODIMP IsVolumeSupported(
        VSS_PWSZ pwszVolumeName, BOOL *pbSupportedByThisProvider);
    STDMETHODIMP IsVolumeSnapshotted(
        VSS_PWSZ pwszVolumeName, BOOL *pbSnapshotsPresent,
        LONG *plSnapshotCompatibility);
    STDMETHODIMP SetSnapshotProperty(
        VSS_ID SnapshotId, VSS_SNAPSHOT_PROPERTY_ID eSnapshotPropertyId,
        VARIANT vProperty);
    STDMETHODIMP RevertToSnapshot(VSS_ID SnapshotId);
    STDMETHODIMP QueryRevertStatus(VSS_PWSZ pwszVolume, IVssAsync **ppAsync);

    /* IVssProviderCreateSnapshotSet Methods */
    STDMETHODIMP EndPrepareSnapshots(VSS_ID SnapshotSetId);
    STDMETHODIMP PreCommitSnapshots(VSS_ID SnapshotSetId);
    STDMETHODIMP CommitSnapshots(VSS_ID SnapshotSetId);
    STDMETHODIMP PostCommitSnapshots(
        VSS_ID SnapshotSetId, LONG lSnapshotsCount);
    STDMETHODIMP PreFinalCommitSnapshots(VSS_ID SnapshotSetId);
    STDMETHODIMP PostFinalCommitSnapshots(VSS_ID SnapshotSetId);
    STDMETHODIMP AbortSnapshots(VSS_ID SnapshotSetId);

    /* IVssProviderNotifications Methods */
    STDMETHODIMP OnLoad(IUnknown *pCallback);
    STDMETHODIMP OnUnload(BOOL bForceUnload);

    /* CQGAVssProvider Methods */
    CQGAVssProvider();
    ~CQGAVssProvider();

private:
    long m_nRefCount;
};

CQGAVssProvider::CQGAVssProvider()
{
    m_nRefCount = 0;
    LockModule(TRUE);
}

CQGAVssProvider::~CQGAVssProvider()
{
    LockModule(FALSE);
}

STDMETHODIMP CQGAVssProvider::QueryInterface(REFIID riid, void **ppObj)
{
    if (riid == IID_IUnknown) {
        *ppObj = static_cast<void*>(this);
        AddRef();
        return S_OK;
    }
    if (riid == IID_IVssSoftwareSnapshotProvider) {
        *ppObj = static_cast<void*>(
            static_cast<IVssSoftwareSnapshotProvider*>(this));
        AddRef();
        return S_OK;
    }
    if (riid == IID_IVssProviderCreateSnapshotSet) {
        *ppObj = static_cast<void*>(
            static_cast<IVssProviderCreateSnapshotSet*>(this));
        AddRef();
        return S_OK;
    }
    if (riid == IID_IVssProviderNotifications) {
        *ppObj = static_cast<void*>(
            static_cast<IVssProviderNotifications*>(this));
        AddRef();
        return S_OK;
    }
    *ppObj = NULL;
    return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) CQGAVssProvider::AddRef()
{
    return InterlockedIncrement(&m_nRefCount);
}

STDMETHODIMP_(ULONG) CQGAVssProvider::Release()
{
    long nRefCount = InterlockedDecrement(&m_nRefCount);
    if (m_nRefCount == 0) {
        delete this;
    }
    return nRefCount;
}


/*
 * IVssSoftwareSnapshotProvider methods
 */

STDMETHODIMP CQGAVssProvider::SetContext(LONG lContext)
{
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::GetSnapshotProperties(
    VSS_ID SnapshotId, VSS_SNAPSHOT_PROP *pProp)
{
    return VSS_E_OBJECT_NOT_FOUND;
}

STDMETHODIMP CQGAVssProvider::Query(
    VSS_ID QueriedObjectId, VSS_OBJECT_TYPE eQueriedObjectType,
    VSS_OBJECT_TYPE eReturnedObjectsType, IVssEnumObject **ppEnum)
{
    try {
        *ppEnum = new CQGAVSSEnumObject;
    } catch (...) {
        return E_OUTOFMEMORY;
    }
    (*ppEnum)->AddRef();
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::DeleteSnapshots(
    VSS_ID SourceObjectId, VSS_OBJECT_TYPE eSourceObjectType,
    BOOL bForceDelete, LONG *plDeletedSnapshots, VSS_ID *pNondeletedSnapshotID)
{
    *plDeletedSnapshots = 0;
    *pNondeletedSnapshotID = SourceObjectId;
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::BeginPrepareSnapshot(
    VSS_ID SnapshotSetId, VSS_ID SnapshotId,
    VSS_PWSZ pwszVolumeName, LONG lNewContext)
{
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::IsVolumeSupported(
    VSS_PWSZ pwszVolumeName, BOOL *pbSupportedByThisProvider)
{
    HANDLE hEventFrozen;

    /* Check if a requester is qemu-ga by whether an event is created */
    hEventFrozen = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_FROZEN);
    if (!hEventFrozen) {
        *pbSupportedByThisProvider = FALSE;
        return S_OK;
    }
    CloseHandle(hEventFrozen);

    *pbSupportedByThisProvider = TRUE;
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::IsVolumeSnapshotted(VSS_PWSZ pwszVolumeName,
    BOOL *pbSnapshotsPresent, LONG *plSnapshotCompatibility)
{
    *pbSnapshotsPresent = FALSE;
    *plSnapshotCompatibility = 0;
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::SetSnapshotProperty(VSS_ID SnapshotId,
    VSS_SNAPSHOT_PROPERTY_ID eSnapshotPropertyId, VARIANT vProperty)
{
    return E_NOTIMPL;
}

STDMETHODIMP CQGAVssProvider::RevertToSnapshot(VSS_ID SnapshotId)
{
    return E_NOTIMPL;
}

STDMETHODIMP CQGAVssProvider::QueryRevertStatus(
    VSS_PWSZ pwszVolume, IVssAsync **ppAsync)
{
    return E_NOTIMPL;
}


/*
 * IVssProviderCreateSnapshotSet methods
 */

STDMETHODIMP CQGAVssProvider::EndPrepareSnapshots(VSS_ID SnapshotSetId)
{
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::PreCommitSnapshots(VSS_ID SnapshotSetId)
{
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::CommitSnapshots(VSS_ID SnapshotSetId)
{
    HRESULT hr = S_OK;
    HANDLE hEventFrozen, hEventThaw, hEventTimeout;

    hEventFrozen = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_FROZEN);
    if (!hEventFrozen) {
        return E_FAIL;
    }

    hEventThaw = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_THAW);
    if (!hEventThaw) {
        CloseHandle(hEventFrozen);
        return E_FAIL;
    }

    hEventTimeout = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_TIMEOUT);
    if (!hEventTimeout) {
        CloseHandle(hEventFrozen);
        CloseHandle(hEventThaw);
        return E_FAIL;
    }

    /* Send event to qemu-ga to notify filesystem is frozen */
    SetEvent(hEventFrozen);

    /* Wait until the snapshot is taken by the host. */
    if (WaitForSingleObject(hEventThaw, VSS_TIMEOUT_MSEC) != WAIT_OBJECT_0) {
        /* Send event to qemu-ga to notify the provider is timed out */
        SetEvent(hEventTimeout);
    }

    CloseHandle(hEventThaw);
    CloseHandle(hEventFrozen);
    CloseHandle(hEventTimeout);
    return hr;
}

STDMETHODIMP CQGAVssProvider::PostCommitSnapshots(
    VSS_ID SnapshotSetId, LONG lSnapshotsCount)
{
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::PreFinalCommitSnapshots(VSS_ID SnapshotSetId)
{
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::PostFinalCommitSnapshots(VSS_ID SnapshotSetId)
{
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::AbortSnapshots(VSS_ID SnapshotSetId)
{
    return S_OK;
}

/*
 * IVssProviderNotifications methods
 */

STDMETHODIMP CQGAVssProvider::OnLoad(IUnknown *pCallback)
{
    return S_OK;
}

STDMETHODIMP CQGAVssProvider::OnUnload(BOOL bForceUnload)
{
    return S_OK;
}


/*
 * CQGAVssProviderFactory class
 */

class CQGAVssProviderFactory : public IClassFactory
{
public:
    STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();
    STDMETHODIMP CreateInstance(
        IUnknown *pUnknownOuter, REFIID iid, void **ppv);
    STDMETHODIMP LockServer(BOOL lock) { return E_NOTIMPL; }

    CQGAVssProviderFactory();
    ~CQGAVssProviderFactory();

private:
    long m_nRefCount;
};

CQGAVssProviderFactory::CQGAVssProviderFactory()
{
    m_nRefCount = 0;
    LockModule(TRUE);
}

CQGAVssProviderFactory::~CQGAVssProviderFactory()
{
    LockModule(FALSE);
}

STDMETHODIMP CQGAVssProviderFactory::QueryInterface(REFIID riid, void **ppv)
{
    if (riid == IID_IUnknown || riid == IID_IClassFactory) {
        *ppv = static_cast<void*>(this);
        AddRef();
        return S_OK;
    }
    *ppv = NULL;
    return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) CQGAVssProviderFactory::AddRef()
{
    return InterlockedIncrement(&m_nRefCount);
}

STDMETHODIMP_(ULONG) CQGAVssProviderFactory::Release()
{
    long nRefCount = InterlockedDecrement(&m_nRefCount);
    if (m_nRefCount == 0) {
        delete this;
    }
    return nRefCount;
}

STDMETHODIMP CQGAVssProviderFactory::CreateInstance(
    IUnknown *pUnknownOuter, REFIID iid, void **ppv)
{
    CQGAVssProvider *pObj;

    if (pUnknownOuter) {
        return CLASS_E_NOAGGREGATION;
    }
    try {
        pObj = new CQGAVssProvider;
    } catch (...) {
        return E_OUTOFMEMORY;
    }
    HRESULT hr = pObj->QueryInterface(iid, ppv);
    if (FAILED(hr)) {
        delete pObj;
    }
    return hr;
}


/*
 * DLL functions
 */

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    CQGAVssProviderFactory *factory;
    try {
        factory = new CQGAVssProviderFactory;
    } catch (...) {
        return E_OUTOFMEMORY;
    }
    factory->AddRef();
    HRESULT hr = factory->QueryInterface(riid, ppv);
    factory->Release();
    return hr;
}

STDAPI DllCanUnloadNow()
{
    return g_nComObjsInUse == 0 ? S_OK : S_FALSE;
}

EXTERN_C
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved);

EXTERN_C
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved)
{
    qga_debug("begin, reason = %lu", dwReason);
    if (dwReason == DLL_PROCESS_ATTACH) {
        g_hinstDll = hinstDll;
        DisableThreadLibraryCalls(hinstDll);
    }
    qga_debug_end;
    return TRUE;
}
