Skip to content

Commit

Permalink
IPC_HLE: Close file handles before savestating. Fixes DKCR crashing.
Browse files Browse the repository at this point in the history
Donkey Kong Country Returns is writing new data to some files in /tmp
when loading each level. But the savestate code was opening the files
a second time and reading some old and stale data out.

As of dolphin-emu#3798, dolphin now correctly restores that stale data to /tmp,
which broke DKCR (and probally countless other games).

This PR closes all file handles before saving and loading savestates,
which flushes the data out and pervents this issue. (old savestates
are corrupted and will still cause crashes if loaded)
  • Loading branch information
phire committed May 29, 2016
1 parent 6233620 commit f419faa
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 8 deletions.
8 changes: 4 additions & 4 deletions Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,11 @@ void DoState(PointerWrap &p)
p.Do(reply_queue);
p.Do(last_reply_time);

if (p.GetMode() == PointerWrap::MODE_READ)
// We need to make sure all file handles are closed so WII_IPC_Devices_fs::DoState can successfully save or re-create /tmp
for (auto& descriptor : g_FdMap)
{
// We need to make sure all file handles are closed so WII_IPC_Devices_fs::DoState can successfully re-create /tmp
for (u32 i = 0; i < IPC_MAX_FDS; i++)
g_FdMap[i].reset();
if (descriptor)
descriptor->PrepareForState(p.GetMode());
}

for (const auto& entry : g_DeviceMap)
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ class IWII_IPC_HLE_Device
{
}

// Release any resources which might interfere with savestating.
virtual void PrepareForState(PointerWrap::Mode mode)
{
}

virtual void DoState(PointerWrap& p)
{
DoStateShared(p);
Expand Down
15 changes: 11 additions & 4 deletions Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,14 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
return GetDefaultReply();
}


void CWII_IPC_HLE_Device_FileIO::PrepareForState(PointerWrap::Mode mode)
{
// Temporally close the file, to prevent any issues with the savestating of /tmp
// it can be opened again with another call to OpenFile()
m_file.reset();
}

void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
{
DoStateShared(p);
Expand All @@ -365,8 +373,7 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)

m_filepath = HLE_IPC_BuildFilename(m_Name);

if (p.GetMode() == PointerWrap::MODE_READ)
{
OpenFile();
}
// The file was closed during state (and might now be pointing at another file)
// Open it again
OpenFile();
}
1 change: 1 addition & 0 deletions Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device
IPCCommandResult Read(u32 _CommandAddress) override;
IPCCommandResult Write(u32 _CommandAddress) override;
IPCCommandResult IOCtl(u32 _CommandAddress) override;
void PrepareForState(PointerWrap::Mode mode) override;
void DoState(PointerWrap &p) override;

void OpenFile();
Expand Down

0 comments on commit f419faa

Please sign in to comment.