/*
 *    Gameux library coclass GameExplorer implementation
 *
 * Copyright (C) 2010 Mariusz Pluciński
 *
 * 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
 */
#define COBJMACROS

#include "config.h"

#include "ole2.h"
#include "sddl.h"

#include "gameux.h"
#include "gameux_private.h"

#include "initguid.h"
#include "msxml2.h"

#include "wine/debug.h"
#include "winreg.h"

WINE_DEFAULT_DEBUG_CHANNEL(gameux);

/* function from Shell32, not defined in header */
extern BOOL WINAPI GUIDFromStringW(LPCWSTR psz, LPGUID pguid);

/*******************************************************************************
 * GameUX helper functions
 */
/*******************************************************************************
 * GAMEUX_initGameData
 *
 * Internal helper function.
 * Initializes GAME_DATA structure fields with proper values. Should be
 * called always before first usage of this structure. Implemented in gameexplorer.c
 *
 * Parameters:
 *  GameData                        [I/O]   pointer to structure to initialize
 */
static void GAMEUX_initGameData(struct GAMEUX_GAME_DATA *GameData)
{
    GameData->sGDFBinaryPath = NULL;
    GameData->sGameInstallDirectory = NULL;
    GameData->bstrName = NULL;
    GameData->bstrDescription = NULL;
}
/*******************************************************************************
 * GAMEUX_uninitGameData
 *
 * Internal helper function.
 * Properly frees all data stored or pointed by fields of GAME_DATA structure.
 * Should be called before freeing this structure. Implemented in gameexplorer.c
 *
 * Parameters:
 *  GameData                        [I/O]   pointer to structure to uninitialize
 */
static void GAMEUX_uninitGameData(struct GAMEUX_GAME_DATA *GameData)
{
    HeapFree(GetProcessHeap(), 0, GameData->sGDFBinaryPath);
    HeapFree(GetProcessHeap(), 0, GameData->sGameInstallDirectory);
    SysFreeString(GameData->bstrName);
    SysFreeString(GameData->bstrDescription);
}
/*******************************************************************************
 * GAMEUX_buildGameRegistryPath
 *
 * Internal helper function. Description available in gameux_private.h file
 */
HRESULT GAMEUX_buildGameRegistryPath(GAME_INSTALL_SCOPE installScope,
        LPCGUID gameInstanceId,
        LPWSTR* lpRegistryPath)
{
    static const WCHAR sGameUxRegistryPath[] = {'S','O','F','T','W','A','R','E','\\',
            'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
            'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','G','a','m','e','U','X',0};
    static const WCHAR sGames[] = {'G','a','m','e','s',0};
    static const WCHAR sBackslash[] = {'\\',0};

    HRESULT hr = S_OK;
    HANDLE hToken = NULL;
    PTOKEN_USER pTokenUser = NULL;
    DWORD dwLength;
    LPWSTR lpSID = NULL;
    WCHAR sInstanceId[40];
    WCHAR sRegistryPath[8192];

    TRACE("(0x%x, %s, %p)\n", installScope, debugstr_guid(gameInstanceId), lpRegistryPath);

    /* this will make freeing it easier for user */
    *lpRegistryPath = NULL;

    lstrcpyW(sRegistryPath, sGameUxRegistryPath);
    lstrcatW(sRegistryPath, sBackslash);

    if(installScope == GIS_CURRENT_USER)
    {
        /* build registry path containing user's SID */
        if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
            hr = HRESULT_FROM_WIN32(GetLastError());

        if(SUCCEEDED(hr))
        {
            if(!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) &&
                    GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
                hr = HRESULT_FROM_WIN32(GetLastError());

            if(SUCCEEDED(hr))
            {
                pTokenUser = HeapAlloc(GetProcessHeap(), 0, dwLength);
                if(!pTokenUser)
                    hr = E_OUTOFMEMORY;
            }

            if(SUCCEEDED(hr))
                if(!GetTokenInformation(hToken, TokenUser, (LPVOID)pTokenUser, dwLength, &dwLength))
                    hr = HRESULT_FROM_WIN32(GetLastError());

            if(SUCCEEDED(hr))
                if(!ConvertSidToStringSidW(pTokenUser->User.Sid, &lpSID))
                    hr = HRESULT_FROM_WIN32(GetLastError());

            if(SUCCEEDED(hr))
            {
                lstrcatW(sRegistryPath, lpSID);
                LocalFree(lpSID);
            }

            HeapFree(GetProcessHeap(), 0, pTokenUser);
            CloseHandle(hToken);
        }
    }
    else if(installScope == GIS_ALL_USERS)
        /* build registry path without SID */
        lstrcatW(sRegistryPath, sGames);
    else
        hr = E_INVALIDARG;

    /* put game's instance id on the end of path, only if instance id was given */
    if(gameInstanceId)
    {
        if(SUCCEEDED(hr))
            hr = (StringFromGUID2(gameInstanceId, sInstanceId, sizeof(sInstanceId)/sizeof(sInstanceId[0])) ? S_OK : E_FAIL);

        if(SUCCEEDED(hr))
        {
            lstrcatW(sRegistryPath, sBackslash);
            lstrcatW(sRegistryPath, sInstanceId);
        }
    }

    if(SUCCEEDED(hr))
    {
        *lpRegistryPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(sRegistryPath)+1)*sizeof(WCHAR));
        if(!*lpRegistryPath)
            hr = E_OUTOFMEMORY;
    }

    if(SUCCEEDED(hr))
        lstrcpyW(*lpRegistryPath, sRegistryPath);

    TRACE("result: 0x%x, path: %s\n", hr, debugstr_w(*lpRegistryPath));
    return hr;
}
/*******************************************************************************
 * GAMEUX_WriteRegistryRecord
 *
 * Helper function, writes data associated with game (stored in GAMEUX_GAME_DATA
 * structure) into expected place in registry.
 *
 * Parameters:
 *  GameData                            [I]     structure with data which will
 *                                              be written into registry.
 *                                              Proper values of fields installScope
 *                                              and guidInstanceId are required
 *                                              to create registry key.
 *
 * Schema of naming registry keys associated with games is available in
 * description of _buildGameRegistryPath internal function.
 *
 * List of registry keys associated with structure fields:
 *  Key                              Field in GAMEUX_GAME_DATA structure
 *   ApplicationId                    guidApplicationId
 *   ConfigApplicationPath            sGameInstallDirectory
 *   ConfigGDFBinaryPath              sGDFBinaryPath
 *   Title                            bstrName
 *
 */
