/*
 * QEMU Guest Agent win32 VSS Provider installer
 *
 * 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 "install.h"
#include <wbemidl.h>
#include <comdef.h>
#include <comutil.h>
#include <sddl.h>
#include <winsvc.h>

#define BUFFER_SIZE 1024

extern HINSTANCE g_hinstDll;

const GUID CLSID_COMAdminCatalog = { 0xF618C514, 0xDFB8, 0x11d1,
    {0xA2, 0xCF, 0x00, 0x80, 0x5F, 0xC7, 0x92, 0x35} };
const GUID IID_ICOMAdminCatalog2 = { 0x790C6E0B, 0x9194, 0x4cc9,
    {0x94, 0x26, 0xA4, 0x8A, 0x63, 0x18, 0x56, 0x96} };
const GUID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,
    {0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} };
const GUID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,
    {0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} };

static void errmsg(DWORD err, const char *text)
{
    /*
     * `text' contains function call statement when errmsg is called via chk().
     * To make error message more readable, we cut off the text after '('.
     * If text doesn't contains '(', negative precision is given, which is
     * treated as though it were missing.
     */
    char *msg = NULL;
    const char *nul = strchr(text, '(');
    int len = nul ? nul - text : -1;

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                  FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                  NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                  (char *)&msg, 0, NULL);
    qga_debug("%.*s. (Error: %lx) %s", len, text, err, msg);
    LocalFree(msg);
}

static void errmsg_dialog(DWORD err, const char *text, const char *opt = "")
{
    char *msg, buf[512];

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                  FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                  NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                  (char *)&msg, 0, NULL);
    snprintf(buf, sizeof(buf), "%s%s. (Error: %lx) %s", text, opt, err, msg);
    MessageBox(NULL, buf, "Error from " QGA_PROVIDER_NAME, MB_OK|MB_ICONERROR);
    LocalFree(msg);
}

#define _chk(hr, status, msg, err_label)        \
    do {                                        \
        hr = (status);                          \
        if (FAILED(hr)) {                       \
            errmsg(hr, msg);                    \
            goto err_label;                     \
        }                                       \
    } while (0)

#define chk(status) _chk(hr, status, "Failed to " #status, out)

#if !defined(__MINGW64_VERSION_MAJOR) || !defined(__MINGW64_VERSION_MINOR) || \
    __MINGW64_VERSION_MAJOR * 100 + __MINGW64_VERSION_MINOR < 301
void __stdcall _com_issue_error(HRESULT hr)
{
    errmsg(hr, "Unexpected error in COM");
}
#endif

template<class T>
HRESULT put_Value(ICatalogObject *pObj, LPCWSTR name, T val)
{
    return pObj->put_Value(_bstr_t(name), _variant_t(val));
}

/* Lookup Administrators group name from winmgmt */
static HRESULT GetAdminName(_bstr_t *name)
{
    qga_debug_begin;

    HRESULT hr;
    COMPointer<IWbemLocator> pLoc;
    COMPointer<IWbemServices> pSvc;
    COMPointer<IEnumWbemClassObject> pEnum;
    COMPointer<IWbemClassObject> pWobj;
    ULONG returned;
    _variant_t var;

    chk(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
                         IID_IWbemLocator, (LPVOID *)pLoc.replace()));
    chk(pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, NULL,
                            0, 0, 0, pSvc.replace()));
    chk(CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
                          NULL, RPC_C_AUTHN_LEVEL_CALL,
                          RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE));
    chk(pSvc->ExecQuery(_bstr_t(L"WQL"),
                        _bstr_t(L"select * from Win32_Account where "
                                "SID='S-1-5-32-544' and localAccount=TRUE"),
                        WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
                        NULL, pEnum.replace()));
    if (!pEnum) {
        hr = E_FAIL;
        errmsg(hr, "Failed to query for Administrators");
        goto out;
    }
    chk(pEnum->Next(WBEM_INFINITE, 1, pWobj.replace(), &returned));
    if (returned == 0) {
        hr = E_FAIL;
        errmsg(hr, "No Administrators found");
        goto out;
    }

    chk(pWobj->Get(_bstr_t(L"Name"), 0, &var, 0, 0));
    try {
        *name = var;
    } catch(...) {
        hr = E_FAIL;
        errmsg(hr, "Failed to get name of Administrators");
        goto out;
    }

