/*
 * QEMU Guest Agent win32 VSS Requester 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"
#include "requester.h"
#include "install.h"
#include <vswriter.h>
#include <vsbackup.h>

/* Max wait time for frozen event (VSS can only hold writes for 10 seconds) */
#define VSS_TIMEOUT_FREEZE_MSEC 60000

/* Call QueryStatus every 10 ms while waiting for frozen event */
#define VSS_TIMEOUT_EVENT_MSEC 10

#define DEFAULT_VSS_BACKUP_TYPE VSS_BT_FULL

#define err_set(e, err, fmt, ...) {                                         \
    (e)->error_setg_win32_wrapper((e)->errp, __FILE__, __LINE__, __func__,  \
                                   err, fmt, ## __VA_ARGS__);               \
    qga_debug(fmt, ## __VA_ARGS__);                                         \
}
/* Bad idea, works only when (e)->errp != NULL: */
#define err_is_set(e) ((e)->errp && *(e)->errp)
/* To lift this restriction, error_propagate(), like we do in QEMU code */

/* Handle to VSSAPI.DLL */
static HMODULE hLib;

/* Functions in VSSAPI.DLL */
typedef HRESULT(STDAPICALLTYPE * t_CreateVssBackupComponents)(
    OUT IVssBackupComponents**);
typedef void(APIENTRY * t_VssFreeSnapshotProperties)(IN VSS_SNAPSHOT_PROP*);
static t_CreateVssBackupComponents pCreateVssBackupComponents;
static t_VssFreeSnapshotProperties pVssFreeSnapshotProperties;

/* Variables used while applications and filesystes are frozen by VSS */
static struct QGAVSSContext {
    IVssBackupComponents *pVssbc;  /* VSS requester interface */
    IVssAsync *pAsyncSnapshot;     /* async info of VSS snapshot operation */
    HANDLE hEventFrozen;           /* notify fs/writer freeze from provider */
    HANDLE hEventThaw;             /* request provider to thaw */
    HANDLE hEventTimeout;          /* notify timeout in provider */
    int cFrozenVols;               /* number of frozen volumes */
} vss_ctx;

STDAPI requester_init(void)
{
    qga_debug_begin;

    COMInitializer initializer; /* to call CoInitializeSecurity */
    HRESULT hr = CoInitializeSecurity(
        NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
        RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL);
    if (FAILED(hr)) {
        qga_debug("failed to CoInitializeSecurity (error %lx)", hr);
        return hr;
    }

    hLib = LoadLibraryA("VSSAPI.DLL");
    if (!hLib) {
        qga_debug("failed to load VSSAPI.DLL");
        return HRESULT_FROM_WIN32(GetLastError());
    }

    pCreateVssBackupComponents = (t_CreateVssBackupComponents)
        GetProcAddress(hLib,
#ifdef _WIN64 /* 64bit environment */
        "?CreateVssBackupComponents@@YAJPEAPEAVIVssBackupComponents@@@Z"
#else /* 32bit environment */
        "?CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z"
#endif
        );
    if (!pCreateVssBackupComponents) {
        qga_debug("failed to get proc address from VSSAPI.DLL");
        return HRESULT_FROM_WIN32(GetLastError());
    }

    pVssFreeSnapshotProperties = (t_VssFreeSnapshotProperties)
        GetProcAddress(hLib, "VssFreeSnapshotProperties");
    if (!pVssFreeSnapshotProperties) {
        qga_debug("failed to get proc address from VSSAPI.DLL");
        return HRESULT_FROM_WIN32(GetLastError());
    }

    qga_debug_end;
    return S_OK;
}

static void requester_cleanup(void)
{
    qga_debug_begin;

    if (vss_ctx.hEventFrozen) {
        CloseHandle(vss_ctx.hEventFrozen);
        vss_ctx.hEventFrozen = NULL;
    }
    if (vss_ctx.hEventThaw) {
        CloseHandle(vss_ctx.hEventThaw);
        vss_ctx.hEventThaw = NULL;
    }
    if (vss_ctx.hEventTimeout) {
        CloseHandle(vss_ctx.hEventTimeout);
        vss_ctx.hEventTimeout = NULL;
    }
    if (vss_ctx.pAsyncSnapshot) {
        vss_ctx.pAsyncSnapshot->Release();
        vss_ctx.pAsyncSnapshot = NULL;
    }
    if (vss_ctx.pVssbc) {
        vss_ctx.pVssbc->Release();
        vss_ctx.pVssbc = NULL;
    }
    vss_ctx.cFrozenVols = 0;
    qga_debug_end;
}

STDAPI requester_deinit(void)
{
    qga_debug_begin;

    requester_cleanup();

    pCreateVssBackupComponents = NULL;
    pVssFreeSnapshotProperties = NULL;
    if (hLib) {
        FreeLibrary(hLib);
        hLib = NULL;
    }

    qga_debug_end;
    return S_OK;
}

static HRESULT WaitForAsync(IVssAsync *pAsync)
{
    qga_debug_begin;

    HRESULT ret, hr;

    do {
        hr = pAsync->Wait();
        if (FAILED(hr)) {
            ret = hr;
            break;
        }
        hr = pAsync->QueryStatus(&ret, NULL);
        if (FAILED(hr)) {
            ret = hr;
            break;
        }
    } while (ret == VSS_S_ASYNC_PENDING);

    qga_debug_end;
    return ret;
}

static void AddComponents(ErrorSet *errset)
{
    qga_debug_begin;

    unsigned int cWriters, i;
    VSS_ID id, idInstance, idWriter;
    BSTR bstrWriterName = NULL;
    VSS_USAGE_TYPE usage;
    VSS_SOURCE_TYPE source;
    unsigned int cComponents, c1, c2, j;
    COMPointer<IVssExamineWriterMetadata> pMetadata;
    COMPointer<IVssWMComponent> pComponent;
    PVSSCOMPONENTINFO info;
    HRESULT hr;

    hr = vss_ctx.pVssbc->GetWriterMetadataCount(&cWriters);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to get writer metadata count");
        goto out;
    }

    for (i = 0; i < cWriters; i++) {
        hr = vss_ctx.pVssbc->GetWriterMetadata(i, &id, pMetadata.replace());
        if (FAILED(hr)) {
            err_set(errset, hr, "failed to get writer metadata of %d/%d",
                             i, cWriters);
            goto out;
        }

        hr = pMetadata->GetIdentity(&idInstance, &idWriter,
                                    &bstrWriterName, &usage, &source);
        if (FAILED(hr)) {
            err_set(errset, hr, "failed to get identity of writer %d/%d",
                             i, cWriters);
            goto out;
        }

        hr = pMetadata->GetFileCounts(&c1, &c2, &cComponents);
        if (FAILED(hr)) {
            err_set(errset, hr, "failed to get file counts of %S",
                             bstrWriterName);
            goto out;
        }

        for (j = 0; j < cComponents; j++) {
            hr = pMetadata->GetComponent(j, pComponent.replace());
            if (FAILED(hr)) {
                err_set(errset, hr,
                                 "failed to get component %d/%d of %S",
                                 j, cComponents, bstrWriterName);
                goto out;
            }

            hr = pComponent->GetComponentInfo(&info);
            if (FAILED(hr)) {
                err_set(errset, hr,
                                 "failed to get component info %d/%d of %S",
                                 j, cComponents, bstrWriterName);
                goto out;
            }

            if (info->bSelectable) {
                hr = vss_ctx.pVssbc->AddComponent(idInstance, idWriter,
                                                  info->type,
                                                  info->bstrLogicalPath,
                                                  info->bstrComponentName);
                if (FAILED(hr)) {
                    err_set(errset, hr, "failed to add component %S(%S)",
                                     info->bstrComponentName, bstrWriterName);
                    goto out;
                }
            }
            SysFreeString(bstrWriterName);
            bstrWriterName = NULL;
            pComponent->FreeComponentInfo(info);
            info = NULL;
        }
    }
out:
    if (bstrWriterName) {
        SysFreeString(bstrWriterName);
    }
    if (pComponent && info) {
        pComponent->FreeComponentInfo(info);
    }
    qga_debug_end;
}