static HRESULT GAMEUX_WriteRegistryRecord(struct GAMEUX_GAME_DATA *GameData)
{
    static const WCHAR sApplicationId[] =
            {'A','p','p','l','i','c','a','t','i','o','n','I','d',0};
    static const WCHAR sConfigApplicationPath[] =
            {'C','o','n','f','i','g','A','p','p','l','i','c','a','t','i','o','n','P','a','t','h',0};
    static const WCHAR sConfigGDFBinaryPath[] =
            {'C','o','n','f','i','g','G','D','F','B','i','n','a','r','y','P','a','t','h',0};
    static const WCHAR sTitle[] =
            {'T','i','t','l','e',0};
    static const WCHAR sDescription[] =
            {'D','e','s','c','r','i','p','t','i','o','n',0};

    HRESULT hr, hr2;
    LPWSTR lpRegistryKey;
    HKEY hKey;
    WCHAR sGameApplicationId[40];

    TRACE("(%p)\n", GameData);

    hr = GAMEUX_buildGameRegistryPath(GameData->installScope, &GameData->guidInstanceId, &lpRegistryKey);

    if(SUCCEEDED(hr))
        hr = (StringFromGUID2(&GameData->guidApplicationId, sGameApplicationId, sizeof(sGameApplicationId)/sizeof(sGameApplicationId[0])) ? S_OK : E_FAIL);

    if(SUCCEEDED(hr))
        hr = HRESULT_FROM_WIN32(RegCreateKeyExW(HKEY_LOCAL_MACHINE, lpRegistryKey,
                                                0, NULL, 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, NULL,
                                                &hKey, NULL));

    if(SUCCEEDED(hr))
    {
        /* write game data to registry key */
        hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, sConfigApplicationPath, 0,
                                               REG_SZ, (LPBYTE)(GameData->sGameInstallDirectory),
                                               (lstrlenW(GameData->sGameInstallDirectory)+1)*sizeof(WCHAR)));

        if(SUCCEEDED(hr))
            hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, sConfigGDFBinaryPath, 0,
                                                   REG_SZ, (LPBYTE)(GameData->sGDFBinaryPath),
                                                   (lstrlenW(GameData->sGDFBinaryPath)+1)*sizeof(WCHAR)));

        if(SUCCEEDED(hr))
            hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, sApplicationId, 0,
                                                   REG_SZ, (LPBYTE)(sGameApplicationId),
                                                   (lstrlenW(sGameApplicationId)+1)*sizeof(WCHAR)));

        if(SUCCEEDED(hr))
            hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, sTitle, 0,
                                                   REG_SZ, (LPBYTE)(GameData->bstrName),
                                                   (lstrlenW(GameData->bstrName)+1)*sizeof(WCHAR)));

        if(SUCCEEDED(hr))
            hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, sDescription, 0,
                                                   REG_SZ, (LPBYTE)(GameData->bstrDescription ? GameData->bstrDescription : GameData->bstrName),
                                                   (lstrlenW(GameData->bstrDescription ? GameData->bstrDescription : GameData->bstrName)+1)*sizeof(WCHAR)));

        RegCloseKey(hKey);

        if(FAILED(hr))
        {
            /* if something failed, remove whole key */
            hr2 = RegDeleteKeyExW(HKEY_LOCAL_MACHINE, lpRegistryKey, KEY_WOW64_64KEY, 0);
            /* do not overwrite old failure code with new success code */
            if(FAILED(hr2))
                hr = hr2;
        }
    }

    HeapFree(GetProcessHeap(), 0, lpRegistryKey);
    TRACE("returning 0x%x\n", hr);
    return hr;
}
/*******************************************************************************
 * GAMEUX_ProcessGameDefinitionElement
 *
 * Helper function, parses single element from Game Definition
 *
 * Parameters:
 *  lpXMLElement                        [I]     game definition element
 *  GameData                            [O]     structure, where parsed
 *                                              data will be stored
 */