out:
    qga_debug_end;
    return hr;
}

/* Acquire group or user name by SID */
static HRESULT getNameByStringSID(
    const wchar_t *sid, LPWSTR buffer, LPDWORD bufferLen)
{
    qga_debug_begin;

    HRESULT hr = S_OK;
    PSID psid = NULL;
    SID_NAME_USE groupType;
    DWORD domainNameLen = BUFFER_SIZE;
    wchar_t domainName[BUFFER_SIZE];

    if (!ConvertStringSidToSidW(sid, &psid)) {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto out;
    }
    if (!LookupAccountSidW(NULL, psid, buffer, bufferLen,
                           domainName, &domainNameLen, &groupType)) {
        hr = HRESULT_FROM_WIN32(GetLastError());
        /* Fall through and free psid */
    }

    LocalFree(psid);

out:
    qga_debug_end;
    return hr;
}

/* Find and iterate QGA VSS provider in COM+ Application Catalog */
static HRESULT QGAProviderFind(
    HRESULT (*found)(ICatalogCollection *, int, void *), void *arg)
{
    qga_debug_begin;

    HRESULT hr;
    COMInitializer initializer;
    COMPointer<IUnknown> pUnknown;
    COMPointer<ICOMAdminCatalog2> pCatalog;
    COMPointer<ICatalogCollection> pColl;
    COMPointer<ICatalogObject> pObj;
    _variant_t var;
    long i, n;

    chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER,
                         IID_IUnknown, (void **)pUnknown.replace()));
    chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog2,
                                 (void **)pCatalog.replace()));
    chk(pCatalog->GetCollection(_bstr_t(L"Applications"),
                                (IDispatch **)pColl.replace()));
    chk(pColl->Populate());

    chk(pColl->get_Count(&n));
    for (i = n - 1; i >= 0; i--) {
        chk(pColl->get_Item(i, (IDispatch **)pObj.replace()));
        chk(pObj->get_Value(_bstr_t(L"Name"), &var));
        if (var == _variant_t(QGA_PROVIDER_LNAME)) {
            if (FAILED(found(pColl, i, arg))) {
                goto out;
            }
        }
    }
    chk(pColl->SaveChanges(&n));

out:
    qga_debug_end;
    return hr;
}

/* Count QGA VSS provider in COM+ Application Catalog */
static HRESULT QGAProviderCount(ICatalogCollection *coll, int i, void *arg)
{
    qga_debug_begin;

    (*(int *)arg)++;

    qga_debug_end;
    return S_OK;
}

/* Remove QGA VSS provider from COM+ Application Catalog Collection */
static HRESULT QGAProviderRemove(ICatalogCollection *coll, int i, void *arg)
{
    qga_debug_begin;
    HRESULT hr;

    qga_debug("Removing COM+ Application: %s", QGA_PROVIDER_NAME);
    chk(coll->Remove(i));
out:
    qga_debug_end;
    return hr;
}

/* Unregister this module from COM+ Applications Catalog */
STDAPI COMUnregister(void);
STDAPI COMUnregister(void)
{
    qga_debug_begin;

    HRESULT hr;

    DllUnregisterServer();
    chk(QGAProviderFind(QGAProviderRemove, NULL));
out:
    qga_debug_end;
    return hr;
}

