Work around MSVC bug, and make it less likely to happen again. Ew.

MSVC insisted on using a copy assignment where a move was intended and
ought to be used.  This would have been caught, because the class in
question inherits from NonCopyable, which declares a move assignment
operator, which is supposed to delete the implicitly declared copy
assignment operator, but of course MSVC didn't do that either, causing a
class that should have been safe to be unsafe.
This commit is contained in:
comex 2013-08-31 23:44:26 -04:00
parent 5209abeb03
commit a6f6695ecd
5 changed files with 29 additions and 9 deletions

View File

@ -37,6 +37,9 @@ protected:
NonCopyable() {}
NonCopyable(const NonCopyable&&) {}
void operator=(const NonCopyable&&) {}
private:
NonCopyable(NonCopyable&);
NonCopyable& operator=(NonCopyable& other);
};
#endif

View File

@ -853,7 +853,7 @@ IOFile::IOFile(IOFile&& other)
IOFile& IOFile::operator=(IOFile&& other)
{
IOFile((IOFile&&)other).Swap(*this);
Swap(other);
return *this;
}

View File

@ -211,6 +211,9 @@ public:
std::FILE* m_file;
bool m_good;
private:
IOFile(IOFile&);
IOFile& operator=(IOFile& other);
};
} // namespace

View File

@ -182,6 +182,10 @@ bool CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress, bool _bForce)
{
// Leave deletion of the INANDContentLoader objects to CNANDContentManager, don't do it here!
m_NANDContent.clear();
for (auto itr = m_ContentAccessMap.begin(); itr != m_ContentAccessMap.end(); ++itr)
{
delete itr->second.m_pFile;
}
m_ContentAccessMap.clear();
m_pContentLoader = NULL;
m_TitleIDs.clear();
@ -222,15 +226,15 @@ u32 CWII_IPC_HLE_Device_es::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index)
std::string Filename = pContent->m_Filename;
INFO_LOG(WII_IPC_ES, "ES: load %s", Filename.c_str());
Access.m_File.Open(Filename, "rb");
if (!Access.m_File.IsGood())
Access.m_pFile = new File::IOFile(Filename, "rb");
if (!Access.m_pFile->IsGood())
{
WARN_LOG(WII_IPC_ES, "ES: couldn't load %s", Filename.c_str());
return 0xffffffff;
}
}
m_ContentAccessMap[CFD] = std::move(Access);
m_ContentAccessMap[CFD] = Access;
return CFD;
}
@ -392,7 +396,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
}
else
{
File::IOFile* pFile = &rContent.m_File;
auto& pFile = rContent.m_pFile;
if (!pFile->Seek(rContent.m_Position, SEEK_SET))
{
ERROR_LOG(WII_IPC_ES, "ES: couldn't seek!");
@ -423,10 +427,18 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
m_ContentAccessMap.erase(CFD);
INFO_LOG(WII_IPC_ES, "IOCTL_ES_CLOSECONTENT: CFD %x", CFD);
auto itr = m_ContentAccessMap.find(CFD);
if (itr == m_ContentAccessMap.end())
{
Memory::Write_U32(-1, _CommandAddress + 0x4);
return true;
}
delete itr->second.m_pFile;
m_ContentAccessMap.erase(itr);
Memory::Write_U32(0, _CommandAddress + 0x4);
return true;
}

View File

@ -8,6 +8,7 @@
#include <map>
#include "WII_IPC_HLE_Device.h"
#include "NANDContentLoader.h"
#include <memory>
class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device
{
@ -112,12 +113,13 @@ private:
ES_HASH_SIZE_WRONG = -2014, // HASH !=20
};
struct SContentAccess : public NonCopyable
struct SContentAccess
{
u32 m_Position;
u64 m_TitleID;
const DiscIO::SNANDContent* m_pContent;
File::IOFile m_File;
// This is a (raw) pointer to work around a MSVC bug.
File::IOFile* m_pFile;
};
typedef std::map<u32, SContentAccess> CContentAccessMap;