static HRESULT GAMEUX_ProcessGameDefinitionElement(
        IXMLDOMElement *element,
        struct GAMEUX_GAME_DATA *GameData)
{
    static const WCHAR sName[] =
            {'N','a','m','e',0};
    static const WCHAR sDescription[] =
            {'D','e','s','c','r','i','p','t','i','o','n',0};

    HRESULT hr;
    BSTR bstrElementName;

    TRACE("(%p, %p)\n", element, GameData);

    hr = IXMLDOMElement_get_nodeName(element, &bstrElementName);
    if(SUCCEEDED(hr))
    {
        /* check element name */
        if(lstrcmpW(bstrElementName, sName) == 0)
            hr = IXMLDOMElement_get_text(element, &GameData->bstrName);

        else if(lstrcmpW(bstrElementName, sDescription) == 0)
            hr = IXMLDOMElement_get_text(element, &GameData->bstrDescription);

        else
            FIXME("entry %s in Game Definition File not yet supported\n", debugstr_w(bstrElementName));

        SysFreeString(bstrElementName);
    }

    return hr;
}
/*******************************************************************************
 * GAMEUX_ParseGameDefinition
 *
 * Helper function, loads data from given XML element into fields of GAME_DATA
 * structure
 *
 * Parameters:
 *  lpXMLGameDefinitionElement          [I]     Game Definition XML element
 *  GameData                            [O]     structure where data loaded from
 *                                              XML element will be stored in
 */
static HRESULT GAMEUX_ParseGameDefinition(
        IXMLDOMElement *gdElement,
        struct GAMEUX_GAME_DATA *GameData)
{
    static const WCHAR sGameId[] = {'g','a','m','e','I','D',0};

    HRESULT hr = S_OK;
    BSTR bstrAttribute;
    VARIANT variant;
    IXMLDOMNodeList *childrenList;
    IXMLDOMNode *nextNode;
    IXMLDOMElement *nextElement;

    TRACE("(%p, %p)\n", gdElement, GameData);

    bstrAttribute = SysAllocString(sGameId);
    if(!bstrAttribute)
        hr = E_OUTOFMEMORY;

    hr = IXMLDOMElement_getAttribute(gdElement, bstrAttribute, &variant);

    if(SUCCEEDED(hr))
    {
        hr = ( GUIDFromStringW(V_BSTR(&variant), &GameData->guidApplicationId)==TRUE ? S_OK : E_FAIL);

        SysFreeString(V_BSTR(&variant));
    }

    SysFreeString(bstrAttribute);

    /* browse subnodes */
    if(SUCCEEDED(hr))
        hr = IXMLDOMElement_get_childNodes(gdElement, &childrenList);

    if(SUCCEEDED(hr))
    {
        do
        {
            hr = IXMLDOMNodeList_nextNode(childrenList, &nextNode);

            if(hr == S_OK)
            {
                hr = IXMLDOMNode_QueryInterface(nextNode, &IID_IXMLDOMElement,
                                                (LPVOID*)&nextElement);

                if(SUCCEEDED(hr))
                {
                    hr = GAMEUX_ProcessGameDefinitionElement(nextElement, GameData);
                    IXMLDOMElement_Release(nextElement);
                }

                IXMLDOMNode_Release(nextNode);
            }
        }
        while(hr == S_OK);
        hr = S_OK;

        IXMLDOMNodeList_Release(childrenList);
    }

    return hr;
}

struct parse_gdf_thread_param
{
    struct GAMEUX_GAME_DATA *GameData;
    HRESULT hr;
};

/*******************************************************************************
 * GAMEUX_ParseGDFBinary
 *
 * Helper function, loads given binary and parses embed GDF if there's any.
 *
 * Parameters:
 *  GameData                [I/O]   Structure with game's data. Content of field
 *                                  sGDFBinaryPath defines path to binary, from
 *                                  which embed GDF will be loaded. Data from
 *                                  GDF will be stored in other fields of this
 *                                  structure.
 */
