From 1ef9897e214c2e71d1838292d9273aa32a3e7c1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mariusz=20Pluci=C5=84ski?= <vshader@gmail.com>
Date: Fri, 9 Jul 2010 00:19:00 +0200
Subject: gameux: add parital implementation of IGameStatistics::GetGameStatistics and create private header

---
 dlls/gameux/gameexplorer.c   |  107 ++++++-----------------
 dlls/gameux/gamestatistics.c |   62 +++++++++++++-
 dlls/gameux/gameux_private.h |  199 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 284 insertions(+), 84 deletions(-)
 create mode 100644 dlls/gameux/gameux_private.h

diff --git a/dlls/gameux/gameexplorer.c b/dlls/gameux/gameexplorer.c
index 2d78139..4fa4620 100644
--- a/dlls/gameux/gameexplorer.c
+++ b/dlls/gameux/gameexplorer.c
@@ -33,6 +33,7 @@
 #include "sddl.h"
 
 #include <gameux.h>
+#include "gameux_private.h"
 
 /* function from Shell32 */
 extern BOOL WINAPI GUIDFromStringW(LPCWSTR str, LPGUID guid);
@@ -56,76 +57,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gameux);
 /*******************************************************************************
  * GameUX helper functions
  */
-/*******************************************************************************
- * GAME_DEFINITION_FILE_DATA
- *
- * helper function for storing data unpacked from GDF file
- */
-struct GAME_DEFINITION_FILE_DATA_LINK
-{
-    LPWSTR name;
-    LPWSTR URI;
-};
-struct GAME_DEFINITION_FILE_DATA_TASK
-{
-    DWORD nIndex;
-    LPWSTR sName;
-    enum
-    {
-         GAME_DEFINITION_FILE_DATA_TASK_FILE,
-         GAME_DEFINITION_FILE_DATA_TASK_URL,
-    } type;
-    union
-    {
-        struct
-        {
-            LPWSTR sPath;
-            LPWSTR sArguments;
-        } fileTask;
-        struct
-        {
-            LPWSTR sLink;
-        } URLTask;
-    } data;
-};
-struct GAME_DEFINITION_FILE_DATA
-{
-    LPWSTR sGameId;
-    LPWSTR sWMID;
-    LPWSTR sName;
-    LPWSTR sDescription;
-    LPWSTR sReleaseDate;
-    DWORD nGenres;
-    LPWSTR *sGenres;
-    LPWSTR sRatings;
-    LPWSTR sVersion;
-    GUID guidSavedGamesKnownFolderID;
-    LPWSTR sSavedGamesPath;
-    FLOAT fPerformanceRatingMinimum;
-    FLOAT fPerformanceRatingRecommended;
-    DWORD nDevelopers;
-    struct GAME_DEFINITION_FILE_DATA_LINK *sDevelopers;
-    DWORD nPublishers;
-    struct GAME_DEFINITION_FILE_DATA_LINK *sPublishers;
-    DWORD nGameExecutables;
-    LPWSTR *sGameExecutables;
-    struct
-    {
-        DWORD nType;
-        LPWSTR sRSS;
-        struct
-        {
-            struct GAME_DEFINITION_FILE_DATA_TASK *primary;
-            DWORD nTasks;
-            struct GAME_DEFINITION_FILE_DATA_TASK **tasks;
-        } playTasks;
-        struct
-        {
-            DWORD nTasks;
-            struct GAME_DEFINITION_FILE_DATA_TASK **tasks;
-        } supportTasks;
-    } extendedProperties;
-};
 /*******************************************************************
  * _init_GAME_DEFINITION_FILE_DATA
  *
@@ -162,8 +93,11 @@ void _init_GAME_DEFINITION_FILE_DATA(struct GAME_DEFINITION_FILE_DATA* GDFData)
 /*******************************************************************
  * _delete_GAME_DEFINITION_FILE_DATA
  *
- * Helper function, frees memory allocated for storing data in
- * GAME_DEFINITION_FILE_DATA structure
+ * Documented in header file: gameux_private.h
+ *
+ * _delete_GAME_DEFINITION_FILE_DATA_TASK is private internal
+ * function used ONLY by normal _delete_GAME_DEFINITION_FILE_DATA,
+ * please do not use it manually
  */
 void _delete_GAME_DEFINITION_FILE_DATA_TASK(struct GAME_DEFINITION_FILE_DATA_TASK **pTask)
 {
@@ -1172,8 +1106,7 @@ HRESULT _ParseGameDefinition(IXMLDOMElement* pXMLGameDefinitionElement,
 /*******************************************************************************
  * _ParseGDF_XML
  *
- * Helper function, parses incoming GDF XML file, and stores data
- * in appropiate structure
+ * Documented in header file: gameux_private.h
  */
 HRESULT _ParseGDF_XML(LPCWSTR sGDFBinaryPath,
     struct GAME_DEFINITION_FILE_DATA* GDFData)
@@ -1245,8 +1178,7 @@ HRESULT _ParseGDF_XML(LPCWSTR sGDFBinaryPath,
 /*******************************************************************
  * _BuildGameRegistryPath
  *
- * Helper function, builds registry path for storing game's data
- * from given parameters
+ * Documented in header file: gameux_private.h
  */
 HRESULT _BuildGameRegistryPath(GAME_INSTALL_SCOPE installScope,
         LPWSTR sRegistryKey,
@@ -1323,10 +1255,12 @@ HRESULT _BuildGameRegistryPath(GAME_INSTALL_SCOPE installScope,
 /* ******************************************************************
  * _IsGameRegistered
  *
- * Helper function for checking is game with given ID is already
- * installed in given scope
+ * Documented in header file: gameux_private.h
  */
-HRESULT _IsGameRegistered(LPGUID pInstanceID, GAME_INSTALL_SCOPE installScope, LPGUID pApplicationID, LPBOOL isGameRegistered)
+HRESULT _IsGameRegistered(LPGUID pInstanceID,
+    GAME_INSTALL_SCOPE installScope,
+    LPGUID pApplicationID,
+    LPBOOL isGameRegistered)
 {
     static const WCHAR sApplicationId[] = {'A','p','p','l','i','c','a','t','i','o','n','I','d',0};
 
@@ -1409,8 +1343,7 @@ LSTATUS _RegSetValueStr(HKEY hKey,
 /*******************************************************************
  * _WriteRegistryRecord
  *
- * Helper function, writes registry record connected with given
- * game
+ * Documented in header file: gameux_private.h
  */
 HRESULT _WriteRegistryRecord(struct GAME_DEFINITION_FILE_DATA* GDFData,
     BSTR sGDFBinaryPath,
@@ -1523,6 +1456,18 @@ registry_end:
     return hr;
 }
 /*******************************************************************
+ * _FindGameByGDFBinaryPath
+ * 
+ * Documented in header file: gameux_private.h
+ */
+HRESULT _FindGameByGDFBinaryPath(LPCWSTR sBinaryPath,
+        GAME_INSTALL_SCOPE* installScope,
+        GUID* pInstanceID)
+{
+    FIXME("stub\n");
+    return E_NOTIMPL;
+}
+/*******************************************************************
  * _RemoveRegistryRecord
  *
  * Helper function, removes registry key associated with given game instance
diff --git a/dlls/gameux/gamestatistics.c b/dlls/gameux/gamestatistics.c
index 75cbc83..e55d77f 100644
--- a/dlls/gameux/gamestatistics.c
+++ b/dlls/gameux/gamestatistics.c
@@ -25,16 +25,20 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winuser.h"
+#include "winreg.h"
 #include "ole2.h"
 
 #include <gameux.h>
+#include "gameux_private.h"
 
 #include "wine/debug.h"
 
+/* function from Shell32 */
+extern BOOL WINAPI GUIDFromStringW(LPCWSTR str, LPGUID guid);
 
 WINE_DEFAULT_DEBUG_CHANNEL(gameux);
 
-/*
+/*******************************************************************
  * IGameStatisticsMgr
  */
 
@@ -104,9 +108,61 @@ static HRESULT STDMETHODCALLTYPE GameStatisticsMgrImpl_GetGameStatistics(
         GAMESTATS_OPEN_RESULT *pOpenResult,
         IGameStatistics **ppiStats)
 {
+    static const WCHAR sApplicationId[] = {'A','p','p','l','i','c','a','t','i','o','n','I','d',0};
+
+    HRESULT hr;
+    LONG lr;
+    BOOL br;
+    GAME_INSTALL_SCOPE installScope;
+    GUID instanceId, applicationId;
+    LPWSTR lpApplicationId;
+    struct GAME_DEFINITION_FILE_DATA GDFData;
+    WCHAR sRegistryKey[65536*sizeof(WCHAR)];
+    DWORD dwSize;
+
     TRACE("(%p, %s, 0x%x, %p, %p)\n", iface, debugstr_w(GDFBinaryPath), openType, pOpenResult, ppiStats);
-    FIXME("stub\n");
-    return E_NOTIMPL;
+
+    hr = _ParseGDF_XML(GDFBinaryPath, &GDFData);
+    if(SUCCEEDED(hr))
+    {
+        hr = _FindGameByGDFBinaryPath(GDFBinaryPath, &installScope, &instanceId);
+        if(SUCCEEDED(hr))
+        {
+            hr = _BuildGameRegistryPath(installScope, sRegistryKey, sizeof(sRegistryKey), &instanceId);
+            if(SUCCEEDED(hr))
+            {
+                lr = RegGetValueW(HKEY_LOCAL_MACHINE, sRegistryKey, sApplicationId,
+                        RRF_RT_REG_SZ, NULL, NULL, &dwSize);
+                if(lr != ERROR_SUCCESS)
+                    hr = HRESULT_FROM_WIN32(lr);
+                else
+                {
+                    lpApplicationId = CoTaskMemAlloc(dwSize);
+                    if(!lpApplicationId)
+                        hr = E_OUTOFMEMORY;
+                    else
+                    {
+                        lr = RegGetValueW(HKEY_LOCAL_MACHINE, sRegistryKey, sApplicationId,
+                                RRF_RT_REG_SZ, NULL, (LPVOID)lpApplicationId, &dwSize);
+                        if(lr != ERROR_SUCCESS)
+                            hr = HRESULT_FROM_WIN32(lr);
+                        else
+                        {
+                            br = GUIDFromStringW(lpApplicationId, &applicationId);
+                            if(br == TRUE)
+                            {
+                                FIXME("not fully implemented\n");
+                                hr = E_NOTIMPL;
+                            }
+                        }
+                        CoTaskMemFree(lpApplicationId);
+                    }
+                }
+            }
+        }
+    }
+
+    return hr;
 }
 
 static HRESULT STDMETHODCALLTYPE GameStatisticsMgrImpl_RemoveGameStatistics(
diff --git a/dlls/gameux/gameux_private.h b/dlls/gameux/gameux_private.h
new file mode 100644
index 0000000..0bd97ba
--- /dev/null
+++ b/dlls/gameux/gameux_private.h
@@ -0,0 +1,199 @@
+/*
+ * gameux: internal header file
+ *
+ * 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
+ */
+
+#ifndef GAMEUX_PRIVATE_H
+#define	GAMEUX_PRIVATE_H
+
+/*******************************************************************************
+ * GameUX helper functions
+ *
+ * Defined in gameexplorer.c
+ */
+/*******************************************************************************
+ * GAME_DEFINITION_FILE_DATA
+ *
+ * helper function for storing data unpacked from GDF file
+ */
+struct GAME_DEFINITION_FILE_DATA_LINK
+{
+    LPWSTR name;
+    LPWSTR URI;
+};
+struct GAME_DEFINITION_FILE_DATA_TASK
+{
+    DWORD nIndex;
+    LPWSTR sName;
+    enum
+    {
+         GAME_DEFINITION_FILE_DATA_TASK_FILE,
+         GAME_DEFINITION_FILE_DATA_TASK_URL,
+    } type;
+    union
+    {
+        struct
+        {
+            LPWSTR sPath;
+            LPWSTR sArguments;
+        } fileTask;
+        struct
+        {
+            LPWSTR sLink;
+        } URLTask;
+    } data;
+};
+struct GAME_DEFINITION_FILE_DATA
+{
+    LPWSTR sGameId;
+    LPWSTR sWMID;
+    LPWSTR sName;
+    LPWSTR sDescription;
+    LPWSTR sReleaseDate;
+    DWORD nGenres;
+    LPWSTR *sGenres;
+    LPWSTR sRatings;
+    LPWSTR sVersion;
+    GUID guidSavedGamesKnownFolderID;
+    LPWSTR sSavedGamesPath;
+    FLOAT fPerformanceRatingMinimum;
+    FLOAT fPerformanceRatingRecommended;
+    DWORD nDevelopers;
+    struct GAME_DEFINITION_FILE_DATA_LINK *sDevelopers;
+    DWORD nPublishers;
+    struct GAME_DEFINITION_FILE_DATA_LINK *sPublishers;
+    DWORD nGameExecutables;
+    LPWSTR *sGameExecutables;
+    struct
+    {
+        DWORD nType;
+        LPWSTR sRSS;
+        struct
+        {
+            struct GAME_DEFINITION_FILE_DATA_TASK *primary;
+            DWORD nTasks;
+            struct GAME_DEFINITION_FILE_DATA_TASK **tasks;
+        } playTasks;
+        struct
+        {
+            DWORD nTasks;
+            struct GAME_DEFINITION_FILE_DATA_TASK **tasks;
+        } supportTasks;
+    } extendedProperties;
+};
+/*******************************************************************
+ * _init_GAME_DEFINITION_FILE_DATA
+ *
+ * Helper function, initialized fields of GAME_DEFINITION_FILE_DATA
+ * structure with default values
+ *
+ * Parameters:
+ *  GDFData                 [I/O] structure to initialize
+ */
+void _init_GAME_DEFINITION_FILE_DATA(struct GAME_DEFINITION_FILE_DATA* GDFData);
+/*******************************************************************
+ * _delete_GAME_DEFINITION_FILE_DATA
+ *
+ * Helper function, frees memory allocated for storing data in
+ * GAME_DEFINITION_FILE_DATA structure. After using this function,
+ * given structure is unable to use. TO use it again, you should
+ * call _init_GAME_DEFINITION_FILE_DATA on it.
+ *
+ * Parameters:
+ *  GDFData                 [I] structure to delete
+ */
+void _delete_GAME_DEFINITION_FILE_DATA(struct GAME_DEFINITION_FILE_DATA* GDFData);
+
+/*******************************************************************************
+ * _ParseGDF_XML
+ *
+ * Helper function, parses incoming GDF XML file, and stores data
+ * in appropiate structure
+ *
+ * Parameters:
+ *  sGDFBinaryPath          [I] path to binary containing GDF file in resources
+ *  GDFData                 [O] data read from GDF file
+ */
+HRESULT _ParseGDF_XML(LPCWSTR sGDFBinaryPath,
+    struct GAME_DEFINITION_FILE_DATA* GDFData);
+/*******************************************************************
+ * _BuildGameRegistryPath
+ *
+ * Helper function, builds registry path for storing game's data
+ * from given parameters
+ *
+ * Parameters:
+ *  installScope            [I] install scope to use in path
+ *  sRegistryKey            [O] path to registry key
+ *  nRegistryKeyBytesSize   [O] size (in bytes) of buffer passed as sRegistryKey
+ *  pInstanceID             [I] instance ID of game
+ */
+HRESULT _BuildGameRegistryPath(GAME_INSTALL_SCOPE installScope,
+        LPWSTR sRegistryKey,
+        DWORD nRegistryKeyBytesSize,
+        GUID* pInstanceID);
+/* ******************************************************************
+ * _IsGameRegistered
+ *
+ * Helper function for checking is game with given ID is already
+ * installed in given scope
+ *
+ * Parameters:
+ *  pInstanceID             [I] instance ID of application to check
+ *  installScope            [I] install scope to check
+ *  pApplicationID          [I] application ID
+ *  isGameRegistered        [O] is game registered or not
+ */
+HRESULT _IsGameRegistered(LPGUID pInstanceID,
+        GAME_INSTALL_SCOPE installScope,
+        LPGUID pApplicationID,
+        LPBOOL isGameRegistered);
+/*******************************************************************
+ * _WriteRegistryRecord
+ *
+ * Helper function, writes registry record connected with given game
+ *
+ * Parameters:
+ *  GDFData                 [I] structure with data to write
+ *  sGDFBinaryPath          [I] path to binary containing GDF associated with game
+ *  sGameInstallDirectory   [I] directory where game is installed
+ *  installScope            [I] scope where game is installed
+ *  pInstanceID             [I] game instance ID
+ */
+HRESULT _WriteRegistryRecord(struct GAME_DEFINITION_FILE_DATA* GDFData,
+    BSTR sGDFBinaryPath,
+    BSTR sGameInstallDirectory,
+    GAME_INSTALL_SCOPE installScope,
+    GUID* pInstanceID);
+/*******************************************************************
+ * _FindGameByGDFBinaryPath
+ *
+ * Helper function, finds game's instance ID and install scope
+ * by given GDF binary path
+ *
+ * Parameters:
+ *  sBinaryPath             [I] path to binary containing GDF associated with game
+ *  installScope            [O] install scope of application
+ *  pInstanceID             [O] instance ID of application
+ */
+HRESULT _FindGameByGDFBinaryPath(LPCWSTR sBinaryPath,
+        GAME_INSTALL_SCOPE* installScope,
+        GUID* pInstanceID);
+
+
+#endif	/* GAMEUX_PRIVATE_H */
-- 
1.7.1.1

