Mariusz Pluciński : gameux/tests: Check presence of GameExplorer registry keys.
Alexandre Julliard
julliard at winehq.org
Mon Aug 23 10:50:20 CDT 2010
Module: wine
Branch: master
Commit: 6cb7658377ac513e8acacd5b4eaeab4632afaadc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6cb7658377ac513e8acacd5b4eaeab4632afaadc
Author: Mariusz Pluciński <vshader at gmail.com>
Date: Mon Aug 23 13:13:38 2010 +0200
gameux/tests: Check presence of GameExplorer registry keys.
---
dlls/gameux/tests/Makefile.in | 2 +-
dlls/gameux/tests/gameexplorer.c | 199 +++++++++++++++++++++++++++++++++++++-
2 files changed, 195 insertions(+), 6 deletions(-)
diff --git a/dlls/gameux/tests/Makefile.in b/dlls/gameux/tests/Makefile.in
index 542fc29..3127ec0 100644
--- a/dlls/gameux/tests/Makefile.in
+++ b/dlls/gameux/tests/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../../..
SRCDIR = @srcdir@
VPATH = @srcdir@
TESTDLL = gameux.dll
-IMPORTS = uuid shlwapi oleaut32 ole32
+IMPORTS = uuid shlwapi oleaut32 ole32 advapi32
C_SRCS = \
gameexplorer.c \
diff --git a/dlls/gameux/tests/gameexplorer.c b/dlls/gameux/tests/gameexplorer.c
index 3decfa2..79349f5 100644
--- a/dlls/gameux/tests/gameexplorer.c
+++ b/dlls/gameux/tests/gameexplorer.c
@@ -25,6 +25,7 @@
#include "objsafe.h"
#include "objbase.h"
#include "shlwapi.h"
+#include "sddl.h"
#include "shobjidl.h"
#include "initguid.h"
@@ -32,7 +33,179 @@
#include "wine/test.h"
+/*******************************************************************************
+ * Pointers used instead of direct calls. These procedures are not available on
+ * older system, which causes problem while loading test binary.
+ */
+static BOOL WINAPI (*_ConvertSidToStringSidW)(PSID,LPWSTR*);
+
+/*******************************************************************************
+ *_loadDynamicRoutines
+ *
+ * Helper function, prepares pointers to system procedures which may be not
+ * available on older operating systems.
+ *
+ * Returns:
+ * TRUE procedures were loaded successfunnly
+ * FALSE procedures were not loaded successfunnly
+ */
+static BOOL _loadDynamicRoutines(void)
+{
+ HMODULE hAdvapiModule = GetModuleHandleA( "advapi32.dll" );
+
+ _ConvertSidToStringSidW = (LPVOID)GetProcAddress(hAdvapiModule, "ConvertSidToStringSidW");
+ if (!_ConvertSidToStringSidW) return FALSE;
+ return TRUE;
+}
+
+/*******************************************************************************
+ * _buildGameRegistryPath
+ *
+ * Helper function, builds registry path to key, where game's data are stored
+ *
+ * Parameters:
+ * installScope [I] the scope which was used in AddGame/InstallGame call
+ * gameInstanceId [I] game instance GUID
+ * lpRegistryPath [O] pointer which will receive address to string
+ * containing expected registry path. Path
+ * is relative to HKLM registry key. It
+ * must be freed by calling CoTaskMemFree
+ */
+static HRESULT _buildGameRegistryPath(GAME_INSTALL_SCOPE installScope,
+ LPCGUID gameInstanceId,
+ LPWSTR* lpRegistryPath)
+{
+ static const WCHAR sGameUxRegistryPath[] = {'S','O','F','T','W','A','R','E','\\',
+ 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
+ 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','G','a','m','e','U','X',0};
+ static const WCHAR sGames[] = {'G','a','m','e','s',0};
+ static const WCHAR sBackslash[] = {'\\',0};
+
+ HRESULT hr = S_OK;
+ HANDLE hToken = NULL;
+ PTOKEN_USER pTokenUser = NULL;
+ DWORD dwLength;
+ LPWSTR lpSID = NULL;
+ WCHAR sInstanceId[40];
+ WCHAR sRegistryPath[8192];
+
+ lstrcpyW(sRegistryPath, sGameUxRegistryPath);
+ lstrcatW(sRegistryPath, sBackslash);
+
+ if(installScope == GIS_CURRENT_USER)
+ {
+ /* build registry path containing user's SID */
+ if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ if(SUCCEEDED(hr))
+ {
+ if(!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) &&
+ GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ if(SUCCEEDED(hr))
+ {
+ pTokenUser = CoTaskMemAlloc(dwLength);
+ if(!pTokenUser)
+ hr = E_OUTOFMEMORY;
+ }
+
+ if(SUCCEEDED(hr))
+ if(!GetTokenInformation(hToken, TokenUser, (LPVOID)pTokenUser, dwLength, &dwLength))
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ if(SUCCEEDED(hr))
+ if(!_ConvertSidToStringSidW(pTokenUser->User.Sid, &lpSID))
+ hr = HRESULT_FROM_WIN32(GetLastError());
+
+ if(SUCCEEDED(hr))
+ {
+ lstrcatW(sRegistryPath, lpSID);
+ LocalFree(lpSID);
+ }
+
+ CoTaskMemFree(pTokenUser);
+ CloseHandle(hToken);
+ }
+ }
+ else if(installScope == GIS_ALL_USERS)
+ /* build registry path without SID */
+ lstrcatW(sRegistryPath, sGames);
+ 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))
+ {
+ lstrcatW(sRegistryPath, sBackslash);
+ lstrcatW(sRegistryPath, sInstanceId);
+ }
+
+ if(SUCCEEDED(hr))
+ {
+ *lpRegistryPath = CoTaskMemAlloc((lstrlenW(sRegistryPath)+1)*sizeof(WCHAR));
+ if(!*lpRegistryPath)
+ hr = E_OUTOFMEMORY;
+ }
+
+ if(SUCCEEDED(hr))
+ lstrcpyW(*lpRegistryPath, sRegistryPath);
+
+ return hr;
+}
+/*******************************************************************************
+ * _validateGameKey
+ *
+ * Helper function, verifies current state of game's registry key with expected.
+ *
+ * Parameters:
+ * line [I] place of original call. Used only to display
+ * more useful message on test fail
+ * installScope [I] the scope which was used in AddGame/InstallGame call
+ * gameInstanceId [I] game instance identifier
+ * presenceExpected [I] is it expected that game should be currently
+ * registered or not. Should be TRUE if checking
+ * after using AddGame/InstallGame, and FALSE
+ * if checking after RemoveGame/UninstallGame
+ */
+static void _validateGameRegistryKey(int line,
+ GAME_INSTALL_SCOPE installScope,
+ LPCGUID gameInstanceId,
+ BOOL presenceExpected)
+{
+ HRESULT hr;
+ LPWSTR lpRegistryPath = NULL;
+ HKEY hKey;
+
+ /* check key presence */
+ hr = _buildGameRegistryPath(installScope, gameInstanceId, &lpRegistryPath);
+
+ if(SUCCEEDED(hr))
+ {
+ hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_LOCAL_MACHINE, lpRegistryPath, 0,
+ KEY_READ | KEY_WOW64_64KEY, &hKey));
+
+ if(presenceExpected)
+ ok_(__FILE__, line)(hr == S_OK,
+ "problem while trying to open registry key (HKLM): %s, error: 0x%x\n", wine_dbgstr_w(lpRegistryPath), hr);
+ else
+ ok_(__FILE__, line)(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+ "other than expected (FILE_NOT_FOUND) error while trying to open registry key (HKLM): %s, error: 0x%x\n", wine_dbgstr_w(lpRegistryPath), hr);
+ }
+
+ if(SUCCEEDED(hr))
+ RegCloseKey(hKey);
+
+ CoTaskMemFree(lpRegistryPath);
+}
+
+/*******************************************************************************
+ * Test routines
+ */
static void test_create(BOOL* gameExplorerAvailable)
{
HRESULT hr;
@@ -106,10 +279,14 @@ static void test_add_remove_game(void)
if(SUCCEEDED(hr))
{
+ todo_wine _validateGameRegistryKey(__LINE__, GIS_CURRENT_USER, &guid, TRUE);
+
hr = IGameExplorer_RemoveGame(ge, guid);
todo_wine ok(SUCCEEDED(hr), "IGameExplorer::RemoveGame failed (error 0x%08x)\n", hr);
}
+ _validateGameRegistryKey(__LINE__, GIS_CURRENT_USER, &guid, FALSE);
+
/* try to register game with empty guid */
memcpy(&guid, &GUID_NULL, sizeof (guid));
@@ -120,9 +297,13 @@ static void test_add_remove_game(void)
if(SUCCEEDED(hr))
{
+ todo_wine _validateGameRegistryKey(__LINE__, GIS_CURRENT_USER, &guid, TRUE);
+
hr = IGameExplorer_RemoveGame(ge, guid);
todo_wine ok(SUCCEEDED(hr), "IGameExplorer::RemoveGame failed (error 0x%08x)\n", hr);
}
+
+ _validateGameRegistryKey(__LINE__, GIS_CURRENT_USER, &guid, FALSE);
}
/* free allocated resources */
@@ -138,13 +319,21 @@ START_TEST(gameexplorer)
HRESULT r;
BOOL gameExplorerAvailable = FALSE;
- r = CoInitialize( NULL );
- ok( r == S_OK, "failed to init COM\n");
+ if(_loadDynamicRoutines())
+ {
+ r = CoInitialize( NULL );
+ ok( r == S_OK, "failed to init COM\n");
+
+ test_create(&gameExplorerAvailable);
- test_create(&gameExplorerAvailable);
+ if(gameExplorerAvailable)
+ test_add_remove_game();
+ }
+ else
+ /* this is not a failure, because both procedures loaded by address
+ * are always available on systems which has gameux.dll */
+ win_skip("too old system, cannot load required dynamic procedures\n");
- if(gameExplorerAvailable)
- test_add_remove_game();
CoUninitialize();
}
More information about the wine-cvs
mailing list