static DWORD WINAPI GAMEUX_ParseGDFBinary(void *thread_param)
{
    struct parse_gdf_thread_param *ctx = thread_param;
    struct GAMEUX_GAME_DATA *GameData = ctx->GameData;
    static const WCHAR sRes[] = {'r','e','s',':','/','/',0};
    static const WCHAR sDATA[] = {'D','A','T','A',0};
    static const WCHAR sSlash[] = {'/',0};

    HRESULT hr = S_OK;
    WCHAR sResourcePath[MAX_PATH];
    VARIANT variant;
    VARIANT_BOOL isSuccessful;
    IXMLDOMDocument *document;
    IXMLDOMNode *gdNode;
    IXMLDOMElement *root, *gdElement;

    TRACE("(%p)->sGDFBinaryPath = %s\n", GameData, debugstr_w(GameData->sGDFBinaryPath));

    /* prepare path to GDF, using res:// prefix */
    lstrcpyW(sResourcePath, sRes);
    lstrcatW(sResourcePath, GameData->sGDFBinaryPath);
    lstrcatW(sResourcePath, sSlash);
    lstrcatW(sResourcePath, sDATA);
    lstrcatW(sResourcePath, sSlash);
    lstrcatW(sResourcePath, ID_GDF_XML_STR);

    CoInitialize(NULL);

    hr = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
            &IID_IXMLDOMDocument, (void**)&document);

    if(SUCCEEDED(hr))
    {
        /* load GDF into MSXML */
        V_VT(&variant) = VT_BSTR;
        V_BSTR(&variant) = SysAllocString(sResourcePath);
        if(!V_BSTR(&variant))
            hr = E_OUTOFMEMORY;

        if(SUCCEEDED(hr))
        {
            hr = IXMLDOMDocument_load(document, variant, &isSuccessful);
            if(hr == S_FALSE || isSuccessful == VARIANT_FALSE)
                hr = E_FAIL;
        }

        SysFreeString(V_BSTR(&variant));

        if(SUCCEEDED(hr))
        {
            hr = IXMLDOMDocument_get_documentElement(document, &root);
            if(hr == S_FALSE)
                hr = E_FAIL;
        }

        if(SUCCEEDED(hr))
        {
            hr = IXMLDOMElement_get_firstChild(root, &gdNode);
            if(hr == S_FALSE)
                hr = E_FAIL;

            if(SUCCEEDED(hr))
            {
                hr = IXMLDOMNode_QueryInterface(gdNode, &IID_IXMLDOMElement, (LPVOID*)&gdElement);
                if(SUCCEEDED(hr))
                {
                    hr = GAMEUX_ParseGameDefinition(gdElement, GameData);
                    IXMLDOMElement_Release(gdElement);
                }

                IXMLDOMNode_Release(gdNode);
            }

            IXMLDOMElement_Release(root);
        }

        IXMLDOMDocument_Release(document);
    }

    CoUninitialize();
    ctx->hr = hr;
    return 0;
}

/*******************************************************************
 * GAMEUX_RemoveRegistryRecord
 *
 * Helper function, removes registry key associated with given game instance
 */
static HRESULT GAMEUX_RemoveRegistryRecord(GUID* pInstanceID)
{
    HRESULT hr;
    LPWSTR lpRegistryPath = NULL;
    TRACE("(%s)\n", debugstr_guid(pInstanceID));

    /* first, check is game installed for all users */
    hr = GAMEUX_buildGameRegistryPath(GIS_ALL_USERS, pInstanceID, &lpRegistryPath);
    if(SUCCEEDED(hr))
        hr = HRESULT_FROM_WIN32(RegDeleteKeyExW(HKEY_LOCAL_MACHINE, lpRegistryPath, KEY_WOW64_64KEY, 0));

    HeapFree(GetProcessHeap(), 0, lpRegistryPath);

    /* if not, check current user */
    if(FAILED(hr))
    {
        hr = GAMEUX_buildGameRegistryPath(GIS_CURRENT_USER, pInstanceID, &lpRegistryPath);
        if(SUCCEEDED(hr))
            hr = HRESULT_FROM_WIN32(RegDeleteKeyExW(HKEY_LOCAL_MACHINE, lpRegistryPath, KEY_WOW64_64KEY, 0));

        HeapFree(GetProcessHeap(), 0, lpRegistryPath);
    }

    return hr;
}
/*******************************************************************************
 *  GAMEUX_RegisterGame
 *
 * Internal helper function. Registers game associated with given GDF binary in
 * Game Explorer. Implemented in gameexplorer.c
 *
 * Parameters:
 *  sGDFBinaryPath                  [I]     path to binary containing GDF file in
 *                                          resources
 *  sGameInstallDirectory           [I]     path to directory, where game installed
 *                                          it's files.
 *  installScope                    [I]     scope of game installation
 *  pInstanceID                     [I/O]   pointer to game instance identifier.
 *                                          If pointing to GUID_NULL, then new
 *                                          identifier will be generated automatically
 *                                          and returned via this parameter
 */