static DWORD get_reg_dword_value(HKEY baseKey, LPCSTR subKey, LPCSTR valueName,
                                 DWORD defaultData)
{
    qga_debug_begin;

    DWORD regGetValueError;
    DWORD dwordData;
    DWORD dataSize = sizeof(DWORD);

    regGetValueError = RegGetValue(baseKey, subKey, valueName, RRF_RT_DWORD,
                                   NULL, &dwordData, &dataSize);
    qga_debug_end;
    if (regGetValueError  != ERROR_SUCCESS) {
        return defaultData;
    }
    return dwordData;
}

static bool is_valid_vss_backup_type(VSS_BACKUP_TYPE vssBT)
{
    return (vssBT > VSS_BT_UNDEFINED && vssBT < VSS_BT_OTHER);
}

static VSS_BACKUP_TYPE get_vss_backup_type(
    VSS_BACKUP_TYPE defaultVssBT = DEFAULT_VSS_BACKUP_TYPE)
{
    qga_debug_begin;

    VSS_BACKUP_TYPE vssBackupType;

    vssBackupType = static_cast<VSS_BACKUP_TYPE>(
                            get_reg_dword_value(HKEY_LOCAL_MACHINE,
                                                QGA_PROVIDER_REGISTRY_ADDRESS,
                                                "VssOption",
                                                defaultVssBT));
    qga_debug_end;
    if (!is_valid_vss_backup_type(vssBackupType)) {
        return defaultVssBT;
    }
    return vssBackupType;
}

