diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp index 63c3d1720e..529ab1b057 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp @@ -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) @@ -320,22 +320,22 @@ void DoState(PointerWrap &p) } else { - for (auto& dev : g_FdMap) + for (auto& descriptor : g_FdMap) { - u32 exists = dev ? 1 : 0; + u32 exists = descriptor ? 1 : 0; p.Do(exists); if (exists) { - u32 isHw = dev->IsHardware() ? 1 : 0; + u32 isHw = descriptor->IsHardware() ? 1 : 0; p.Do(isHw); if (isHw) { - u32 hwId = dev->GetDeviceID(); + u32 hwId = descriptor->GetDeviceID(); p.Do(hwId); } else { - dev->DoState(p); + descriptor->DoState(p); } } } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h index 0702b502be..a5100a4953 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h @@ -109,6 +109,11 @@ public: { } + // Release any resources which might interfere with savestating. + virtual void PrepareForState(PointerWrap::Mode mode) + { + } + virtual void DoState(PointerWrap& p) { DoStateShared(p); diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index d92950b7f7..136533d03e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -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); @@ -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(); } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h index c8715a4a86..880887a637 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h @@ -26,6 +26,7 @@ public: 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();