/* Register this module to COM+ Applications Catalog */
STDAPI COMRegister(void);
STDAPI COMRegister(void)
{
    qga_debug_begin;

    HRESULT hr;
    COMInitializer initializer;
    COMPointer<IUnknown> pUnknown;
    COMPointer<ICOMAdminCatalog2> pCatalog;
    COMPointer<ICatalogCollection> pApps, pRoles, pUsersInRole;
    COMPointer<ICatalogObject> pObj;
    long n;
    _bstr_t name;
    _variant_t key;
    CHAR dllPath[MAX_PATH], tlbPath[MAX_PATH];
    bool unregisterOnFailure = false;
    int count = 0;
    DWORD bufferLen = BUFFER_SIZE;
    wchar_t buffer[BUFFER_SIZE];
    const wchar_t *administratorsGroupSID = L"S-1-5-32-544";
    const wchar_t *systemUserSID = L"S-1-5-18";

    if (!g_hinstDll) {
        errmsg(E_FAIL, "Failed to initialize DLL");
        qga_debug_end;
        return E_FAIL;
    }

    chk(QGAProviderFind(QGAProviderCount, (void *)&count));
    if (count) {
        qga_debug("QGA VSS Provider is already installed. Attempting to unregister first.");
        hr = COMUnregister();
        if (FAILED(hr)) {
            errmsg(hr, "Failed to unregister existing QGA VSS Provider. Aborting installation.");
            qga_debug_end;
            return E_ABORT;
        }
    }

    chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER,
                         IID_IUnknown, (void **)pUnknown.replace()));
    chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog2,
                                 (void **)pCatalog.replace()));

    /* Install COM+ Component */

    chk(pCatalog->GetCollection(_bstr_t(L"Applications"),
                                (IDispatch **)pApps.replace()));
    chk(pApps->Populate());
    chk(pApps->Add((IDispatch **)&pObj));
    chk(put_Value(pObj, L"Name",        QGA_PROVIDER_LNAME));
    chk(put_Value(pObj, L"Description", QGA_PROVIDER_LNAME));
    chk(put_Value(pObj, L"ApplicationAccessChecksEnabled", true));
    chk(put_Value(pObj, L"Authentication",                 short(6)));
    chk(put_Value(pObj, L"AuthenticationCapability",       short(2)));
    chk(put_Value(pObj, L"ImpersonationLevel",             short(2)));
    chk(pApps->SaveChanges(&n));

    /* The app should be deleted if something fails after SaveChanges */
    unregisterOnFailure = true;

    chk(pObj->get_Key(&key));

    if (!GetModuleFileName(g_hinstDll, dllPath, sizeof(dllPath))) {
        hr = HRESULT_FROM_WIN32(GetLastError());
        errmsg(hr, "GetModuleFileName failed");
        goto out;
    }
    n = strlen(dllPath);
    if (n < 3) {
        hr = E_FAIL;
        errmsg(hr, "Failed to lookup dll");
        goto out;
    }
    strcpy(tlbPath, dllPath);
    strcpy(tlbPath+n-3, "tlb");
    qga_debug("Registering " QGA_PROVIDER_NAME ": %s %s",
              dllPath, tlbPath);
    if (!PathFileExists(tlbPath)) {
        hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
        errmsg(hr, "Failed to lookup tlb");
        goto out;
    }

    chk(pCatalog->CreateServiceForApplication(
            _bstr_t(QGA_PROVIDER_LNAME), _bstr_t(QGA_PROVIDER_LNAME),
            _bstr_t(L"SERVICE_DEMAND_START"), _bstr_t(L"SERVICE_ERROR_NORMAL"),
            _bstr_t(L""), _bstr_t(L".\\localsystem"), _bstr_t(L""), FALSE));
    chk(pCatalog->InstallComponent(_bstr_t(QGA_PROVIDER_LNAME),
                                   _bstr_t(dllPath), _bstr_t(tlbPath),
                                   _bstr_t("")));

    /* Setup roles of the application */

    chk(getNameByStringSID(administratorsGroupSID, buffer, &bufferLen));
    chk(pApps->GetCollection(_bstr_t(L"Roles"), key,
                             (IDispatch **)pRoles.replace()));
    chk(pRoles->Populate());
    chk(pRoles->Add((IDispatch **)pObj.replace()));
    chk(put_Value(pObj, L"Name", buffer));
    chk(put_Value(pObj, L"Description", L"Administrators group"));
    chk(pRoles->SaveChanges(&n));
    chk(pObj->get_Key(&key));

    /* Setup users in the role */

    chk(pRoles->GetCollection(_bstr_t(L"UsersInRole"), key,
                              (IDispatch **)pUsersInRole.replace()));
    chk(pUsersInRole->Populate());

    chk(pUsersInRole->Add((IDispatch **)pObj.replace()));
    chk(GetAdminName(&name));
    chk(put_Value(pObj, L"User", _bstr_t(".\\") + name));

    bufferLen = BUFFER_SIZE;
    chk(getNameByStringSID(systemUserSID, buffer, &bufferLen));
    chk(pUsersInRole->Add((IDispatch **)pObj.replace()));
    chk(put_Value(pObj, L"User", buffer));
    chk(pUsersInRole->SaveChanges(&n));