void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
{
    qga_debug_begin;

    COMPointer<IVssAsync> pAsync;
    HANDLE volume;
    HRESULT hr;
    LONG ctx;
    GUID guidSnapshotSet = GUID_NULL;
    SECURITY_DESCRIPTOR sd;
    SECURITY_ATTRIBUTES sa;
    WCHAR short_volume_name[64], *display_name = short_volume_name;
    DWORD wait_status;
    int num_fixed_drives = 0, i;
    int num_mount_points = 0;
    VSS_BACKUP_TYPE vss_bt = get_vss_backup_type();

    if (vss_ctx.pVssbc) { /* already frozen */
        *num_vols = 0;
        qga_debug("finished, already frozen");
        return;
    }

    CoInitialize(NULL);

    /* Allow unrestricted access to events */
    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = &sd;
    sa.bInheritHandle = FALSE;

    vss_ctx.hEventFrozen = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_FROZEN);
    if (!vss_ctx.hEventFrozen) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_FROZEN);
        goto out;
    }
    vss_ctx.hEventThaw = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_THAW);
    if (!vss_ctx.hEventThaw) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_THAW);
        goto out;
    }
    vss_ctx.hEventTimeout = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_TIMEOUT);
    if (!vss_ctx.hEventTimeout) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_TIMEOUT);
        goto out;
    }

    assert(pCreateVssBackupComponents != NULL);
    hr = pCreateVssBackupComponents(&vss_ctx.pVssbc);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to create VSS backup components");
        goto out;
    }

    hr = vss_ctx.pVssbc->InitializeForBackup();
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to initialize for backup");
        goto out;
    }

    hr = vss_ctx.pVssbc->SetBackupState(true, true, vss_bt, false);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to set backup state");
        goto out;
    }

    /*
     * Currently writable snapshots are not supported.
     * To prevent the final commit (which requires to write to snapshots),
     * ATTR_NO_AUTORECOVERY and ATTR_TRANSPORTABLE are specified here.
     */
    ctx = VSS_CTX_APP_ROLLBACK | VSS_VOLSNAP_ATTR_TRANSPORTABLE |
        VSS_VOLSNAP_ATTR_NO_AUTORECOVERY | VSS_VOLSNAP_ATTR_TXF_RECOVERY;
    hr = vss_ctx.pVssbc->SetContext(ctx);
    if (hr == (HRESULT)VSS_E_UNSUPPORTED_CONTEXT) {
        /* Non-server version of Windows doesn't support ATTR_TRANSPORTABLE */
        ctx &= ~VSS_VOLSNAP_ATTR_TRANSPORTABLE;
        hr = vss_ctx.pVssbc->SetContext(ctx);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to set backup context");
        goto out;
    }

    hr = vss_ctx.pVssbc->GatherWriterMetadata(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to gather writer metadata");
        goto out;
    }

    AddComponents(errset);
    if (err_is_set(errset)) {
        goto out;
    }

    hr = vss_ctx.pVssbc->StartSnapshotSet(&guidSnapshotSet);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to start snapshot set");
        goto out;
    }

    if (mountpoints) {
        PWCHAR volume_name_wchar;
        for (volList *list = (volList *)mountpoints; list; list = list->next) {
            size_t len = strlen(list->value) + 1;
            size_t converted = 0;
            VSS_ID pid;

            volume_name_wchar = new wchar_t[len];
            mbstowcs_s(&converted, volume_name_wchar, len,
                       list->value, _TRUNCATE);

            hr = vss_ctx.pVssbc->AddToSnapshotSet(volume_name_wchar,
                                                  g_gProviderId, &pid);
            if (FAILED(hr)) {
                err_set(errset, hr, "failed to add %S to snapshot set",
                        volume_name_wchar);
                delete[] volume_name_wchar;
                goto out;
            }
            num_mount_points++;

            delete[] volume_name_wchar;
        }

        if (num_mount_points == 0) {
            /* If there is no valid mount points, just exit. */
            goto out;
        }
    }

    if (!mountpoints) {
        volume = FindFirstVolumeW(short_volume_name, sizeof(short_volume_name));
        if (volume == INVALID_HANDLE_VALUE) {
            err_set(errset, hr, "failed to find first volume");
            goto out;
        }

        for (;;) {
            if (GetDriveTypeW(short_volume_name) == DRIVE_FIXED) {
                VSS_ID pid;
                hr = vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name,
                                                      g_gProviderId, &pid);
                if (FAILED(hr)) {
                    WCHAR volume_path_name[PATH_MAX];
                    if (GetVolumePathNamesForVolumeNameW(
                            short_volume_name, volume_path_name,
                            sizeof(volume_path_name), NULL) &&
                            *volume_path_name) {
                        display_name = volume_path_name;
                    }
                    err_set(errset, hr, "failed to add %S to snapshot set",
                            display_name);
                    FindVolumeClose(volume);
                    goto out;
                }
                num_fixed_drives++;
            }
            if (!FindNextVolumeW(volume, short_volume_name,
                                 sizeof(short_volume_name))) {
                FindVolumeClose(volume);
                break;
            }
        }

        if (num_fixed_drives == 0) {
            goto out; /* If there is no fixed drive, just exit. */
        }
    }

    qga_debug("preparing for backup");
    hr = vss_ctx.pVssbc->PrepareForBackup(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to prepare for backup");
        goto out;
    }

    hr = vss_ctx.pVssbc->GatherWriterStatus(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to gather writer status");
        goto out;
    }

    /*
     * Start VSS quiescing operations.
     * CQGAVssProvider::CommitSnapshots will kick vss_ctx.hEventFrozen
     * after the applications and filesystems are frozen.
     */
    qga_debug("do snapshot set");
    hr = vss_ctx.pVssbc->DoSnapshotSet(&vss_ctx.pAsyncSnapshot);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to do snapshot set");
        goto out;
    }

    /* Need to call QueryStatus several times to make VSS provider progress */
    for (i = 0; i < VSS_TIMEOUT_FREEZE_MSEC/VSS_TIMEOUT_EVENT_MSEC; i++) {
        HRESULT hr2 = vss_ctx.pAsyncSnapshot->QueryStatus(&hr, NULL);
        if (FAILED(hr2)) {
            err_set(errset, hr, "failed to do snapshot set");
            goto out;
        }
        if (hr != VSS_S_ASYNC_PENDING) {
            err_set(errset, E_FAIL,
                    "DoSnapshotSet exited without Frozen event");
            goto out;
        }
        wait_status = WaitForSingleObject(vss_ctx.hEventFrozen,
                                          VSS_TIMEOUT_EVENT_MSEC);
        if (wait_status != WAIT_TIMEOUT) {
            break;
        }
    }

    if (wait_status == WAIT_TIMEOUT) {
        err_set(errset, E_FAIL,
                "timeout when try to receive Frozen event from VSS provider");
        /* If we are here, VSS had timeout.
         * Don't call AbortBackup, just return directly.
         */
        goto out1;
    }

    if (wait_status != WAIT_OBJECT_0) {
        err_set(errset, E_FAIL,
                "couldn't receive Frozen event from VSS provider");
        goto out;
    }

    if (mountpoints) {
        *num_vols = vss_ctx.cFrozenVols = num_mount_points;
    } else {
        *num_vols = vss_ctx.cFrozenVols = num_fixed_drives;
    }

    qga_debug("end successful");
    return;

