Mariusz Pluciński : gameux: IGameStatistics:: Save initial implementation.
Alexandre Julliard
julliard at winehq.org
Mon Sep 27 11:29:42 CDT 2010
Module: wine
Branch: master
Commit: ef3a1ab53a1b772d1efffd0ee6a40c057469f24d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ef3a1ab53a1b772d1efffd0ee6a40c057469f24d
Author: Mariusz Pluciński <vshader at gmail.com>
Date: Sun Sep 26 15:02:43 2010 +0200
gameux: IGameStatistics::Save initial implementation.
---
dlls/gameux/gamestatistics.c | 139 +++++++++++++++++++++++++++++++++++-
dlls/gameux/tests/gamestatistics.c | 8 +-
2 files changed, 141 insertions(+), 6 deletions(-)
diff --git a/dlls/gameux/gamestatistics.c b/dlls/gameux/gamestatistics.c
index a4c88a4..83ee5cd 100644
--- a/dlls/gameux/gamestatistics.c
+++ b/dlls/gameux/gamestatistics.c
@@ -23,6 +23,9 @@
#include "ole2.h"
#include "winreg.h"
+#include "msxml2.h"
+#include "shlwapi.h"
+#include "shlobj.h"
#include "gameux.h"
#include "gameux_private.h"
@@ -63,6 +66,124 @@ struct GAMEUX_STATS
struct GAMEUX_STATS_CATEGORY categories[MAX_CATEGORIES];
};
/*******************************************************************************
+ * GAMEUX_createStatsDirectory
+ *
+ * Helper function, creates directory to store game statistics
+ *
+ * Parameters
+ * path [I] path to game statistics file.
+ * base directory of this file will
+ * be created if it doesn't exists
+ */
+static HRESULT GAMEUX_createStatsDirectory(LPCWSTR lpFilePath)
+{
+ HRESULT hr;
+ WCHAR lpDirectoryPath[MAX_PATH];
+ LPCWSTR lpEnd;
+
+ lpEnd = StrRChrW(lpFilePath, NULL, '\\');
+ lstrcpynW(lpDirectoryPath, lpFilePath, lpEnd-lpFilePath+1);
+
+ hr = HRESULT_FROM_WIN32(SHCreateDirectoryExW(NULL, lpDirectoryPath, NULL));
+
+ if(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS) ||
+ hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS))
+ hr = S_FALSE;
+
+ return hr;
+}
+/*******************************************************************
+ * GAMEUX_updateStatisticsFile
+ *
+ * Helper function updating data stored in statistics file
+ *
+ * Parameters:
+ * data [I] pointer to struct containing
+ * statistics data
+ */
+static HRESULT GAMEUX_updateStatisticsFile(struct GAMEUX_STATS *stats)
+{
+ static const WCHAR sStatistics[] = {'S','t','a','t','i','s','t','i','c','s',0};
+
+ HRESULT hr = S_OK;
+ IXMLDOMDocument *document;
+ IXMLDOMElement *root;
+ VARIANT vStatsFilePath;
+ BSTR bstrStatistics = NULL;
+
+ TRACE("(%p)\n", stats);
+
+ V_VT(&vStatsFilePath) = VT_BSTR;
+ V_BSTR(&vStatsFilePath) = SysAllocString(stats->sStatsFile);
+ if(!V_BSTR(&vStatsFilePath))
+ hr = E_OUTOFMEMORY;
+
+ if(SUCCEEDED(hr))
+ hr = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IXMLDOMDocument, (void**)&document);
+
+ if(SUCCEEDED(hr))
+ {
+ bstrStatistics = SysAllocString(sStatistics);
+ if(!bstrStatistics)
+ hr = E_OUTOFMEMORY;
+ }
+
+ if(SUCCEEDED(hr))
+ hr = IXMLDOMDocument_createElement(document, bstrStatistics, &root);
+
+ FIXME("writing statistics not fully implemented\n");
+
+ TRACE("saving game statistics in %s file\n", debugstr_w(stats->sStatsFile));
+ if(SUCCEEDED(hr))
+ hr = GAMEUX_createStatsDirectory(stats->sStatsFile);
+
+ if(SUCCEEDED(hr))
+ hr = IXMLDOMDocument_save(document, vStatsFilePath);
+
+ SysFreeString(V_BSTR(&vStatsFilePath));
+ SysFreeString(bstrStatistics);
+ TRACE("ret=0x%x\n", hr);
+ return hr;
+}
+/*******************************************************************************
+ * GAMEUX_buildStatisticsFilePath
+ * Creates path to file contaning statistics of game with given id.
+ *
+ * Parameters:
+ * lpApplicationId [I] application id of game,
+ * as string
+ * lpStatisticsFile [O] array where path will be
+ * stored. It's size must be
+ * at least MAX_PATH
+ */
+static HRESULT GAMEUX_buildStatisticsFilePath(
+ LPCWSTR lpApplicationId,
+ LPWSTR lpStatisticsFile)
+{
+ static const WCHAR sBackslash[] = {'\\',0};
+ static const WCHAR sStatisticsDir[] = {'\\','M','i','c','r','o','s','o','f','t',
+ '\\','W','i','n','d','o','w','s','\\','G','a','m','e','E','x','p',
+ 'l','o','r','e','r','\\','G','a','m','e','S','t','a','t','i','s',
+ 't','i','c','s',0};
+ static const WCHAR sDotGamestats[] = {'.','g','a','m','e','s','t','a','t','s',0};
+
+ HRESULT hr;
+
+ hr = SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, lpStatisticsFile);
+
+ if(SUCCEEDED(hr))
+ {
+ lstrcatW(lpStatisticsFile, sStatisticsDir);
+ lstrcatW(lpStatisticsFile, lpApplicationId);
+ lstrcatW(lpStatisticsFile, sBackslash);
+ lstrcatW(lpStatisticsFile, lpApplicationId);
+ lstrcatW(lpStatisticsFile, sDotGamestats);
+ }
+
+ return hr;
+}
+/*******************************************************************
* IGameStatistics implementation
*/
typedef struct _GameStatisticsImpl
@@ -299,8 +420,17 @@ static HRESULT WINAPI GameStatisticsImpl_Save(
IGameStatistics *iface,
BOOL trackChanges)
{
- FIXME("stub\n");
- return E_NOTIMPL;
+ GameStatisticsImpl *This = impl_from_IGameStatistics(iface);
+ HRESULT hr = S_OK;
+
+ TRACE("(%p, %d)\n", This, trackChanges);
+
+ if(trackChanges == TRUE)
+ FIXME("tracking changes not yet implemented\n");
+
+ hr = GAMEUX_updateStatisticsFile(&This->stats);
+
+ return hr;
}
static HRESULT WINAPI GameStatisticsImpl_SetLastPlayedCategory(
@@ -479,6 +609,11 @@ static HRESULT STDMETHODCALLTYPE GameStatisticsMgrImpl_GetGameStatistics(
if(SUCCEEDED(hr))
{
*ppiStats = IGameStatistics_from_impl(statisticsImpl);
+ hr = GAMEUX_buildStatisticsFilePath(lpApplicationId, statisticsImpl->stats.sStatsFile);
+ }
+
+ if(SUCCEEDED(hr))
+ {
FIXME("loading game statistics not yet implemented\n");
hr = E_NOTIMPL;
}
diff --git a/dlls/gameux/tests/gamestatistics.c b/dlls/gameux/tests/gamestatistics.c
index 491aecb..759f6d5 100644
--- a/dlls/gameux/tests/gamestatistics.c
+++ b/dlls/gameux/tests/gamestatistics.c
@@ -328,9 +328,9 @@ static void test_gamestatisticsmgr( void )
ok(_isFileExists(lpStatisticsFile) == FALSE, "statistics file %s already exists\n", wine_dbgstr_w(lpStatisticsFile));
- todo_wine ok(IGameStatistics_Save(gs, FALSE)==S_OK, "statistic saving failed\n");
+ ok(IGameStatistics_Save(gs, FALSE)==S_OK, "statistic saving failed\n");
- todo_wine ok(_isFileExists(lpStatisticsFile) == TRUE, "statistics file %s does not exists\n", wine_dbgstr_w(lpStatisticsFile));
+ ok(_isFileExists(lpStatisticsFile) == TRUE, "statistics file %s does not exists\n", wine_dbgstr_w(lpStatisticsFile));
/* this value should not be stored in storage, we need it only to test is it not saved */
ok(IGameStatistics_SetCategoryTitle(gs, 0, sCategory0a)==S_OK, "setting category title failed: %s\n", wine_dbgstr_w(sCategory0a));
@@ -412,10 +412,10 @@ static void test_gamestatisticsmgr( void )
ok(SUCCEEDED(hr), "releasing IGameStatistics returned error: 0x%x\n", hr);
/* test of removing game statistics from underlying storage */
- todo_wine ok(_isFileExists(lpStatisticsFile) == TRUE, "statistics file %s does not exists\n", wine_dbgstr_w(lpStatisticsFile));
+ ok(_isFileExists(lpStatisticsFile) == TRUE, "statistics file %s does not exists\n", wine_dbgstr_w(lpStatisticsFile));
hr = IGameStatisticsMgr_RemoveGameStatistics(gsm, sExeName);
todo_wine ok(SUCCEEDED(hr), "cannot remove game statistics, error: 0x%x\n", hr);
- ok(_isFileExists(lpStatisticsFile) == FALSE, "statistics file %s still exists\n", wine_dbgstr_w(lpStatisticsFile));
+ todo_wine ok(_isFileExists(lpStatisticsFile) == FALSE, "statistics file %s still exists\n", wine_dbgstr_w(lpStatisticsFile));
}
hr = IGameStatisticsMgr_Release(gsm);
More information about the wine-cvs
mailing list