/*
 * 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 <stdio.h>
#include "vss-common.h"
#include "inc/win2003/vscoordint.h"
#include "inc/win2003/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} };


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);
        hr = E_ABORT;
    }

    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)
{
    if (dwReason == DLL_PROCESS_ATTACH) {
        g_hinstDll = hinstDll;
        DisableThreadLibraryCalls(hinstDll);
    }
    return TRUE;
}
