- Removed tick and time values from ThreadSavedState.
- Removed affiliated get/set code from Save and Restore.
- Removed dangerous SetGuestTickCount method.
This fixes cases introduced by 52e836d0f81e752ba368717e68773b591adfa9cf
where thread handles get closed before the thread finishes.
Handle was assumed to be alive there, which was not true as
threads self-referenced only their objects, not their handles.
Affected games: Payday 2 Demo
Although this seems counter-intuitive, operating on handle
reference counters in
- ObLookupThreadByThreadId
- ObReferenceObjectByHandle
- ObDereferenceObject
allows to cleanly clean up handles for resources created elsewhere
and destructed by ObDereferenceObject (for example, threads with 0x80
creation flag). Operating on pointer reference counters alone
would leave a stray handle in the slots list.
Closing the thread handle should delete the thread object
if it's finished. When this handle was retained, closing the handle
left a lingering handle reference and thus this XThread would leak
- [Kernel] Rename game_language cvar to user_language.
- [Kernel] Recategorize user_language to XConfig.
- [Kernel] Add user_country cvar, used instead of hardcoded value in XConfig.
- [XAM] Use user_country cvar for xeXamGetLocaleEx instead of
xeExGetXConfigSetting.
Games like Forza use NtQueryInformationFile to get the size of the file, to make sure that there's enough room inside it to write data.
Previously, updating the file size (via SetInfoFile(EndOfFile) or WriteFile) wouldn't update the vfs::Entry size field, which NtQueryInfo uses to return the size of the file.
This resulted in the game thinking that the file was smaller than it actually is, and trying to correct that by using SetInfoFile(EndOfFile), which then truncated the file and deleted important data that was written to it.
Previously adding a notification that already exists would just overwrite the older notifications value, meaning the game would never see that older notification.
This would break games like Project Sylpheed, which seems to require seeing XN_SYS_UI = true eventually followed by XN_SYS_UI = false for the game to realize all system UIs are closed.