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