out:
    if (vss_ctx.pVssbc) {
        vss_ctx.pVssbc->AbortBackup();
    }

out1:
    requester_cleanup();
    CoUninitialize();

    qga_debug_end;
}


void requester_thaw(int *num_vols, void *mountpints, ErrorSet *errset)
{
    qga_debug_begin;
    COMPointer<IVssAsync> pAsync;

    if (!vss_ctx.hEventThaw) {
        /*
         * In this case, DoSnapshotSet is aborted or not started,
         * and no volumes must be frozen. We return without an error.
         */
        *num_vols = 0;
        qga_debug("finished, no volumes were frozen");

        return;
    }

    /* Tell the provider that the snapshot is finished. */
    SetEvent(vss_ctx.hEventThaw);

    assert(vss_ctx.pVssbc);
    assert(vss_ctx.pAsyncSnapshot);

    HRESULT hr = WaitForAsync(vss_ctx.pAsyncSnapshot);
    switch (hr) {
    case VSS_S_ASYNC_FINISHED:
        hr = vss_ctx.pVssbc->BackupComplete(pAsync.replace());
        if (SUCCEEDED(hr)) {
            hr = WaitForAsync(pAsync);
        }
        if (FAILED(hr)) {
            err_set(errset, hr, "failed to complete backup");
        }
        break;

    case (HRESULT)VSS_E_OBJECT_NOT_FOUND:
        /*
         * On Windows earlier than 2008 SP2 which does not support
         * VSS_VOLSNAP_ATTR_NO_AUTORECOVERY context, the final commit is not
         * skipped and VSS is aborted by VSS_E_OBJECT_NOT_FOUND. However, as
         * the system had been frozen until fsfreeze-thaw command was issued,
         * we ignore this error.
         */
        vss_ctx.pVssbc->AbortBackup();
        break;

    case VSS_E_UNEXPECTED_PROVIDER_ERROR:
        if (WaitForSingleObject(vss_ctx.hEventTimeout, 0) != WAIT_OBJECT_0) {
            err_set(errset, hr, "unexpected error in VSS provider");
            break;
        }
        /* fall through if hEventTimeout is signaled */

    case (HRESULT)VSS_E_HOLD_WRITES_TIMEOUT:
        err_set(errset, hr, "couldn't hold writes: "
                "fsfreeze is limited up to 10 seconds");
        break;

    default:
        err_set(errset, hr, "failed to do snapshot set");
    }

    if (err_is_set(errset)) {
        vss_ctx.pVssbc->AbortBackup();
    }
    *num_vols = vss_ctx.cFrozenVols;
    requester_cleanup();

    CoUninitialize();
    StopService();

    qga_debug_end;
}