static HRESULT GAMEUX_RegisterGame(LPCWSTR sGDFBinaryPath,
        LPCWSTR sGameInstallDirectory,
        GAME_INSTALL_SCOPE installScope,
        GUID *pInstanceID)
{
    HRESULT hr = S_OK;
    struct GAMEUX_GAME_DATA GameData;

    TRACE("(%s, %s, 0x%x, %s)\n", debugstr_w(sGDFBinaryPath), debugstr_w(sGameInstallDirectory), installScope, debugstr_guid(pInstanceID));

    GAMEUX_initGameData(&GameData);
    GameData.sGDFBinaryPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(sGDFBinaryPath)+1)*sizeof(WCHAR));
    lstrcpyW(GameData.sGDFBinaryPath, sGDFBinaryPath);
    GameData.sGameInstallDirectory = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(sGameInstallDirectory)+1)*sizeof(WCHAR));
    lstrcpyW(GameData.sGameInstallDirectory, sGameInstallDirectory);
    GameData.installScope = installScope;

    /* generate GUID if it was not provided by user */
    if(IsEqualGUID(pInstanceID, &GUID_NULL))
        hr = CoCreateGuid(pInstanceID);

    GameData.guidInstanceId = *pInstanceID;

    /* load data from GDF binary */
    if(SUCCEEDED(hr))
    {
        struct parse_gdf_thread_param thread_param;
        HANDLE thread;
        DWORD ret;

        thread_param.GameData = &GameData;
        if(!(thread = CreateThread(NULL, 0, GAMEUX_ParseGDFBinary, &thread_param, 0, &ret)))
        {
            ERR("Failed to create thread.\n");
            hr = E_FAIL;
            goto done;
        }
        ret = WaitForSingleObject(thread, INFINITE);
        CloseHandle(thread);
        if(ret != WAIT_OBJECT_0)
        {
            ERR("Wait failed (%#x).\n", ret);
            hr = E_FAIL;
            goto done;
        }
        hr = thread_param.hr;
    }

    /* save data to registry */
    if(SUCCEEDED(hr))
        hr = GAMEUX_WriteRegistryRecord(&GameData);

done:
    GAMEUX_uninitGameData(&GameData);
    TRACE("returning 0x%08x\n", hr);
    return hr;
}
/*******************************************************************************
 * GAMEUX_IsGameKeyExist
 *
 * Helper function, checks if game's registry ath exists in given scope
 *
 * Parameters:
 *  installScope            [I]     scope to search game in
 *  InstanceID              [I]     game instance identifier
 *  lpRegistryPath          [O]     place to store address of registry path to
 *                                  the game. It is filled only if key exists.
 *                                  It must be freed by HeapFree(GetProcessHeap(), 0, ...)
 *
 * Returns:
 *  S_OK                key was found properly
 *  S_FALSE             key does not exists
 *
 */
static HRESULT GAMEUX_IsGameKeyExist(GAME_INSTALL_SCOPE installScope,
    LPCGUID InstanceID,
    LPWSTR* lpRegistryPath) {

    HRESULT hr;
    HKEY hKey;

    hr = GAMEUX_buildGameRegistryPath(installScope, InstanceID, lpRegistryPath);

    if(SUCCEEDED(hr))
        hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_LOCAL_MACHINE, *lpRegistryPath,
                                              0, KEY_WOW64_64KEY, &hKey));

    if(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
        hr = S_FALSE;

    if(hr == S_OK)
        RegCloseKey(hKey);
    else
    {
        /* if the key does not exist or another error occurred, do not return the path */
        HeapFree(GetProcessHeap(), 0, *lpRegistryPath);
        *lpRegistryPath = NULL;
    }

    return hr;
}
/*******************************************************************************
 * GAMEUX_LoadRegistryString
 *
 * Helper function, loads string from registry value and allocates buffer for it
 */
static HRESULT GAMEUX_LoadRegistryString(HKEY hRootKey,
        LPCWSTR lpRegistryKey,
        LPCWSTR lpRegistryValue,
        LPWSTR* lpValue)
{
    HRESULT hr;
    DWORD dwSize;

    *lpValue = NULL;

    hr = HRESULT_FROM_WIN32(RegGetValueW(hRootKey, lpRegistryKey, lpRegistryValue,
            RRF_RT_REG_SZ, NULL, NULL, &dwSize));

    if(SUCCEEDED(hr))
    {
        *lpValue = HeapAlloc(GetProcessHeap(), 0, dwSize);
        if(!*lpValue)
            hr = E_OUTOFMEMORY;
    }

    if(SUCCEEDED(hr))
        hr = HRESULT_FROM_WIN32(RegGetValueW(hRootKey, lpRegistryKey, lpRegistryValue,
                RRF_RT_REG_SZ, NULL, *lpValue, &dwSize));

    return hr;
}
/*******************************************************************************
 * GAMEUX_UpdateGame
 *
 * Helper function, updates stored data about game with given InstanceID
 */
