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