out:
    if (unregisterOnFailure && FAILED(hr)) {
        COMUnregister();
    }

    qga_debug_end;
    return hr;
}

STDAPI_(void) CALLBACK DLLCOMRegister(HWND, HINSTANCE, LPSTR, int);
STDAPI_(void) CALLBACK DLLCOMRegister(HWND, HINSTANCE, LPSTR, int)
{
    HRESULT hr = COMRegister();
    if (FAILED(hr)) {
        exit(hr);
    }
}

STDAPI_(void) CALLBACK DLLCOMUnregister(HWND, HINSTANCE, LPSTR, int);
STDAPI_(void) CALLBACK DLLCOMUnregister(HWND, HINSTANCE, LPSTR, int)
{
    COMUnregister();
}

static BOOL CreateRegistryKey(LPCTSTR key, LPCTSTR value, LPCTSTR data)
{
    qga_debug_begin;

    HKEY  hKey;
    LONG  ret;
    DWORD size;

    ret = RegCreateKeyEx(HKEY_CLASSES_ROOT, key, 0, NULL,
        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
    if (ret != ERROR_SUCCESS) {
        goto out;
    }

    if (data != NULL) {
        size = strlen(data) + 1;
    } else {
        size = 0;
    }

    ret = RegSetValueEx(hKey, value, 0, REG_SZ, (LPBYTE)data, size);
    RegCloseKey(hKey);

out:
    qga_debug_end;
    if (ret != ERROR_SUCCESS) {
        /* As we cannot printf within DllRegisterServer(), show a dialog. */
        errmsg_dialog(ret, "Cannot add registry", key);
        return FALSE;
    }
    return TRUE;
}

/* Register this dll as a VSS provider */
STDAPI DllRegisterServer(void)
{
    qga_debug_begin;

    COMInitializer initializer;
    COMPointer<IVssAdmin> pVssAdmin;
    HRESULT hr = E_FAIL;
    char dllPath[MAX_PATH];
    char key[256];

    if (!g_hinstDll) {
        errmsg_dialog(hr, "Module instance is not available");
        goto out;
    }

    /* Add this module to registry */

    sprintf(key, "CLSID\\%s", g_szClsid);
    if (!CreateRegistryKey(key, NULL, g_szClsid)) {
        goto out;
    }

    if (!GetModuleFileName(g_hinstDll, dllPath, sizeof(dllPath))) {
        errmsg_dialog(GetLastError(), "GetModuleFileName failed");
        goto out;
    }

    sprintf(key, "CLSID\\%s\\InprocServer32", g_szClsid);
    if (!CreateRegistryKey(key, NULL, dllPath)) {
        goto out;
    }

    if (!CreateRegistryKey(key, "ThreadingModel", "Apartment")) {
        goto out;
    }

    sprintf(key, "CLSID\\%s\\ProgID", g_szClsid);
    if (!CreateRegistryKey(key, NULL, g_szProgid)) {
        goto out;
    }

    if (!CreateRegistryKey(g_szProgid, NULL, QGA_PROVIDER_NAME)) {
        goto out;
    }

    sprintf(key, "%s\\CLSID", g_szProgid);
    if (!CreateRegistryKey(key, NULL, g_szClsid)) {
        goto out;
    }

    hr = CoCreateInstance(CLSID_VSSCoordinator, NULL, CLSCTX_ALL,
                          IID_IVssAdmin, (void **)pVssAdmin.replace());
    if (FAILED(hr)) {
        errmsg_dialog(hr, "CoCreateInstance(VSSCoordinator) failed");
        goto out;
    }

    hr = pVssAdmin->RegisterProvider(g_gProviderId, CLSID_QGAVSSProvider,
                                     const_cast<WCHAR*>(QGA_PROVIDER_LNAME),
                                     VSS_PROV_SOFTWARE,
                                     const_cast<WCHAR*>(QGA_PROVIDER_VERSION),
                                     g_gProviderVersion);
    if (hr == (long int) VSS_E_PROVIDER_ALREADY_REGISTERED) {
        DllUnregisterServer();
        hr = pVssAdmin->RegisterProvider(g_gProviderId, CLSID_QGAVSSProvider,
                                         const_cast<WCHAR * >
                                         (QGA_PROVIDER_LNAME),
                                         VSS_PROV_SOFTWARE,
                                         const_cast<WCHAR * >
                                         (QGA_PROVIDER_VERSION),
                                         g_gProviderVersion);
    }

    if (FAILED(hr)) {
        errmsg_dialog(hr, "RegisterProvider failed");
    }

out:
    if (FAILED(hr)) {
        DllUnregisterServer();
    }

    qga_debug_end;
    return hr;
}

/* Unregister this VSS hardware provider from the system */
STDAPI DllUnregisterServer(void)
{
    qga_debug_begin;

    TCHAR key[256];
    COMInitializer initializer;
    COMPointer<IVssAdmin> pVssAdmin;

    HRESULT hr = CoCreateInstance(CLSID_VSSCoordinator,
                                  NULL, CLSCTX_ALL, IID_IVssAdmin,
                                  (void **)pVssAdmin.replace());
    if (SUCCEEDED(hr)) {
        hr = pVssAdmin->UnregisterProvider(g_gProviderId);
    } else {
        errmsg(hr, "CoCreateInstance(VSSCoordinator) failed");
    }

    sprintf(key, "CLSID\\%s", g_szClsid);
    SHDeleteKey(HKEY_CLASSES_ROOT, key);
    SHDeleteKey(HKEY_CLASSES_ROOT, g_szProgid);

    qga_debug_end;
    return S_OK; /* Uninstall should never fail */
}


/* Support function to convert ASCII string into BSTR (used in _bstr_t) */
#ifndef CONFIG_CONVERT_STRING_TO_BSTR
namespace _com_util
{
    BSTR WINAPI ConvertStringToBSTR(const char *ascii) {
        int len = strlen(ascii);
        BSTR bstr = SysAllocStringLen(NULL, len);

        if (!bstr) {
            return NULL;
        }

        if (mbstowcs(bstr, ascii, len) == (size_t)-1) {
            qga_debug("Failed to convert string '%s' into BSTR", ascii);
            bstr[0] = 0;
        }
        return bstr;
    }
}
#endif

/* Stop QGA VSS provider service using Winsvc API  */
STDAPI StopService(void)
{
    qga_debug_begin;

    HRESULT hr = S_OK;
    SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    SC_HANDLE service = NULL;

    if (!manager) {
        errmsg(E_FAIL, "Failed to open service manager");
        hr = E_FAIL;
        goto out;
    }
    service = OpenService(manager, QGA_PROVIDER_NAME, SC_MANAGER_ALL_ACCESS);

    if (!service) {
        errmsg(E_FAIL, "Failed to open service");
        hr =  E_FAIL;
        goto out;
    }
    if (!(ControlService(service, SERVICE_CONTROL_STOP, NULL))) {
        errmsg(E_FAIL, "Failed to stop service");
        hr = E_FAIL;
    }

out:
    CloseServiceHandle(service);
    CloseServiceHandle(manager);
    qga_debug_end;
    return hr;
}