static HRESULT GAMEUX_UpdateGame(LPGUID InstanceID) {
    static const WCHAR sConfigGDFBinaryPath[] = {'C','o','n','f','i','g','G','D','F','B','i','n','a','r','y','P','a','t','h',0};
    static const WCHAR sConfigApplicationPath[] = {'C','o','n','f','i','g','A','p','p','l','i','c','a','t','i','o','n','P','a','t','h',0};

    HRESULT hr;
    GAME_INSTALL_SCOPE installScope;
    LPWSTR lpRegistryPath;
    LPWSTR lpGDFBinaryPath;

    TRACE("(%s)\n", debugstr_guid(InstanceID));

    /* first, check is game exists in CURRENT_USER scope  */
    installScope = GIS_CURRENT_USER;
    hr = GAMEUX_IsGameKeyExist(installScope, InstanceID, &lpRegistryPath);

    if(hr == S_FALSE)
    {
        /* game not found in CURRENT_USER scope, let's check in ALL_USERS */
        installScope = GIS_ALL_USERS;
        hr = GAMEUX_IsGameKeyExist(installScope, InstanceID, &lpRegistryPath);
    }

    if(hr == S_FALSE)
        /* still not found? let's inform user that game does not exists */
        hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

    if(SUCCEEDED(hr))
    {
        WCHAR *lpGameInstallDirectory = NULL;

        /* game found, it's registry path is in lpRegistryPath and install
         * scope in installScope */
        TRACE("game found in registry (path %s), updating\n", debugstr_w(lpRegistryPath));

        /* first, read required data about game */
        hr = GAMEUX_LoadRegistryString(HKEY_LOCAL_MACHINE, lpRegistryPath,
            sConfigGDFBinaryPath, &lpGDFBinaryPath);

        if(SUCCEEDED(hr))
            hr = GAMEUX_LoadRegistryString(HKEY_LOCAL_MACHINE, lpRegistryPath,
                sConfigApplicationPath, &lpGameInstallDirectory);

        /* now remove currently existing registry key */
        if(SUCCEEDED(hr))
            hr = GAMEUX_RemoveRegistryRecord(InstanceID);

        /* and add it again, it will cause in reparsing of whole GDF */
        if(SUCCEEDED(hr))
            hr = GAMEUX_RegisterGame(lpGDFBinaryPath, lpGameInstallDirectory,
                                     installScope, InstanceID);

        HeapFree(GetProcessHeap(), 0, lpGDFBinaryPath);
        HeapFree(GetProcessHeap(), 0, lpGameInstallDirectory);
    }

    HeapFree(GetProcessHeap(), 0, lpRegistryPath);
    TRACE("returning 0x%x\n", hr);
    return hr;
}
/*******************************************************************************
 * GAMEUX_FindGameInstanceId
 *
 * Internal helper function. Description available in gameux_private.h file
 */
HRESULT GAMEUX_FindGameInstanceId(
        LPCWSTR sGDFBinaryPath,
        GAME_INSTALL_SCOPE installScope,
        GUID* pInstanceId)
{
    static const WCHAR sConfigGDFBinaryPath[] =
            {'C','o','n','f','i','g','G','D','F','B','i','n','a','r','y','P','a','t','h',0};

    HRESULT hr;
    BOOL found = FALSE;
    LPWSTR lpRegistryPath = NULL;
    HKEY hRootKey;
    DWORD dwSubKeys, dwSubKeyLen, dwMaxSubKeyLen, i;
    LPWSTR lpName = NULL, lpValue = NULL;

    hr = GAMEUX_buildGameRegistryPath(installScope, NULL, &lpRegistryPath);

    if(SUCCEEDED(hr))
        /* enumerate all subkeys of received one and search them for value "ConfigGGDFBinaryPath" */
        hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                lpRegistryPath, 0, KEY_READ | KEY_WOW64_64KEY, &hRootKey));

    if(SUCCEEDED(hr))
    {
        hr = HRESULT_FROM_WIN32(RegQueryInfoKeyW(hRootKey, NULL, NULL, NULL,
                &dwSubKeys, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL));

        if(SUCCEEDED(hr))
        {
            ++dwMaxSubKeyLen; /* for string terminator */
            lpName = CoTaskMemAlloc(dwMaxSubKeyLen*sizeof(WCHAR));
            if(!lpName) hr = E_OUTOFMEMORY;
        }

        if(SUCCEEDED(hr))
        {
            for(i=0; i<dwSubKeys && !found; ++i)
            {
                dwSubKeyLen = dwMaxSubKeyLen;
                hr = HRESULT_FROM_WIN32(RegEnumKeyExW(hRootKey, i, lpName, &dwSubKeyLen,
                        NULL, NULL, NULL, NULL));

                if(SUCCEEDED(hr))
                    hr = GAMEUX_LoadRegistryString(hRootKey, lpName,
                                             sConfigGDFBinaryPath, &lpValue);

                if(SUCCEEDED(hr))
                {
                    if(lstrcmpW(lpValue, sGDFBinaryPath)==0)
                    {
                        /* key found, let's copy instance id and exit */
                        hr = (GUIDFromStringW(lpName, pInstanceId) ? S_OK : E_FAIL);
                        found = TRUE;
                    }
                    HeapFree(GetProcessHeap(), 0, lpValue);
                }
            }
        }

        HeapFree(GetProcessHeap(), 0, lpName);
        RegCloseKey(hRootKey);
    }

    HeapFree(GetProcessHeap(), 0, lpRegistryPath);

    if((SUCCEEDED(hr) && !found) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
        hr = S_FALSE;

    return hr;
}
/*******************************************************************************
 * GameExplorer implementation
 */

