Menu

Win7 MS GameUX shim causing old games to hang

2019-08-12
2023-02-12
1 2 3 > >> (Page 1 of 3)
  • dippy dipper

    dippy dipper - 2019-08-12

    So Microsoft has nuked the metadata server for their Games Explorer feature that was part of Win Vista and 7. What this means is that old games that have the GameUX shim are trying to connect to the Microsoft server and hanging forever consuming CPU power. This hang up would also occure in the past if the computer was not connected to the internet but it is now happening even if connected.

    The simplest way to fix the issue is just to rename the affected games executable to something else. E.g. "game.exe" to "game_noshim.exe".

    A more permanent and general fix is to do a registry edit as explained in this post:
    https://www.gog.com/forum/general/old_games_not_launching_and_eating_100_of_the_cpu_on_windows_7/page1

    So if your old game is hanging up at startup this might explain it. Also note that this should not be an issue if you are using a newer OS like Win8.1 or Win10.

     
    • gho

      gho - 2019-08-12

      Sounds interesting. Is the shim triggered by anything that DxWnd could bypass? It's just a weird idea, but if this shim is activated by some specific event, or executes some specific action, perhaps DxWnd could hook and fix it.
      For instance, faking a tcp/ip cpnnection with a return code.

       
      • dippy dipper

        dippy dipper - 2019-08-13

        I don't think so.

        It is activated if the game executable is listed in the Windows\System32(or SysWOW64)\GameUXLegacyGDFs.dll.
        And I assume Windows\System32(or SysWOW64)\gameux.dll looks up the registry key for the metadata server.

         
        • gho

          gho - 2019-08-13

          I suppose the query is made by the Win loader, beause if it was done by the game directly it would be possible to intercept the RegQueryValueEx (or whatever) and pretend the entry is not there.
          If MS doesn't fix the problem (it should, but considering that Win7 is announced to be unsupported it may not ..) I could add a command to DxWnd menu to clear the registry entry for that game, just for the fearsome newby that should better leave the registry untouched. Let's see ...

           
  • UCyborg

    UCyborg - 2019-08-14

    I know a better fix.

     
    • dippy dipper

      dippy dipper - 2019-08-14

      Your reg edits do not seem to work for me (testing the game "EarthSiege2").

      P.S. Where did you get that GUID list?

       
      • UCyborg

        UCyborg - 2019-08-14

        Right-click on the game .exe or its shortcut, select Compatibility tab and click OK. I ran the query on the database with Compatibility Administrator to get the GUIDs.

         
        • dippy dipper

          dippy dipper - 2019-08-14

          OK, now it works. Sorry for missing that. Pity one needs that extra step visiting the Compatibility tab using this method.

           
          • UCyborg

            UCyborg - 2019-08-14

            The problem is some stubborn cache being kept somewhere after you've already launched the game at least once before applying the registry settings.

             
            • dippy dipper

              dippy dipper - 2019-08-14

              By the way doesn't "dword:00000077" disable all the shims for the listed applications not just GameUX? That might not always be preferable since some of the pre installed shims might still be useful.

               
              • UCyborg

                UCyborg - 2019-08-14

                No, because there are separate entries for actual compatibility shims, which are left as is.

                 
                • dippy dipper

                  dippy dipper - 2019-08-14

                  I had a look at the ACT database query and looks like you are right. The GUID's listed are all tied to the GameUX shim so disabling them should not affect other fixes.

                  P.S. I also noticed you can flush the SDB cache with the "sdbinst -c" command which does the same as visiting the Comp. tab of the executable.

                   
  • huh

    huh - 2019-09-07

    @UCyborg
    Thanks, this seems to have solved my problem with running game Chaser here on Win7, which contains the GameuxInstallHelper.dll library.
    The game already has a record in shim database.
    Because I don't have the Application Compatibility Toolkit, I found the application id by exporting the shim database with the Shim Database Tool (sdb) v1.0 via command
    sdb.exe > sdb.xml and then I searched string chaser.exe.
    At the end of the section was something like
    <command_line tid="0x85df4" typ="STRINGREF">90f6e8b5-4bfb-4515-8347-62e753414268</command_line>
    I also found this value in the registers
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\GameUX\This string is different on other computers{CCC0ACDD-09B5-4E1D-851C-6D4F249FADB6}]
    "ConfigApplicationPath"="C:\Games\Chaser"
    "ApplicationId"="{90f6e8b5-4bfb-4515-8347-62e753414268}"
    Then I created the .reg and unreg.reg files according to your instructions and so far it looks like it works.

     
    • gho

      gho - 2019-09-07

      @huh:
      the manual process you put in place could perhaps be automated.
      It goes through the following steps:

      • dump the shim dm and search the target program
      • take note of the shim uuid (90f6e8b5-4bfb-4515-8347-62e753414268 in your case)
      • search the program in the GameUX shims registry section
      • clear the registry

      I'm going to ask you a favor: may I have a copy of your shim database file? I don't have Chaser installed on my pc and I'm not sure that if even I install it I could get the shim activated, Dumping your file is the easiest way to find out if DxWnd could do at least the first step (AFAIK it should be the same logic of the view->shims DxWnd command, but that command often provided unreliable results)

       

      Last edit: gho 2019-09-07
      • huh

        huh - 2019-09-07

        Sure, here's the whole shim database from Win7.

        clear the registry

        I would like to say that I did not delete the registry, but followed the instructions of UCyborg ie.
        I wrote the appid here over my .reg file.
        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags]
        "{90f6e8b5-4bfb-4515-8347-62e753414268}"=dword:0000007
        Well, in fact, the key with the value was written to
        [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags]
        probably due to 64bit OS.

        Update:
        Unfortunately, I ran Chaser this morning and the game hangs in my memory the first time I start it again.
        I have to kill chaser.exe in memory and run the game a second time then it's okay.
        So I added next change of registers (I kept the previous shim key).
        [HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\GameUX\ServiceLocation]
        "Games"="127.0.0.1"
        Now I have 2 changed registry entries, the game starts at the first time, I tried it four times and the game started at the first time (between each run I did a computer restart).

         

        Last edit: huh 2019-09-08
  • gho

    gho - 2023-02-04

    Here it is, untested and to be verified. I had to make some changes to the code and also copy from the web a custom implementation of the missing stristr e wcsistr functions, so the result is not for granted.
    Please, after the experiment collect and post here a dxwnd.log file with (at least) the "Logs / DxWnd hacks" flag enabled.

     
    • Cthulhu

      Cthulhu - 2023-02-04

      I'll remove the registry keys and give this a shot either tonight or tomorrow.

      P.S. You could've used these shell functions: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-strstria and https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-strstriw

       
    • Cthulhu

      Cthulhu - 2023-02-04

      @ghotik Here are some preliminary data:

      1. Works only with an early injection method (tested with Inject DLL and Window hook).
      2. Somehow, the rundll32 process is still around and keeps retrying a TCP connection to the MS server ad infinitum (C:\Windows\system32\rundll32.exe C:\Windows\system32\gameux.dll,GameUXShim {0ec84280-f6b5-413b-ae51-614776bd2950};F:\Fable The Lost Chapters\Fable.exe;4044).
      3. I can't find anything in the log file regarding this hack (no mentions of CreateProcess and gameux) and the log file is over 4k lines just with "DxWnd hacks" enabled and the game immediately closed at the initial splash screen. I'd rather not go through all of it to ensure it's safe for public sharing (privacy concerns). If you could tell me what I should look for, I'll gladly provide you with the data.

      P.S. This is the retail version of the game, not the Steam one.

      EDIT: A quick look at the dll's symbol table gave me this string: "%s: SUPPRESS GAMEUX Commandline=%s". I clearly don't have it in the log, is there a setting I should enable? So far I've assumed this hack is hardcoded in and always applied within the dll you sent me as I couldn't find any settings for it.

       

      Last edit: Cthulhu 2023-02-04
  • gho

    gho - 2023-02-04

    Works only with an early injection method

    Well, this could be expected. The early injection is the only method that should assure to catch everything that you need. The Elishacloud hack is in a ddraw proxy, that could behave as an early hook methods (when the ddraw.dll is linked and so loaded immediately at the program start)

    Somehow, the rundll32 process is still around

    If you look at Elishacloud code, il searched the "gameux.dll,GameUXShim" string and then cuts everything after the comma ",", so the string "gameux.dll" remains there ...

    If you could tell me what I should look for ...

    That's easy, I look for "gameux.dll,GameUXShim" or "CreateProcess" substrings. How comes that you say there are no mentions of these? If they don't appear, the fix should not work ...
    I need to understand better what happens, for instance what is the exact full command and who/when/why is issued?

    Is there a way for me to replicate the problem on a Win11 machine?

     
    • Cthulhu

      Cthulhu - 2023-02-04
      1. Indeed, but a "rundll32.exe gameux.dll" call appears to never deadlock trying a TCP connection; meanwhile I am getting the old command-line signature with the shim and game signature.
      2. Check my edit, is there a specific setting I need to enable? It's very odd because Fable.exe hangs forever without "Inject DLL", with rundll32 never completing. With "Inject DLL" the game doesn't deadlock, but you can still find rundll32, effectively deadlocked, attempting TCP connections; you even have to manually kill it afterwards.

      I don't believe you can reproduce this on Windows 11, unless you run a Windows 7 VM there.

       

      Last edit: Cthulhu 2023-02-04
    • Cthulhu

      Cthulhu - 2023-02-05

      Here is what I've found after some quick debugging:

      1. Starting the process with a debugger and a breakpoint at its entry point, shows that rundll32 is already running (and deadlocked); the breakpoint is NEVER triggered. Fable.exe is in the process table with both stack and heap allocated.
      2. The "rundll32.exe gameux.dll" process seems to be spawned internally by Windows and it doesn't care what the dll does; as long as the process exits with a "0" code, then it resumes the original process, calling its entry point.
      3. Calling rundll32.exe with a non-existent dll causes it to exit with a "0" code.
      4. If the previous rundll32.exe process is left untouched (and deadlocked) and you try to start the game again, Windows will skip spawning a new rundll32.exe process and immediately calls the original process's entry point.

      I don't know whether the author of the hack tested this or not, but it seems impossible to catch this from within the process.
      Other than renaming the exe, deleting/renaming/moving gameux.dll and the registry hacks, there doesn't seem to be a way out of this; a classic example of why developers should always avoid novel Microsoft "features" imo.

      In theory, we could create a proxy gameux.dll, renaming the original one to something else and redirect anything that doesn't get called with the "GameUXShim" paramater. This however, would require putting the proxy dll into system32.
      We could also patch the original gameux.dll to return just before attempting the TCP connection; that would violate Microsoft's signature, however.

      Full command-line:
      %SystemRoot%\system32\rundll32.exe %SystemRoot%\system32\gameux.dll,GameUXShim {PROGRAM_GUID};PROGRAM_FULL_PATH;PROGRAM_PID

      EDIT: As to how Inject DLL is able to bypass it despite rundll32.exe being launched and deadlocked, I have no clue.

       

      Last edit: Cthulhu 2023-02-05
  • gho

    gho - 2023-02-05

    The hack was hardcoded into the experimental dxwnd.dll, no need to set any flag to activate it.
    So, if you don't find any trace of the mentioned strings in the log, that would indicate that the hack was bypassed. Why does it work in injection mode? I don't know, maybe a different execution mode, but the trick should work also without the patched dxwnd.dll, is that so?
    About the fake gameux.dll, that is not a bad idea. Usually it's not wise to mess in system files, but replacing something that hangs your programs can hardly do worse than this.
    Making a fake gameux.dll shouldn't be too hard, the exported symbols are not too many, the only problem is the lack of documentation and signature for the GameUXShimW call, but one could guess it by trials and errors by using fake prototypes with an increasing number of LPVOID arguments until the launcher doesn't crash (or entering the dll with a debugger and looking at the stack decrement upon return).
    Since there are trials and errors in the process, I suppose that if you have some confidence with a compiler you may try that yourself, otherwise I will do it but it will take more interactions to test it.
    Anyway, in the end I'd like to add this fake gameux.dll in the DxWnd bundle (and you in the hall of fame, of course ...).
    What about it?

     

    Last edit: gho 2023-02-05
    • Cthulhu

      Cthulhu - 2023-02-05

      Those exported functions are likely stdcall just like the rest of the WinAPI functions, and we don't need to worry about the parameters, since we want to return immediately.
      The dll is 32-bits, we can use __declspec(naked) on MSVC, with a "ret" instruction for the functions we want to bypass and a "jmp" instruction for the ones we want to redirect.

      I'll debug the call to GameUXShim in order to make sure I pass the correct size to ret; the full command-line gives a pretty good idea of the number of arguments and their type.

      I'll write it so that it compiles for both ANSI C and C++, but I'll leave the project file (and production compilation/deployment) for you to tweak as you deem fit.

      And yes, normal DxWnd loads Fable.exe normally with Inject DLL, even if rundll32.exe is not running (it still launches and deadlocks rundll32 though).
      Window hook loads it normally if rundll32.exe is already running or one of the tricks to bypass GameUXShim is applied.

       
1 2 3 > >> (Page 1 of 3)

Log in to post a comment.