https://bugs.winehq.org/show_bug.cgi?id=57758
--- Comment #11 from Paul Gofman pgofman@codeweavers.com --- Created attachment 78051 --> https://bugs.winehq.org/attachment.cgi?id=78051 ad-hoc test illustrating that case conversion during hashing is required
The attached patch also fixes the crash, and it doesn't break the HashLinks tests in dlls/kernel32/tests/module.c. Are we certain that HashLinks is supposed to be case-insensitive?
Basically, since the search for module is case insensitive I am afraid hashing has to be case-insensitive too, no way around. It is not immediately trivial to confirm in test that there is a difference because for the typical cases the difference in codes between capical and low case letter is 32. And so is HASH_MAP_SIZE (hash_basename returns hash % HASH_MAP_SIZE), so one character effectively affects hash as (*hash = *hash * 65599 + string->Buffer[i]) % 32, and if the two characters' codes differ in 32 the result is the same for them (that can be proved mathematically). So for the typical case (and always for ascii module names) there is no difference in result whether we convert case in RtlHashUnicodeString() or not. However, it is not always the case, e. g., Czech letters Ž and ž differ in 1. So the very ad-hoc and dirty attached test illustrates that case insensitive call to RtlHashUnicodeString() is correct; the test fails on Wine with your patch but succeeds as is and on Windows for me.
But this is not too much related to the present bug anyway. I hope my PoC patch attached to Comment #8 confirms beyond any doubt that the effect of blamed commit is not a wrong functional change but the effect of stack data modification (to be later used erroneously). What is harder to prove beyond any doubt is that, blamed commit aside, the difference in stack data and buggy game behaviour is not triggered by some other, unrelated Wine bug or fixable difference with Windows. However, I tried to build a confidence in that in a way explained in the rest of Comment #8.
So of course random changes on GetModuleHandleA can tweak the reproduction on and off depending on which bytes it ends up modifying on its local stack and how. But we don't have a control of that in C really, nor we can guarantee the exact stack leftover garbage matching Windows. If we were to workaround this game bug reliably the only possible way is something between the line of the patch in Comment #8 (with some cleanup, like sanitizing asm names, reducing extra stack allocation, removing check for return address etc.).
I don't think this bug can be closed, whenever something reliably works on Windows, even if that is a game bug and works by chance, we consider this a bug. But I doubt it can be fixed, while also may start working due to other random changes or switching compiler version (and then randomly stop working again...)