/*
 * Main DLL interface to WIA Device Manager
 *
 * Copyright 2009 Damjan Jovanovic
 *
 * 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 <stdio.h>

#include "objbase.h"
#include "winuser.h"
#include "winreg.h"
#include "advpub.h"
#include "olectl.h"
#include "rpcproxy.h"
#include "winsvc.h"

#include "wia_lh.h"
#include "initguid.h"

#include "wiaservc_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wia);

/* Handle to the base address of this DLL */
static HINSTANCE hInst;

/* Entry point for DLL */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason)
    {
        case DLL_WINE_PREATTACH:
            return FALSE;  /* prefer native version */
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hinstDLL);
            hInst = hinstDLL;
            break;
        case DLL_PROCESS_DETACH:
            break;
    }

    return TRUE;
}

static HRESULT init_register_strtable(STRTABLEA *strtable)
{
#define CLSID_EXPANSION_ENTRY(id) { "CLSID_" #id, &CLSID_ ## id }
    static const struct {
        const char *name;
        const CLSID *clsid;
    } expns[] =  {
        CLSID_EXPANSION_ENTRY(WiaDevMgr)
    };
#undef CLSID_EXPANSION_ENTRY
    static STRENTRYA pse[sizeof expns / sizeof expns[0]];
    DWORD i;

    strtable->cEntries = sizeof pse / sizeof pse[0];
    strtable->pse = pse;
    for (i = 0; i < strtable->cEntries; i++) {
        static const char dummy_sample[] = "{12345678-1234-1234-1234-123456789012}";
        const CLSID *clsid = expns[i].clsid;
        pse[i].pszName = wiaservc_strdup(expns[i].name);
        pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, sizeof dummy_sample);
        if (!pse[i].pszName || !pse[i].pszValue)
            return E_OUTOFMEMORY;
        sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
                clsid->Data1, clsid->Data2, clsid->Data3, clsid->Data4[0],
                clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], clsid->Data4[4],
                clsid->Data4[5], clsid->Data4[6], clsid->Data4[7]);
    }

    return S_OK;
}

static void cleanup_register_strtable(STRTABLEA *strtable)
{
    DWORD i;
    for (i = 0; i < strtable->cEntries; i++) {
        HeapFree(GetProcessHeap(), 0, strtable->pse[i].pszName);
        HeapFree(GetProcessHeap(), 0, strtable->pse[i].pszValue);
        if (!strtable->pse[i].pszName || !strtable->pse[i].pszValue)
            return;
    }
}

static HRESULT register_service(BOOL do_register)
{
    static const WCHAR name[] = { 's','t','i','s','v','c', 0 };
    static const WCHAR path[] = { 's','v','c','h','o','s','t','.','e','x','e',
                                  ' ','-','k',' ','i','m','g','s','v','c', 0 };
    SC_HANDLE scm, service;

    scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!scm)
        return SELFREG_E_CLASS;

    if (do_register)
        service = CreateServiceW(scm, name, name, SERVICE_ALL_ACCESS,
                                 SERVICE_WIN32_OWN_PROCESS,
                                 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
                                 path, NULL, NULL, NULL, NULL, NULL);
    else
        service = OpenServiceW(scm, name, DELETE);


    CloseServiceHandle(scm);
    if (service)
    {
        if (!do_register) DeleteService(service);
        CloseServiceHandle(service);
    }
    return S_OK;
}

/* Use an INF file to register or unregister the DLL */
static HRESULT register_server(BOOL do_register)
{
    HRESULT hr;
    STRTABLEA strtable;
    HMODULE hAdvpack;
    HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
    static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};

    TRACE("(%x)\n", do_register);

    hr = register_service(do_register);
    if (FAILED(hr)) {
        ERR("register_service failed: %d\n", GetLastError());
        return hr;
    }

    hAdvpack = LoadLibraryW(wszAdvpack);
    pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");

    hr = init_register_strtable(&strtable);
    if (SUCCEEDED(hr))
        hr = pRegInstall(hInst, do_register ? "RegisterDll" : "UnregisterDll",
                         &strtable);
    cleanup_register_strtable(&strtable);

    if (FAILED(hr))
        ERR("RegInstall failed: %08x\n", hr);

    return hr;
}

HRESULT WINAPI DllRegisterServer(void)
{
    HRESULT hr = __wine_register_resources( hInst, NULL );
    if (FAILED(hr)) return hr;
    return register_server(TRUE);
}

HRESULT WINAPI DllUnregisterServer(void)
{
    HRESULT hr = __wine_unregister_resources( hInst, NULL );
    if (FAILED(hr)) return hr;
    return register_server(FALSE);
}