typedef struct _GameExplorerImpl
{
    IGameExplorer IGameExplorer_iface;
    IGameExplorer2 IGameExplorer2_iface;
    LONG ref;
} GameExplorerImpl;

static inline GameExplorerImpl *impl_from_IGameExplorer(IGameExplorer *iface)
{
    return CONTAINING_RECORD(iface, GameExplorerImpl, IGameExplorer_iface);
}

static inline GameExplorerImpl *impl_from_IGameExplorer2(IGameExplorer2 *iface)
{
    return CONTAINING_RECORD(iface, GameExplorerImpl, IGameExplorer2_iface);
}

static HRESULT WINAPI GameExplorerImpl_QueryInterface(
        IGameExplorer *iface,
        REFIID riid,
        void **ppvObject)
{
    GameExplorerImpl *This = impl_from_IGameExplorer(iface);

    TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);

    *ppvObject = NULL;

    if(IsEqualGUID(riid, &IID_IUnknown) ||
       IsEqualGUID(riid, &IID_IGameExplorer))
    {
        *ppvObject = &This->IGameExplorer_iface;
    }
    else if(IsEqualGUID(riid, &IID_IGameExplorer2))
    {
        *ppvObject = &This->IGameExplorer2_iface;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IGameExplorer_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI GameExplorerImpl_AddRef(IGameExplorer *iface)
{
    GameExplorerImpl *This = impl_from_IGameExplorer(iface);
    LONG ref;

    ref = InterlockedIncrement(&This->ref);

    TRACE("(%p): ref=%d\n", This, ref);
    return ref;
}

static ULONG WINAPI GameExplorerImpl_Release(IGameExplorer *iface)
{
    GameExplorerImpl *This = impl_from_IGameExplorer(iface);
    LONG ref;

    ref = InterlockedDecrement(&This->ref);
    TRACE("(%p): ref=%d\n", This, ref);

    if(ref == 0)
    {
        TRACE("freeing GameExplorer object\n");
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI GameExplorerImpl_AddGame(
        IGameExplorer *iface,
        BSTR bstrGDFBinaryPath,
        BSTR sGameInstallDirectory,
        GAME_INSTALL_SCOPE installScope,
        GUID *pInstanceID)
{
    GameExplorerImpl *This = impl_from_IGameExplorer(iface);
    TRACE("(%p, %s, %s, 0x%x, %s)\n", This, debugstr_w(bstrGDFBinaryPath), debugstr_w(sGameInstallDirectory), installScope, debugstr_guid(pInstanceID));
    return GAMEUX_RegisterGame(bstrGDFBinaryPath, sGameInstallDirectory, installScope, pInstanceID);
}

static HRESULT WINAPI GameExplorerImpl_RemoveGame(
        IGameExplorer *iface,
        GUID instanceID)
{
    GameExplorerImpl *This = impl_from_IGameExplorer(iface);

    TRACE("(%p, %s)\n", This, debugstr_guid(&instanceID));
    return GAMEUX_RemoveRegistryRecord(&instanceID);
}

static HRESULT WINAPI GameExplorerImpl_UpdateGame(
        IGameExplorer *iface,
        GUID instanceID)
{
    GameExplorerImpl *This = impl_from_IGameExplorer(iface);

    TRACE("(%p, %s)\n", This, debugstr_guid(&instanceID));
    return GAMEUX_UpdateGame(&instanceID);
}

static HRESULT WINAPI GameExplorerImpl_VerifyAccess(
        IGameExplorer *iface,
        BSTR sGDFBinaryPath,
        BOOL *pHasAccess)
{
    GameExplorerImpl *This = impl_from_IGameExplorer(iface);

    FIXME("(%p, %s, %p)\n", This, debugstr_w(sGDFBinaryPath), pHasAccess);
    *pHasAccess = TRUE;
    return S_OK;
}

static const struct IGameExplorerVtbl GameExplorerImplVtbl =
{
    GameExplorerImpl_QueryInterface,
    GameExplorerImpl_AddRef,
    GameExplorerImpl_Release,
    GameExplorerImpl_AddGame,
    GameExplorerImpl_RemoveGame,
    GameExplorerImpl_UpdateGame,
    GameExplorerImpl_VerifyAccess
};


static HRESULT WINAPI GameExplorer2Impl_QueryInterface(
        IGameExplorer2 *iface,
        REFIID riid,
        void **ppvObject)
{
    GameExplorerImpl *This = impl_from_IGameExplorer2(iface);
    return GameExplorerImpl_QueryInterface(&This->IGameExplorer_iface, riid, ppvObject);
}

static ULONG WINAPI GameExplorer2Impl_AddRef(IGameExplorer2 *iface)
{
    GameExplorerImpl *This = impl_from_IGameExplorer2(iface);
    return GameExplorerImpl_AddRef(&This->IGameExplorer_iface);
}

static ULONG WINAPI GameExplorer2Impl_Release(IGameExplorer2 *iface)
{
    GameExplorerImpl *This = impl_from_IGameExplorer2(iface);
    return GameExplorerImpl_Release(&This->IGameExplorer_iface);
}

static HRESULT WINAPI GameExplorer2Impl_CheckAccess(
        IGameExplorer2 *iface,
        LPCWSTR binaryGDFPath,
        BOOL *pHasAccess)
{
    GameExplorerImpl *This = impl_from_IGameExplorer2(iface);
    FIXME("stub (%p, %s, %p)\n", This, debugstr_w(binaryGDFPath), pHasAccess);
    return E_NOTIMPL;
}

static HRESULT WINAPI GameExplorer2Impl_InstallGame(
        IGameExplorer2 *iface,
        LPCWSTR binaryGDFPath,
        LPCWSTR installDirectory,
        GAME_INSTALL_SCOPE installScope)
{
    HRESULT hr;
    GUID instanceId;
    GameExplorerImpl *This = impl_from_IGameExplorer2(iface);

    TRACE("(%p, %s, %s, 0x%x)\n", This, debugstr_w(binaryGDFPath), debugstr_w(installDirectory), installScope);

    if(!binaryGDFPath)
        return E_INVALIDARG;

    hr = GAMEUX_FindGameInstanceId(binaryGDFPath, GIS_CURRENT_USER, &instanceId);

    if(hr == S_FALSE)
        hr = GAMEUX_FindGameInstanceId(binaryGDFPath, GIS_ALL_USERS, &instanceId);

    if(hr == S_FALSE)
    {
        /* if game isn't yet registered, then install it */
        instanceId = GUID_NULL;
        hr = GAMEUX_RegisterGame(binaryGDFPath, installDirectory, installScope, &instanceId);
    }
    else if(hr == S_OK)
        /* otherwise, update game */
        hr = GAMEUX_UpdateGame(&instanceId);

    return hr;
}

static HRESULT WINAPI GameExplorer2Impl_UninstallGame(
        IGameExplorer2 *iface,
        LPCWSTR binaryGDFPath)
{
    HRESULT hr;
    GUID instanceId;
    GameExplorerImpl *This = impl_from_IGameExplorer2(iface);
    TRACE("(%p, %s)\n", This, debugstr_w(binaryGDFPath));

    if(!binaryGDFPath)
        return E_INVALIDARG;

    hr = GAMEUX_FindGameInstanceId(binaryGDFPath, GIS_CURRENT_USER, &instanceId);

    if(hr == S_FALSE)
        hr = GAMEUX_FindGameInstanceId(binaryGDFPath, GIS_ALL_USERS, &instanceId);

    if(hr == S_OK)
        hr = GAMEUX_RemoveRegistryRecord(&instanceId);

    return hr;
}

static const struct IGameExplorer2Vtbl GameExplorer2ImplVtbl =
{
    GameExplorer2Impl_QueryInterface,
    GameExplorer2Impl_AddRef,
    GameExplorer2Impl_Release,
    GameExplorer2Impl_InstallGame,
    GameExplorer2Impl_UninstallGame,
    GameExplorer2Impl_CheckAccess
};

/*
 * Construction routine
 */
HRESULT GameExplorer_create(
        IUnknown* pUnkOuter,
        IUnknown** ppObj)
{
    GameExplorerImpl *pGameExplorer;

    TRACE("(%p, %p)\n", pUnkOuter, ppObj);

    pGameExplorer = HeapAlloc(GetProcessHeap(), 0, sizeof(*pGameExplorer));

    if(!pGameExplorer)
        return E_OUTOFMEMORY;

    pGameExplorer->IGameExplorer_iface.lpVtbl = &GameExplorerImplVtbl;
    pGameExplorer->IGameExplorer2_iface.lpVtbl = &GameExplorer2ImplVtbl;
    pGameExplorer->ref = 1;

    *ppObj = (IUnknown*)&pGameExplorer->IGameExplorer_iface;

    TRACE("returning iface: %p\n", *ppObj);
    return S_OK;
}
