Mariusz Pluciński : gameux: Add InstallGame implementation.

Alexandre Julliard julliard at winehq.org
Thu Sep 16 14:09:05 CDT 2010


Module: wine
Branch: master
Commit: 5213d9d07e7e91062d37e07b6150f48c298dea1c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5213d9d07e7e91062d37e07b6150f48c298dea1c

Author: Mariusz Pluciński <vshader at gmail.com>
Date:   Thu Sep 16 13:55:19 2010 +0200

gameux: Add InstallGame implementation.

---

 dlls/gameux/gameexplorer.c       |  130 +++++++++++++++++++++++++++++++++++---
 dlls/gameux/tests/gameexplorer.c |    8 +-
 2 files changed, 124 insertions(+), 14 deletions(-)

diff --git a/dlls/gameux/gameexplorer.c b/dlls/gameux/gameexplorer.c
index 2619857..66173f2 100644
--- a/dlls/gameux/gameexplorer.c
+++ b/dlls/gameux/gameexplorer.c
@@ -73,7 +73,8 @@ void GAMEUX_uninitGameData(struct GAMEUX_GAME_DATA *GameData)
  *
  * Parameters:
  *  installScope                [I]     the scope which was used in AddGame/InstallGame call
- *  gameInstanceId              [I]     game instance GUID
+ *  gameInstanceId              [I]     game instance GUID. If NULL, then only
+ *                                      path to scope will be returned
  *  lpRegistryPath              [O]     pointer which will receive address to string
  *                                      containing expected registry path. Path
  *                                      is relative to HKLM registry key. It
@@ -159,14 +160,17 @@ static HRESULT GAMEUX_buildGameRegistryPath(GAME_INSTALL_SCOPE installScope,
     else
         hr = E_INVALIDARG;
 
-    /* put game's instance id on the end of path */
-    if(SUCCEEDED(hr))
-        hr = (StringFromGUID2(gameInstanceId, sInstanceId, sizeof(sInstanceId)/sizeof(sInstanceId[0])) ? S_OK : E_FAIL);
-
-    if(SUCCEEDED(hr))
+    /* put game's instance id on the end of path, only if instance id was given */
+    if(gameInstanceId)
     {
-        lstrcatW(sRegistryPath, sBackslash);
-        lstrcatW(sRegistryPath, sInstanceId);
+        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))
@@ -691,6 +695,90 @@ static HRESULT GAMEUX_UpdateGame(LPGUID InstanceID) {
     return hr;
 }
 /*******************************************************************************
+ * GAMEUX_FindGameInstanceId
+ *
+ * Helper funtion. Searches for instance identifier of given game in given
+ * installation scope.
+ *
+ * Parameters:
+ *  sGDFBinaryPath                          [I]     path to binary containing GDF
+ *  installScope                            [I]     game install scope to search in
+ *  pInstanceId                             [O]     instance identifier of given game
+ *
+ * Returns:
+ *  S_OK                    id was returned properly
+ *  S_FALSE                 id was not found in the registry
+ *  E_OUTOFMEMORY           problem while memory allocation
+ */
+static 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
  */
 
@@ -872,9 +960,31 @@ static HRESULT WINAPI GameExplorer2Impl_InstallGame(
         LPCWSTR installDirectory,
         GAME_INSTALL_SCOPE installScope)
 {
+    HRESULT hr;
+    GUID instanceId;
     GameExplorerImpl *This = impl_from_IGameExplorer2(iface);
-    FIXME("stub (%p, %s, %s, 0x%x)\n", This, debugstr_w(binaryGDFPath), debugstr_w(installDirectory), installScope);
-    return E_NOTIMPL;
+
+    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(
diff --git a/dlls/gameux/tests/gameexplorer.c b/dlls/gameux/tests/gameexplorer.c
index 8553890..4fc432b 100644
--- a/dlls/gameux/tests/gameexplorer.c
+++ b/dlls/gameux/tests/gameexplorer.c
@@ -491,7 +491,7 @@ static void _findGameInstanceId(int line,
     }
 
     CoTaskMemFree(lpRegistryPath);
-    todo_wine ok_(__FILE__, line)(found==TRUE, "cannot find game with GDF path %s in scope %d\n",
+    ok_(__FILE__, line)(found==TRUE, "cannot find game with GDF path %s in scope %d\n",
             wine_dbgstr_w(sGDFBinaryPath), installScope);
 }
 /*******************************************************************************
@@ -636,20 +636,20 @@ void test_install_uninstall_game(void)
 
 
         hr = IGameExplorer2_InstallGame(ge2, sExeName, sExePath, GIS_CURRENT_USER);
-        todo_wine ok(SUCCEEDED(hr), "IGameExplorer2::InstallGame failed (error 0x%08x)\n", hr);
+        ok(SUCCEEDED(hr), "IGameExplorer2::InstallGame failed (error 0x%08x)\n", hr);
         /* in comparision to AddGame, InstallGame does not return instance ID,
          * so we need to find it manually */
         _findGameInstanceId(__LINE__, sExeName, GIS_CURRENT_USER, &guid);
 
         if(SUCCEEDED(hr))
         {
-            todo_wine _validateGameRegistryKey(__LINE__, GIS_CURRENT_USER, &guid, &applicationId, sExePath, sExeName, TRUE);
+            _validateGameRegistryKey(__LINE__, GIS_CURRENT_USER, &guid, &applicationId, sExePath, sExeName, TRUE);
 
             hr = IGameExplorer2_UninstallGame(ge2, sExeName);
             todo_wine ok(SUCCEEDED(hr), "IGameExplorer2::UninstallGame failed (error 0x%08x)\n", hr);
         }
 
-        _validateGameRegistryKey(__LINE__, GIS_CURRENT_USER, &guid, &applicationId, sExePath, sExeName, FALSE);
+        todo_wine _validateGameRegistryKey(__LINE__, GIS_CURRENT_USER, &guid, &applicationId, sExePath, sExeName, FALSE);
 
         IGameExplorer2_Release(ge2);
     }




More information about the wine-cvs mailing list