Fix some wii IPC stuff:

/dev/fs: IOCTLV_GETUSAGE
/dev/es: IOCTL_ES_GETCONSUMPTION
IOCTL_ES_GETTITLECONTENTSCNT
IOCTL_ES_GETTITLECONTENTS
IOCTL_ES_SETUID

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4489 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2009-10-31 09:20:24 +00:00
parent 1d666bf109
commit 2913d1fd9e
3 changed files with 130 additions and 126 deletions

View File

@ -147,7 +147,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{ {
case IOCTL_ES_GETDEVICEID: case IOCTL_ES_GETDEVICEID:
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETDEVICEID no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETDEVICEID no out buffer");
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICEID"); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICEID");
// Return arbitrary device ID - TODO allow user to set value? // Return arbitrary device ID - TODO allow user to set value?
@ -157,63 +157,60 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
} }
break; break;
case IOCTL_ES_GETTITLECONTENTSCNT: case IOCTL_ES_GETTITLECONTENTSCNT:
{ {
_dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1); _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1);
_dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1);
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
const DiscIO::INANDContentLoader& rNANDCOntent = AccessContentDevice(TitleID); const DiscIO::INANDContentLoader& rNANDCOntent = AccessContentDevice(TitleID);
_dbg_assert_(WII_IPC_ES, rNANDCOntent.IsValid()); u16 NumberOfPrivateContent = 0;
if (rNANDCOntent.IsValid()) // Not sure if dolphin will ever fail this check
{
NumberOfPrivateContent = rNANDCOntent.GetNumEntries();
u32 NumberOfPrivateContent = 0; if ((u32)(TitleID>>32) == 0x00010000)
const std::vector<DiscIO::SNANDContent>& rContent = rNANDCOntent.GetContent(); Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
for (size_t i=0; i<rContent.size();i++) else
{ Memory::Write_U32(NumberOfPrivateContent, Buffer.PayloadBuffer[0].m_Address);
if ((rContent[i].m_Type & 0x8000) == 0)
{
NumberOfPrivateContent++;
}
}
Memory::Write_U32(NumberOfPrivateContent, Buffer.PayloadBuffer[0].m_Address); Memory::Write_U32(0, _CommandAddress + 0x4);
}
else
Memory::Write_U32((u32)rNANDCOntent.GetContentSize(), _CommandAddress + 0x4);
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLECONTENTSCNT: TitleID: %08x/%08x content count %i (just content in private directory)", INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTSCNT: TitleID: %08x/%08x content count %i",
(u32)(TitleID>>32), (u32)TitleID, rNANDCOntent.GetContentSize()); (u32)(TitleID>>32), (u32)TitleID, rNANDCOntent.IsValid() ? NumberOfPrivateContent : (u32)rNANDCOntent.GetContentSize());
Memory::Write_U32(0, _CommandAddress + 0x4); return true;
return true; }
} break;
break;
case IOCTL_ES_GETTITLECONTENTS: case IOCTL_ES_GETTITLECONTENTS:
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTITLECONTENTS no in buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "IOCTL_ES_GETTITLECONTENTS bad in buffer");
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTITLECONTENTS no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETTITLECONTENTS bad out buffer");
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); u32 MaxSize = Memory::Read_U32(Buffer.InBuffer[1].m_Address); // unused?
std::string TitlePath = CreateTitleContentPath(TitleID);
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitlePath);
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: title: %08x/%08x MaxCount: %i (just content in private directory)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); const DiscIO::INANDContentLoader& rNANDCOntent = AccessContentDevice(TitleID);
if (rNANDCOntent.IsValid()) // Not sure if dolphin will ever fail this check
{
for (u16 i = 0; i < rNANDCOntent.GetNumEntries(); i++)
{
Memory::Write_U32(rNANDCOntent.GetContentByIndex(i)->m_ContentID, Buffer.PayloadBuffer[0].m_Address + i*4);
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Index %d: %08x", i, rNANDCOntent.GetContentByIndex(i)->m_ContentID);
}
Memory::Write_U32(0, _CommandAddress + 0x4);
}
else
{
Memory::Write_U32((u32)rNANDCOntent.GetContentSize(), _CommandAddress + 0x4);
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Unable to open content %d", rNANDCOntent.GetContentSize());
}
_dbg_assert_(WII_IPC_ES, Loader.GetContentSize() == MaxCount);
if (Loader.IsValid())
{
const std::vector<DiscIO::SNANDContent>& rContent = Loader.GetContent();
for (int i = 0; i < (int)Loader.GetContentSize(); i++)
{
if ((rContent[i].m_Type & 0x8000) == 0)
{
Memory::Write_U32(rContent[i].m_ContentID, Buffer.PayloadBuffer[0].m_Address + i*4);
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Index 0x%x", rContent[i].m_ContentID);
}
}
}
Memory::Write_U32(0, _CommandAddress + 0x4);
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Count %i", Loader.GetContentSize());
return true; return true;
} }
break; break;
@ -237,7 +234,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
CFD = 0xffffffff; //TODO: what is the correct error value here? CFD = 0xffffffff; //TODO: what is the correct error value here?
Memory::Write_U32(CFD, _CommandAddress + 0x4); Memory::Write_U32(CFD, _CommandAddress + 0x4);
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_OPENTITLECONTENT: TitleID: %08x/%08x Index %i -> got CFD %x", (u32)(TitleID>>32), (u32)TitleID, Index, CFD); INFO_LOG(WII_IPC_ES, "IOCTL_ES_OPENTITLECONTENT: TitleID: %08x/%08x Index %i -> got CFD %x", (u32)(TitleID>>32), (u32)TitleID, Index, CFD);
return true; return true;
} }
break; break;
@ -256,7 +253,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
Memory::Write_U32(CFD, _CommandAddress + 0x4); Memory::Write_U32(CFD, _CommandAddress + 0x4);
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_OPENCONTENT: Index %i -> got CFD %x", Index, CFD); INFO_LOG(WII_IPC_ES, "IOCTL_ES_OPENCONTENT: Index %i -> got CFD %x", Index, CFD);
return true; return true;
} }
break; break;
@ -293,7 +290,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
} }
} }
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_READCONTENT: CFD %x, Addr 0x%x, Size %i -> stream pos %i (Index %i)", CFD, Addr, Size, rContent.m_Position, rContent.m_pContent->m_Index); INFO_LOG(WII_IPC_ES, "IOCTL_ES_READCONTENT: CFD %x, Addr 0x%x, Size %i -> stream pos %i (Index %i)", CFD, Addr, Size, rContent.m_Position, rContent.m_pContent->m_Index);
Memory::Write_U32(Size, _CommandAddress + 0x4); Memory::Write_U32(Size, _CommandAddress + 0x4);
return true; return true;
@ -310,7 +307,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
CContentAccessMap::iterator itr = m_ContentAccessMap.find(CFD); CContentAccessMap::iterator itr = m_ContentAccessMap.find(CFD);
m_ContentAccessMap.erase(itr); m_ContentAccessMap.erase(itr);
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_CLOSECONTENT: CFD %x", CFD); INFO_LOG(WII_IPC_ES, "IOCTL_ES_CLOSECONTENT: CFD %x", CFD);
Memory::Write_U32(0, _CommandAddress + 0x4); Memory::Write_U32(0, _CommandAddress + 0x4);
return true; return true;
@ -344,7 +341,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
break; break;
} }
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_SEEKCONTENT: CFD %x, Addr 0x%x, Mode %i -> Pos %i", CFD, Addr, Mode, rContent.m_Position); INFO_LOG(WII_IPC_ES, "IOCTL_ES_SEEKCONTENT: CFD %x, Addr 0x%x, Mode %i -> Pos %i", CFD, Addr, Mode, rContent.m_Position);
Memory::Write_U32(rContent.m_Position, _CommandAddress + 0x4); Memory::Write_U32(rContent.m_Position, _CommandAddress + 0x4);
return true; return true;
@ -362,27 +359,27 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
char* Path = (char*)Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); char* Path = (char*)Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address);
sprintf(Path, "/%08x/%08x/data", (u32)(TitleID >> 32), (u32)TitleID); sprintf(Path, "/%08x/%08x/data", (u32)(TitleID >> 32), (u32)TitleID);
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEDIR: %s)", Path); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLEDIR: %s)", Path);
} }
break; break;
case IOCTL_ES_GETTITLEID: case IOCTL_ES_GETTITLEID:
{ {
_dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 0); _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 0);
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTITLEID no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETTITLEID no out buffer");
Memory::Write_U64(m_TitleID, Buffer.PayloadBuffer[0].m_Address); Memory::Write_U64(m_TitleID, Buffer.PayloadBuffer[0].m_Address);
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEID: %08x/%08x", (u32)(m_TitleID>>32), (u32)m_TitleID); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLEID: %08x/%08x", (u32)(m_TitleID>>32), (u32)m_TitleID);
} }
break; break;
case IOCTL_ES_SETUID: case IOCTL_ES_SETUID:
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTITLEID no in buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_SETUID no in buffer");
_dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0); _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0);
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 m_TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_SETUID titleID: %08x/%08x", (u32)(TitleID>>32), (u32)TitleID ); INFO_LOG(WII_IPC_ES, "IOCTL_ES_SETUID titleID: %08x/%08x", (u32)(m_TitleID>>32), (u32)m_TitleID );
} }
break; break;
@ -394,7 +391,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
Memory::Write_U32((u32)m_TitleIDs.size(), Buffer.PayloadBuffer[0].m_Address); Memory::Write_U32((u32)m_TitleIDs.size(), Buffer.PayloadBuffer[0].m_Address);
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECNT: Number of Titles %i", m_TitleIDs.size()); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECNT: Number of Titles %i", m_TitleIDs.size());
Memory::Write_U32(0, _CommandAddress + 0x4); Memory::Write_U32(0, _CommandAddress + 0x4);
@ -413,17 +410,13 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
for (int i = 0; i < (int)m_TitleIDs.size(); i++) for (int i = 0; i < (int)m_TitleIDs.size(); i++)
{ {
Memory::Write_U64(m_TitleIDs[i], Buffer.PayloadBuffer[0].m_Address + i*8); Memory::Write_U64(m_TitleIDs[i], Buffer.PayloadBuffer[0].m_Address + i*8);
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: %08x/%08x", (u32)(m_TitleIDs[i] >> 32), (u32)m_TitleIDs[i]); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: %08x/%08x", (u32)(m_TitleIDs[i] >> 32), (u32)m_TitleIDs[i]);
Count++; Count++;
if (Count >= MaxCount) if (Count >= MaxCount)
break; break;
} }
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: Number of titles returned %i", Count); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLES: Number of titles returned %i", Count);
// really strange: if i return the number of returned titleIDs the WiiMenu_00 doesn't work anymore
// and i get an error message ("The system files are corrupted. Please refer to the Wii Operation Manual...")
// if i return 0 it works...
Memory::Write_U32(0, _CommandAddress + 0x4); Memory::Write_U32(0, _CommandAddress + 0x4);
return true; return true;
} }
@ -432,8 +425,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
case IOCTL_ES_GETVIEWCNT: case IOCTL_ES_GETVIEWCNT:
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETVIEWCNT no in buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETVIEWCNT no in buffer");
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETVIEWCNT no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETVIEWCNT no out buffer");
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
@ -445,10 +438,10 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
const u32 SIZE_OF_ONE_TICKET = 676; const u32 SIZE_OF_ONE_TICKET = 676;
u32 FileSize = (u32)(File::GetSize(TicketFilename.c_str())); u32 FileSize = (u32)(File::GetSize(TicketFilename.c_str()));
_dbg_assert_msg_(WII_IPC_ES, (FileSize % SIZE_OF_ONE_TICKET) == 0, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETVIEWCNT ticket file size seems to be wrong"); _dbg_assert_msg_(WII_IPC_ES, (FileSize % SIZE_OF_ONE_TICKET) == 0, "IOCTL_ES_GETVIEWCNT ticket file size seems to be wrong");
ViewCount = FileSize / SIZE_OF_ONE_TICKET; ViewCount = FileSize / SIZE_OF_ONE_TICKET;
_dbg_assert_msg_(WII_IPC_ES, (ViewCount>0) && (ViewCount<=4), "CWII_IPC_HLE_Device_es: IOCTL_ES_GETVIEWCNT ticket count seems to be wrong"); _dbg_assert_msg_(WII_IPC_ES, (ViewCount>0) && (ViewCount<=4), "IOCTL_ES_GETVIEWCNT ticket count seems to be wrong");
} }
else else
{ {
@ -459,7 +452,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
ViewCount = 0; ViewCount = 0;
} }
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_GETVIEWCNT for titleID: %08x/%08x (View Count = %i)", (u32)(TitleID>>32), (u32)TitleID, ViewCount); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETVIEWCNT for titleID: %08x/%08x (View Count = %i)", (u32)(TitleID>>32), (u32)TitleID, ViewCount);
Memory::Write_U32(ViewCount, Buffer.PayloadBuffer[0].m_Address); Memory::Write_U32(ViewCount, Buffer.PayloadBuffer[0].m_Address);
Memory::Write_U32(0, _CommandAddress + 0x4); Memory::Write_U32(0, _CommandAddress + 0x4);
@ -507,8 +500,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
case IOCTL_ES_GETTMDVIEWCNT: case IOCTL_ES_GETTMDVIEWCNT:
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTMDVIEWCNT no in buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETTMDVIEWCNT no in buffer");
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTMDVIEWCNT no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETTMDVIEWCNT no out buffer");
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
std::string TitlePath = CreateTitleContentPath(TitleID); std::string TitlePath = CreateTitleContentPath(TitleID);
@ -534,8 +527,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
case IOCTL_ES_GETTMDVIEWS: case IOCTL_ES_GETTMDVIEWS:
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTMDVIEWCNT no in buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "IOCTL_ES_GETTMDVIEWCNT no in buffer");
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTMDVIEWCNT no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETTMDVIEWCNT no out buffer");
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
@ -575,10 +568,16 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
} }
break; break;
case IOCTL_ES_GETCONSUMPTION: // This is at least what crediar's ES module does
Memory::Write_U32(0, Buffer.PayloadBuffer[1].m_Address);
Memory::Write_U32(0, _CommandAddress + 0x4);
WARN_LOG(WII_IPC_ES, "IOCTL_ES_GETCONSUMPTION:%d", Memory::Read_U32(_CommandAddress+4));
return true;
case IOCTL_ES_GETSTOREDTMD: case IOCTL_ES_GETSTOREDTMD:
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMD no in buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "IOCTL_ES_GETSTOREDTMD no in buffer");
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMD no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETSTOREDTMD no out buffer");
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
@ -614,8 +613,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
case IOCTL_ES_GETSTOREDTMDSIZE: case IOCTL_ES_GETSTOREDTMDSIZE:
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMDSIZE no in buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETSTOREDTMDSIZE no in buffer");
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_ES_GETSTOREDTMDSIZE no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_ES_GETSTOREDTMDSIZE no out buffer");
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
std::string TitlePath = CreateTitleContentPath(TitleID); std::string TitlePath = CreateTitleContentPath(TitleID);
@ -670,21 +669,20 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
break; break;
// =============================================================================================== // ===============================================================================================
// unsupported functions // unsupported functions
// =============================================================================================== // ===============================================================================================
case IOCTL_ES_LAUNCH: case IOCTL_ES_LAUNCH:
{ {
_dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2); _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2);
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
u32 view = Memory::Read_U32(Buffer.InBuffer[1].m_Address); u32 view = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
u64 ticketid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+4); u64 ticketid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+4);
u32 devicetype =Memory::Read_U32(Buffer.InBuffer[1].m_Address+12); u32 devicetype = Memory::Read_U32(Buffer.InBuffer[1].m_Address+12);
u64 titleid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+16); u64 titleid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+16);
u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address+24); u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address+24);
PanicAlert("IOCTL_ES_LAUNCH: src titleID %08x/%08x -> start %08x/%08x \n" PanicAlert("IOCTL_ES_LAUNCH: src titleID %08x/%08x -> start %08x/%08x \n"
"This means that dolphin tries to relaunch the WiiMenu or" "This means that dolphin tries to relaunch the WiiMenu or"
@ -700,11 +698,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
} }
break; break;
case IOCTL_ES_GETCONSUMPTION: // (Input: 8 bytes, Output: 0 bytes, 4 bytes) case IOCTL_ES_DIGETTICKETVIEW: // (Input: none, Output: 216 bytes) bug crediar :D
WARN_LOG(WII_IPC_ES, "IOCTL_ES_GETCONSUMPTION: this looks really wrong...");
break;
case IOCTL_ES_DIGETTICKETVIEW: // (Input: none, Output: 216 bytes)
WARN_LOG(WII_IPC_ES, "IOCTL_ES_DIGETTICKETVIEW: this looks really wrong..."); WARN_LOG(WII_IPC_ES, "IOCTL_ES_DIGETTICKETVIEW: this looks really wrong...");
break; break;
@ -716,7 +710,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
WARN_LOG(WII_IPC_ES, "CWII_IPC_HLE_Device_es: 0x%x", Buffer.Parameter); WARN_LOG(WII_IPC_ES, "CWII_IPC_HLE_Device_es: 0x%x", Buffer.Parameter);
DumpCommands(_CommandAddress, 8, LogTypes::WII_IPC_ES); DumpCommands(_CommandAddress, 8, LogTypes::WII_IPC_ES);
INFO_LOG(WII_IPC_ES, "CWII_IPC_HLE_Device_es command.Parameter: 0x%08x", Buffer.Parameter); INFO_LOG(WII_IPC_ES, "command.Parameter: 0x%08x", Buffer.Parameter);
break; break;
} }

