Mariusz Pluciński : gameux: Add support of loading Application Id into registry.
Alexandre Julliard
julliard at winehq.org
Thu Sep 9 13:56:51 CDT 2010
Module: wine
Branch: master
Commit: 180ac750bba09a7dab8af4041e6e65dfd80e78bd
URL: http://source.winehq.org/git/wine.git/?a=commit;h=180ac750bba09a7dab8af4041e6e65dfd80e78bd
Author: Mariusz Pluciński <vshader at gmail.com>
Date: Tue Sep 7 15:36:30 2010 +0200
gameux: Add support of loading Application Id into registry.
---
dlls/gameux/Makefile.in | 2 +-
dlls/gameux/gameexplorer.c | 152 +++++++++++++++++++++++++++++++++++++-
dlls/gameux/gameux_private.h | 1 +
dlls/gameux/tests/gameexplorer.c | 2 +-
4 files changed, 154 insertions(+), 3 deletions(-)
diff --git a/dlls/gameux/Makefile.in b/dlls/gameux/Makefile.in
index b90698c..bf8f9ab 100644
--- a/dlls/gameux/Makefile.in
+++ b/dlls/gameux/Makefile.in
@@ -4,7 +4,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = gameux.dll
-IMPORTS = uuid ole32 user32 advapi32 oleaut32
+IMPORTS = uuid shell32 oleaut32 ole32 user32 advapi32
C_SRCS = \
factory.c \
diff --git a/dlls/gameux/gameexplorer.c b/dlls/gameux/gameexplorer.c
index 9df9a23..a4c37a7 100644
--- a/dlls/gameux/gameexplorer.c
+++ b/dlls/gameux/gameexplorer.c
@@ -23,15 +23,22 @@
#include "ole2.h"
#include "sddl.h"
+#include "xmldom.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
*/
@@ -186,12 +193,15 @@ static HRESULT GAMEUX_buildGameRegistryPath(GAME_INSTALL_SCOPE installScope,
*
* List of registry keys associated with structure fields:
* Key Field in GAMEUX_GAME_DATA structure
+ * ApplicationId guidApplicationId
* ConfigApplicationPath sGameInstallDirectory
* ConfigGDFBinaryPath sGDFBinaryPath
*
*/
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[] =
@@ -200,12 +210,16 @@ static HRESULT GAMEUX_WriteRegistryRecord(struct GAMEUX_GAME_DATA *GameData)
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, NULL,
&hKey, NULL));
@@ -222,6 +236,11 @@ static HRESULT GAMEUX_WriteRegistryRecord(struct GAMEUX_GAME_DATA *GameData)
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)));
+
RegCloseKey(hKey);
if(FAILED(hr))
@@ -239,6 +258,135 @@ static HRESULT GAMEUX_WriteRegistryRecord(struct GAMEUX_GAME_DATA *GameData)
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;
+
+ 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);
+
+ return hr;
+}
+/*******************************************************************************
+ * GAMEUX_ParseGDFBinary
+ *
+ * Helper funtion, 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 HRESULT GAMEUX_ParseGDFBinary(struct GAMEUX_GAME_DATA *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);
+
+ 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);
+ }
+
+ return hr;
+}
+/*******************************************************************************
* GAMEUX_RegisterGame
*
* Internal helper function. Description available in gameux_private.h file
@@ -266,7 +414,9 @@ HRESULT WINAPI GAMEUX_RegisterGame(LPCWSTR sGDFBinaryPath,
GameData.guidInstanceId = *pInstanceID;
- FIXME("loading game data from GDF file not yet implemented\n");
+ /* load data from GDF binary */
+ if(SUCCEEDED(hr))
+ hr = GAMEUX_ParseGDFBinary(&GameData);
/* save data to registry */
if(SUCCEEDED(hr))
diff --git a/dlls/gameux/gameux_private.h b/dlls/gameux/gameux_private.h
index 3ff28ec..4beb500 100644
--- a/dlls/gameux/gameux_private.h
+++ b/dlls/gameux/gameux_private.h
@@ -41,6 +41,7 @@ struct GAMEUX_GAME_DATA
LPWSTR sGameInstallDirectory; /* directory passed to AddGame/InstallGame methods */
GAME_INSTALL_SCOPE installScope;/* game's installation scope */
GUID guidInstanceId; /* game installation instance identifier */
+ GUID guidApplicationId; /* game's application identifier */
};
/*******************************************************************************
* GAMEUX_initGameData
diff --git a/dlls/gameux/tests/gameexplorer.c b/dlls/gameux/tests/gameexplorer.c
index 4a0f241..4367ab3 100644
--- a/dlls/gameux/tests/gameexplorer.c
+++ b/dlls/gameux/tests/gameexplorer.c
@@ -295,7 +295,7 @@ static void _validateGameRegistryValues(int line,
/* these values exist up from Vista */
hr = _validateRegistryValue(hKey, keyPath, sApplicationId, RRF_RT_REG_SZ, sGameApplicationId);
- todo_wine ok_(__FILE__, line)(hr==S_OK, "failed while checking registry value (error 0x%x)\n", hr);
+ ok_(__FILE__, line)(hr==S_OK, "failed while checking registry value (error 0x%x)\n", hr);
hr = _validateRegistryValue(hKey, keyPath, sConfigApplicationPath, RRF_RT_REG_SZ, gameExePath);
ok_(__FILE__, line)(hr==S_OK, "failed while checking registry value (error 0x%x)\n", hr);
hr = _validateRegistryValue(hKey, keyPath, sConfigGDFBinaryPath, RRF_RT_REG_SZ, gameExeName);
More information about the wine-cvs
mailing list