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