View File

@ -41,7 +41,7 @@ bool CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode)
{ {
// clear tmp folder // clear tmp folder
{ {
// std::string WiiTempFolder = File::GetUserDirectory() + FULL_WII_USER_DIR + std::string("tmp"); //std::string WiiTempFolder = File::GetUserDirectory() + FULL_WII_USER_DIR + std::string("tmp");
std::string WiiTempFolder = FULL_WII_USER_DIR + std::string("tmp"); std::string WiiTempFolder = FULL_WII_USER_DIR + std::string("tmp");
File::DeleteDirRecursively(WiiTempFolder.c_str()); File::DeleteDirRecursively(WiiTempFolder.c_str());
File::CreateDir(WiiTempFolder.c_str()); File::CreateDir(WiiTempFolder.c_str());
@ -70,6 +70,31 @@ bool CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode)
return true; return true;
} }
bool CWII_IPC_HLE_Device_fs::Close(u32 _CommandAddress)
{
// Do we even need to do anything?
INFO_LOG(WII_IPC_NET, "/dev/fs: Close");
Memory::Write_U32(0, _CommandAddress + 4);
return true;
}
// Get total filesize of contents of a directory (recursive)
// Only used for ES_GetUsage atm, could be useful elsewhere?
static u64 ComputeTotalFileSize(const File::FSTEntry& parentEntry)
{
u64 sizeOfFiles = 0;
const std::vector<File::FSTEntry>& children = parentEntry.children;
for (std::vector<File::FSTEntry>::const_iterator it = children.begin(); it != children.end(); ++it)
{
const File::FSTEntry& entry = *it;
if (entry.isDirectory)
sizeOfFiles += ComputeTotalFileSize(entry);
else
sizeOfFiles += entry.size;
}
return sizeOfFiles;
}
bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
{ {
u32 ReturnValue = FS_RESULT_OK; u32 ReturnValue = FS_RESULT_OK;
@ -173,55 +198,40 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
case IOCTLV_GETUSAGE: case IOCTLV_GETUSAGE:
{ {
// check buffer sizes
_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer.size() == 2); _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer.size() == 2);
_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[0].m_Size == 4); _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[0].m_Size == 4);
_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[1].m_Size == 4); _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[1].m_Size == 4);
// this command sucks because it asks of the number of used // this command sucks because it asks of the number of used
// fsBlocks and inodes // fsBlocks and inodes
// we answer nothing is used, but if a program uses it to check // It should be correct, but don't count on it...
// how much memory has been used we are doomed... std::string path(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size));
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size)); u32 fsBlocks = 0;
u32 fsBlock = 0;
u32 iNodes = 0; u32 iNodes = 0;
WARN_LOG(WII_IPC_FILEIO, "FS: IOCTL_GETUSAGE %s", Filename.c_str()); INFO_LOG(WII_IPC_FILEIO, "IOCTL_GETUSAGE %s", path.c_str());
if (File::IsDirectory(Filename.c_str())) if (File::IsDirectory(path.c_str()))
{ {
// make a file search File::FSTEntry parentDir;
CFileSearch::XStringVector Directories; iNodes = File::ScanDirectoryTree(path.c_str(), parentDir);
Directories.push_back(Filename);
CFileSearch::XStringVector Extensions; u64 totalSize = ComputeTotalFileSize(parentDir); // "Real" size, to be converted to nand blocks
Extensions.push_back("*.*");
CFileSearch FileSearch(Extensions, Directories); fsBlocks = (u32)(totalSize / (16 * 1024)); // one bock is 16kb
u64 overAllSize = 0;
for (size_t i=0; i<FileSearch.GetFileNames().size(); i++)
{
overAllSize += File::GetSize(FileSearch.GetFileNames()[i].c_str());
}
fsBlock = (u32)(overAllSize / (16 * 1024)); // one bock is 16kb
iNodes = (u32)(FileSearch.GetFileNames().size());
ReturnValue = FS_RESULT_OK; ReturnValue = FS_RESULT_OK;
WARN_LOG(WII_IPC_FILEIO, " fsBlock: %i, iNodes: %i", fsBlock, iNodes); INFO_LOG(WII_IPC_FILEIO, "\tfsBlock: %i, iNodes: %i", fsBlocks, iNodes);
} }
else else
{ {
fsBlock = 0; fsBlocks = 0;
iNodes = 0; iNodes = 0;
ReturnValue = FS_RESULT_OK; ReturnValue = FS_RESULT_OK;
WARN_LOG(WII_IPC_FILEIO, "\tError: not executed on a valid directoy: %s", path.c_str());
// PanicAlert("IOCTL_GETUSAGE - unk dir %s", Filename.c_str());
WARN_LOG(WII_IPC_FILEIO, " error: not executed on a valid directoy: %s", Filename.c_str());
} }
Memory::Write_U32(fsBlock, CommandBuffer.PayloadBuffer[0].m_Address); Memory::Write_U32(fsBlocks, CommandBuffer.PayloadBuffer[0].m_Address);
Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address); Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address);
} }
break; break;

View File

@ -36,9 +36,9 @@ public:
virtual ~CWII_IPC_HLE_Device_fs(); virtual ~CWII_IPC_HLE_Device_fs();
virtual bool Open(u32 _CommandAddress, u32 _Mode); virtual bool Open(u32 _CommandAddress, u32 _Mode);
virtual bool Close(u32 _CommandAddress);
virtual bool IOCtl(u32 _CommandAddress); virtual bool IOCtl(u32 _CommandAddress);
virtual bool IOCtlV(u32 _CommandAddress); virtual bool IOCtlV(u32 _CommandAddress);
private: private: