fixed IOCTL_READ_DIR command, removed some commands which are at best "misleading"

i dunno which games are using IOCTL_READ_DIR at all but i hope i havn't broken anything

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1358 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
fires.gc
2008-12-01 06:52:02 +00:00
parent df6cc66d87
commit 327662bce3
4 changed files with 170 additions and 201 deletions

View File

@ -84,12 +84,11 @@ TDeviceMap g_DeviceMap;
// STATE_TO_SAVE // STATE_TO_SAVE
u32 g_LastDeviceID = 0x13370000; u32 g_LastDeviceID = 0x13370000;
std::list<u32> g_Ack;
std::queue<std::pair<u32,std::string> > g_ReplyQueue;
void ExecuteCommand(u32 _Address);
// General IPC functions
// ===================================================
/* General IPC functions */
// ----------------
void Init() void Init()
{ {
_dbg_assert_msg_(WII_IPC, g_DeviceMap.empty(), "DeviceMap isnt empty on init"); _dbg_assert_msg_(WII_IPC, g_DeviceMap.empty(), "DeviceMap isnt empty on init");
@ -139,16 +138,12 @@ void DeleteDeviceByID(u32 ID)
g_DeviceMap.erase(ID); g_DeviceMap.erase(ID);
} }
} }
// ================
// This is called from COMMAND_OPEN_DEVICE. Here we either create a new device
// =================================================== // or open a new file handle.
/* This is called from COMMAND_OPEN_DEVICE. Here we either create a new device
or open a new file handle. */
// ----------------
IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName) IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName)
{ {
// scan device name and create the right one ^^ // scan device name and create the right one
IWII_IPC_HLE_Device* pDevice = NULL; IWII_IPC_HLE_Device* pDevice = NULL;
if (_rDeviceName.find("/dev/") != std::string::npos) if (_rDeviceName.find("/dev/") != std::string::npos)
{ {
@ -207,26 +202,14 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName
return pDevice; return pDevice;
} }
std::list<u32> m_Ack; // This generates some kind of acknowledgment
std::queue<std::pair<u32,std::string> > m_ReplyQueue;
void ExecuteCommand(u32 _Address);
// ===================================================
/* This generates an acknowledgment to IPC calls. This function is called from
IPC_CONTROL_REGISTER requests in WII_IPC.cpp. The acknowledgment _Address will
start with 0x033e...., it will be for the _CommandAddress 0x133e...., from
debugging I also noticed that the Ioctl arguments are stored temporarily in
0x933e.... with the same .... as in the _CommandAddress. */
// ----------------
bool AckCommand(u32 _Address) bool AckCommand(u32 _Address)
{ {
// Debugger::PrintCallstack(LogTypes::WII_IPC_HLE); // Debugger::PrintCallstack(LogTypes::WII_IPC_HLE);
LOG(WII_IPC_HLE, "AckCommand: 0%08x", _Address); LOG(WII_IPC_HLE, "AckCommand: 0%08x", _Address);
std::list<u32>::iterator itr = m_Ack.begin(); std::list<u32>::iterator itr = g_Ack.begin();
while (itr != m_Ack.end()) while (itr != g_Ack.end())
{ {
if (*itr == _Address) if (*itr == _Address)
{ {
@ -237,7 +220,7 @@ bool AckCommand(u32 _Address)
itr++; itr++;
} }
m_Ack.push_back(_Address); g_Ack.push_back(_Address);
return true; return true;
} }
@ -268,26 +251,8 @@ void CopySettingsFile(std::string DeviceName)
} }
} }
void ExecuteCommand(u32 _Address) void ExecuteCommand(u32 _Address)
{ {
/* // small dump
switch (Memory::Read_U32(_Address))
{
case COMMAND_OPEN_DEVICE: LOG(WII_IPC_HLE, "COMMAND_OPEN_DEVICE"); break;
case COMMAND_CLOSE_DEVICE: LOG(WII_IPC_HLE, "COMMAND_CLOSE_DEVICE"); break;
case COMMAND_READ: LOG(WII_IPC_HLE, "COMMAND_READ"); break;
case COMMAND_WRITE: LOG(WII_IPC_HLE, "COMMAND_WRITE"); break;
case COMMAND_SEEK: LOG(WII_IPC_HLE, "COMMAND_SEEK"); break;
case COMMAND_IOCTL: LOG(WII_IPC_HLE, "COMMAND_IOCTL"); break;
case COMMAND_IOCTLV: LOG(WII_IPC_HLE, "COMMAND_IOCTLV"); break;
}
for (size_t i=0; i<0x30/4; i++)
{
LOG(WII_IPC_HLE, "Command%02i: 0x%08x", i, Memory::Read_U32(_Address + i*4));
}*/
bool GenerateReply = false; bool GenerateReply = false;
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address)); ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
@ -295,9 +260,8 @@ void ExecuteCommand(u32 _Address)
{ {
case COMMAND_OPEN_DEVICE: case COMMAND_OPEN_DEVICE:
{ {
LOG(WII_IPC_FILEIO, "==================================================================="); // Create a new HLE device. The Mode and DeviceName is given to us but we
/* Create a new HLE device. The Mode and DeviceName is given to us but we // generate a DeviceID to be used for access to this device until it is Closed.
generate a DeviceID to be used for access to this device until it is Closed. */
std::string DeviceName; std::string DeviceName;
Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC)); Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC));
@ -307,7 +271,7 @@ void ExecuteCommand(u32 _Address)
u32 Mode = Memory::Read_U32(_Address + 0x10); u32 Mode = Memory::Read_U32(_Address + 0x10);
u32 DeviceID = GetDeviceIDByName(DeviceName); u32 DeviceID = GetDeviceIDByName(DeviceName);
/* The device has already been opened and was not closed, reuse the same DeviceID. */ // check if a device with this name has been created already
if (DeviceID == 0) if (DeviceID == 0)
{ {
// create the new device // create the new device
@ -333,12 +297,16 @@ void ExecuteCommand(u32 _Address)
} }
else else
{ {
// The device has already been opened and was not closed, reuse the same DeviceID.
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID); IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
/* If we return -6 here after a Open > Failed > CREATE_FILE > ReOpen call // If we return -6 here after a Open > Failed > CREATE_FILE > ReOpen call
sequence Mario Galaxy and Mario Kart Wii will not start writing to the file, // sequence Mario Galaxy and Mario Kart Wii will not start writing to the file,
it will just (seemingly) wait for one or two seconds and then give an error // it will just (seemingly) wait for one or two seconds and then give an error
message. So I'm trying to return the DeviceID instead to make it write to the file. // message. So I'm trying to return the DeviceID instead to make it write to the file.
(Which was most likely the reason it created the file in the first place.) */ // (Which was most likely the reason it created the file in the first place.) */
// F|RES: prolly the re-open is just a mode change
if(DeviceName.find("/dev/") == std::string::npos) if(DeviceName.find("/dev/") == std::string::npos)
{ {
@ -347,10 +315,10 @@ void ExecuteCommand(u32 _Address)
u32 Mode = Memory::Read_U32(_Address + 0x10); u32 Mode = Memory::Read_U32(_Address + 0x10);
/* We may not have a file handle at this point, in Mario Kart I got a // We may not have a file handle at this point, in Mario Kart I got a
Open > Failed > ... other stuff > ReOpen call sequence, in that case // Open > Failed > ... other stuff > ReOpen call sequence, in that case
we have no file and no file handle, so we call Open again to basically // we have no file and no file handle, so we call Open again to basically
get a -106 error so that the game call CreateFile and then ReOpen again. */ // get a -106 error so that the game call CreateFile and then ReOpen again.
if(pDevice->ReturnFileHandle()) if(pDevice->ReturnFileHandle())
Memory::Write_U32(DeviceID, _Address + 4); Memory::Write_U32(DeviceID, _Address + 4);
else else
@ -360,6 +328,7 @@ void ExecuteCommand(u32 _Address)
{ {
LOG(WII_IPC_HLE, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)", LOG(WII_IPC_HLE, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), pDevice->GetDeviceID(), Mode); pDevice->GetDeviceName().c_str(), pDevice->GetDeviceID(), Mode);
// We have already opened this device, return -6 // We have already opened this device, return -6
Memory::Write_U32(u32(-6), _Address + 4); Memory::Write_U32(u32(-6), _Address + 4);
} }
@ -377,19 +346,9 @@ void ExecuteCommand(u32 _Address)
{ {
pDevice->Close(_Address); pDevice->Close(_Address);
/* Write log // Delete the device when CLOSE is called, this does not effect
if(pDevice->GetDeviceName().find("/dev/") == std::string::npos // GenerateReply() for any other purpose than the logging because
|| pDevice->GetDeviceName().c_str() == std::string("/dev/fs")) { // it's a true / false only function //
LOG(WII_IPC_FILEIO, "IOP: Close (Device=%s ID=0x%08x)",
pDevice->GetDeviceName().c_str(), DeviceID);
LOG(WII_IPC_FILEIO, "===================================================================");
} else {
LOG(WII_IPC_HLE, "IOP: Close (Device=%s ID=0x%08x)",
pDevice->GetDeviceName().c_str(), DeviceID); }*/
/* Delete the device when CLOSE is called, this does not effect
GenerateReply() for any other purpose than the logging because
it's a true / false only function */
DeleteDeviceByID(DeviceID); DeleteDeviceByID(DeviceID);
GenerateReply = true; GenerateReply = true;
} }
@ -447,8 +406,8 @@ void ExecuteCommand(u32 _Address)
break; break;
} }
/* It seems that the original hardware overwrites the command after it has been // It seems that the original hardware overwrites the command after it has been
executed. We write 8 which is not any valid command. */ // executed. We write 8 which is not any valid command.
Memory::Write_U32(8, _Address); Memory::Write_U32(8, _Address);
// Generate a reply to the IPC command // Generate a reply to the IPC command
@ -464,35 +423,17 @@ void ExecuteCommand(u32 _Address)
if (pDevice != NULL) if (pDevice != NULL)
{ {
/* Write log
u32 Mode = Memory::Read_U32(_Address + 0x10);
if(pDevice->GetDeviceName().find("/dev/") == std::string::npos
|| pDevice->GetDeviceName().c_str() == std::string("/dev/fs"))
{
LOGV(WII_IPC_FILEIO, 1, "IOP: GenerateReply (Device=%s, DeviceID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), pDevice->GetDeviceID(), Mode);
}
else
{
LOG(WII_IPC_HLE, "IOP: GenerateReply (Device=%s, DeviceID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), pDevice->GetDeviceID(), Mode);
} */
// Write reply, this will later be executed in Update() // Write reply, this will later be executed in Update()
m_ReplyQueue.push(std::pair<u32, std::string>(_Address, pDevice->GetDeviceName())); g_ReplyQueue.push(std::pair<u32, std::string>(_Address, pDevice->GetDeviceName()));
} }
else else
{ {
m_ReplyQueue.push(std::pair<u32, std::string>(_Address, "unknown")); g_ReplyQueue.push(std::pair<u32, std::string>(_Address, "unknown"));
} }
} }
} }
// This is called continuously and WII_IPCInterface::IsReady() is controlled from WII_IPC.cpp.
// ===================================================
/* This is called continouosly and WII_IPCInterface::IsReady() is controlled from
WII_IPC.cpp. */
// ----------------
void Update() void Update()
{ {
if (WII_IPCInterface::IsReady()) if (WII_IPCInterface::IsReady())
@ -504,39 +445,24 @@ void Update()
u32 CommandAddr = itr->second->Update(); u32 CommandAddr = itr->second->Update();
if (CommandAddr != 0) if (CommandAddr != 0)
{ {
m_ReplyQueue.push(std::pair<u32, std::string>(CommandAddr, itr->second->GetDeviceName())); g_ReplyQueue.push(std::pair<u32, std::string>(CommandAddr, itr->second->GetDeviceName()));
} }
++itr; ++itr;
} }
// Check if we have to execute an acknowledge command... // Check if we have to execute an acknowledge command...
if (!m_ReplyQueue.empty()) if (!g_ReplyQueue.empty())
{ {
/* Write one log for files and one for devices WII_IPCInterface::GenerateReply(g_ReplyQueue.front().first);
if(m_ReplyQueue.front().second.find("unknown") == std::string::npos g_ReplyQueue.pop();
&& (m_ReplyQueue.front().second.find("/dev/") == std::string::npos
|| m_ReplyQueue.front().second.c_str() == std::string("/dev/fs")))
{
LOGV(WII_IPC_FILEIO, 1, "-- Update() Reply %s (0x%08x)",
m_ReplyQueue.front().second.c_str(), m_ReplyQueue.front().first);
}
else
{
LOGV(WII_IPC_HLE, 1, "-- Update() Reply %s (0x%08x)",
m_ReplyQueue.front().second.c_str(), m_ReplyQueue.front().first);
} */
WII_IPCInterface::GenerateReply(m_ReplyQueue.front().first);
m_ReplyQueue.pop();
return; return;
} }
// ...no we don't, we can now execute the IPC command // ...no we don't, we can now execute the IPC command
if (m_ReplyQueue.empty() && !m_Ack.empty()) if (g_ReplyQueue.empty() && !g_Ack.empty())
{ {
u32 _Address = m_Ack.front(); u32 _Address = g_Ack.front();
m_Ack.pop_front(); g_Ack.pop_front();
ExecuteCommand(_Address); ExecuteCommand(_Address);
LOGV(WII_IPC_HLE, 1, "-- Generate Ack (0x%08x)", _Address); LOGV(WII_IPC_HLE, 1, "-- Generate Ack (0x%08x)", _Address);

View File

@ -38,11 +38,6 @@ std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
return Filename; return Filename;
} }
/// ----------------------------------------------------------------
// The FileIO class
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName ) CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName )
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
, m_pFileHandle(NULL) , m_pFileHandle(NULL)
@ -74,9 +69,12 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
bool bool
CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode) CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
{ {
//LOG(WII_IPC_FILEIO, "==================================================================="); // close the file handle if we get a reopen
if (m_pFileHandle != NULL)
u32 ReturnValue = 0; {
fclose(m_pFileHandle);
m_pFileHandle = NULL;
}
const char Modes[][128] = const char Modes[][128] =
{ {
@ -86,44 +84,35 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
{ "Read and Write" } { "Read and Write" }
}; };
m_Filename = std::string(HLE_IPC_BuildFilename(GetDeviceName().c_str(), 64));
LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s)", GetDeviceName().c_str(), Modes[_Mode]); LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s)", GetDeviceName().c_str(), Modes[_Mode]);
m_Filename = std::string(HLE_IPC_BuildFilename(GetDeviceName().c_str(), 64));
if (File::Exists(m_Filename.c_str())) { if (File::Exists(m_Filename.c_str()))
{
switch(_Mode) switch(_Mode)
{ {
// Do "r+b" for all writing to avoid truncating the file // Do "r+b" for all writing to avoid truncating the file
case 0x01: case 0x01: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break;
m_pFileHandle = fopen(m_Filename.c_str(), "rb"); case 0x02: //m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break;
break; case 0x03: m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break;
case 0x02: default: PanicAlert("CWII_IPC_HLE_Device_FileIO: unknown open mode"); break;
//m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break; }
case 0x03:
m_pFileHandle = fopen(m_Filename.c_str(), "r+b");
break;
default:
PanicAlert("CWII_IPC_HLE_Device_FileIO: unknown open mode");
break;
} }
u32 ReturnValue = 0;
if (m_pFileHandle != NULL) { if (m_pFileHandle != NULL)
{
m_FileLength = File::GetSize(m_Filename.c_str()); m_FileLength = File::GetSize(m_Filename.c_str());
ReturnValue = GetDeviceID(); ReturnValue = GetDeviceID();
} }
else { else
LOG(WII_IPC_FILEIO, "Error opening file %s", m_Filename.c_str()); {
ReturnValue = -106; LOG(WII_IPC_FILEIO, " failed - File doesn't exist");
}
} else {
LOG(WII_IPC_FILEIO, "File %s doesn't exist", m_Filename.c_str() );
ReturnValue = -106; ReturnValue = -106;
} }
Memory::Write_U32(ReturnValue, _CommandAddress+4); Memory::Write_U32(ReturnValue, _CommandAddress+4);
//LOG(WII_IPC_FILEIO, "===================================================================");
return true; return true;
} }

View File

@ -28,6 +28,7 @@
extern std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size); extern std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size);
#define FS_RESULT_OK (0) #define FS_RESULT_OK (0)
#define FS_INVALID_ARGUMENT (-101)
#define FS_FILE_EXIST (-105) #define FS_FILE_EXIST (-105)
#define FS_FILE_NOT_EXIST (-106) #define FS_FILE_NOT_EXIST (-106)
#define FS_RESULT_FATAL (-128) #define FS_RESULT_FATAL (-128)
@ -88,7 +89,7 @@ bool CWII_IPC_HLE_Device_fs::IOCtl(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
{ {
u32 ReturnValue = 0; u32 ReturnValue = FS_RESULT_OK;
SIOCtlVBuffer CommandBuffer(_CommandAddress); SIOCtlVBuffer CommandBuffer(_CommandAddress);
@ -104,11 +105,15 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
/* Check if this is really a directory. Or a file, because it seems like Mario Kart /* Check if this is really a directory. Or a file, because it seems like Mario Kart
did a IOCTL_READ_DIR on the save file to check if it existed before deleting it, did a IOCTL_READ_DIR on the save file to check if it existed before deleting it,
and if I returned a -something it never deleted the file presumably because it and if I returned a -something it never deleted the file presumably because it
thought it didn't exist. So this solution worked for Mario Kart. */ thought it didn't exist. So this solution worked for Mario Kart.
if (!File::Exists(Filename.c_str()) && !File::IsDirectory(Filename.c_str()))
F|RES: i dont have mkart but -6 is a wrong return value if you try to read from a directory which doesnt exist
*/
if (!File::IsDirectory(Filename.c_str()))
{ {
LOG(WII_IPC_FILEIO, " No file and not a directory - return -6 (dunno if this is a correct return value)", Filename.c_str()); LOG(WII_IPC_FILEIO, " No file and not a directory - return FS_INVALID_ARGUMENT", Filename.c_str());
ReturnValue = -6; ReturnValue = FS_INVALID_ARGUMENT;
break; break;
} }
@ -131,26 +136,34 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
} }
else else
{ {
u32 MaxEntries = Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address);
memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, CommandBuffer.PayloadBuffer[0].m_Size); memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, CommandBuffer.PayloadBuffer[0].m_Size);
size_t numFile = FileSearch.GetFileNames().size(); size_t numFiles = 0;
for (size_t i=0; i<numFile; i++) char* pFilename = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address));
for (size_t i=0; i<FileSearch.GetFileNames().size(); i++)
{ {
char* pDest = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address + i * MAX_NAME)); if (i >= MaxEntries)
break;
std::string filename, ext; std::string filename, ext;
SplitPath(FileSearch.GetFileNames()[i], NULL, &filename, &ext); SplitPath(FileSearch.GetFileNames()[i], NULL, &filename, &ext);
std::string CompleteFilename = filename + ext;
strcpy(pFilename, CompleteFilename.c_str());
pFilename += CompleteFilename.length();
*pFilename++ = 0x00; // termination
numFiles++;
memcpy(pDest, (filename + ext).c_str(), MAX_NAME); LOG(WII_IPC_FILEIO, " %s", CompleteFilename.c_str());
pDest[MAX_NAME-1] = 0x00;
LOG(WII_IPC_FILEIO, " %s", pDest);
} }
Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[1].m_Address); Memory::Write_U32((u32)numFiles, CommandBuffer.PayloadBuffer[1].m_Address);
} }
ReturnValue = 0; ReturnValue = FS_RESULT_OK;
} }
break; break;
@ -190,7 +203,7 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
fsBlock = (u32)(overAllSize / (16 * 1024)); // one bock is 16kb fsBlock = (u32)(overAllSize / (16 * 1024)); // one bock is 16kb
iNodes = (u32)(FileSearch.GetFileNames().size()); iNodes = (u32)(FileSearch.GetFileNames().size());
ReturnValue = 0; ReturnValue = FS_RESULT_OK;
LOGV(WII_IPC_FILEIO, 1, " fsBlock: %i, iNodes: %i", fsBlock, iNodes); LOGV(WII_IPC_FILEIO, 1, " fsBlock: %i, iNodes: %i", fsBlock, iNodes);
} }
@ -198,7 +211,9 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
{ {
fsBlock = 0; fsBlock = 0;
iNodes = 0; iNodes = 0;
ReturnValue = 0; ReturnValue = FS_RESULT_OK;
// PanicAlert("IOCTL_GETUSAGE - unk dir %s", Filename.c_str());
LOGV(WII_IPC_FILEIO, 1, " error: not executed on a valid directoy: %s", Filename.c_str()); LOGV(WII_IPC_FILEIO, 1, " error: not executed on a valid directoy: %s", Filename.c_str());
} }
@ -218,14 +233,33 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
return true; return true;
} }
s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize) s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize)
{ {
switch(_Parameter) switch(_Parameter)
{ {
case GET_STATS: case GET_STATS:
PanicAlert("FS: GET_STATS not supported"); {
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 28);
LOG(WII_IPC_FILEIO, "FS: GET STATS - no idea what we have to return here, prolly the free memory etc:)");
LOG(WII_IPC_FILEIO, " InBufferSize: %i OutBufferSize: %i", _BufferInSize, _BufferOutSize);
u32 Addr = _BufferOut;
/* Memory::Write_U32(Addr, a); Addr += 4;
Memory::Write_U32(Addr, b); Addr += 4;
Memory::Write_U32(Addr, c); Addr += 4;
Memory::Write_U32(Addr, d); Addr += 4;
Memory::Write_U32(Addr, e); Addr += 4;
Memory::Write_U32(Addr, f); Addr += 4;
Memory::Write_U32(Addr, g); Addr += 4;
*/
PanicAlert("GET_STATS");
return FS_RESULT_OK;
}
break; break;
case CREATE_DIR: case CREATE_DIR:
{ {
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
@ -233,8 +267,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4;
u16 GroupID = Memory::Read_U16(Addr); Addr += 2; u16 GroupID = Memory::Read_U16(Addr); Addr += 2;
std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64)); std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64)); Addr += 64;
Addr += 64;
Addr += 9; // owner attribs, permission Addr += 9; // owner attribs, permission
u8 Attribs = Memory::Read_U8(Addr); u8 Attribs = Memory::Read_U8(Addr);
@ -248,6 +281,30 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
} }
break; break;
case SET_ATTR:
{
u32 Addr = _BufferIn;
u32 OwnerID = Memory::Read_U32(Addr); Addr += 4;
u16 GroupID = Memory::Read_U16(Addr); Addr += 2;
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn), 64); Addr += 64;
u8 OwnerPerm = Memory::Read_U8(Addr); Addr += 1;
u8 GroupPerm = Memory::Read_U8(Addr); Addr += 1;
u8 OtherPerm = Memory::Read_U8(Addr); Addr += 1;
u8 Attributes = Memory::Read_U8(Addr); Addr += 1;
LOGV(WII_IPC_FILEIO, 0, "FS: SetAttrib %s", Filename.c_str());
LOG(WII_IPC_FILEIO, " OwnerID: 0x%08x", OwnerID);
LOG(WII_IPC_FILEIO, " GroupID: 0x%04x", GroupID);
LOG(WII_IPC_FILEIO, " OwnerPerm: 0x%02x", OwnerPerm);
LOG(WII_IPC_FILEIO, " GroupPerm: 0x%02x", GroupPerm);
LOG(WII_IPC_FILEIO, " OtherPerm: 0x%02x", OtherPerm);
LOG(WII_IPC_FILEIO, " Attributes: 0x%02x", Attributes);
return FS_RESULT_OK;
}
break;
case GET_ATTR: case GET_ATTR:
{ {
_dbg_assert_msg_(WII_IPC_FILEIO, _BufferOutSize == 76, " GET_ATTR needs an 76 bytes large output buffer but it is %i bytes large", _BufferOutSize); _dbg_assert_msg_(WII_IPC_FILEIO, _BufferOutSize == 76, " GET_ATTR needs an 76 bytes large output buffer but it is %i bytes large", _BufferOutSize);
@ -258,20 +315,19 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
u32 OwnerID = 0; u32 OwnerID = 0;
u16 GroupID = 0; u16 GroupID = 0;
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn), 64); std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn), 64);
u8 OwnerPerm = 0; u8 OwnerPerm = 0x3; // read/write
u8 GroupPerm = 0; u8 GroupPerm = 0x3; // read/write
u8 OtherPerm = 0; u8 OtherPerm = 0x3; // read/write
u8 Attributes = 0; u8 Attributes = 0x00; // no attributes
if (File::IsDirectory(Filename.c_str())) if (File::IsDirectory(Filename.c_str()))
{ {
LOG(WII_IPC_FILEIO, "FS: GET_ATTR Directory %s - ni", Filename.c_str()); LOG(WII_IPC_FILEIO, "FS: GET_ATTR Directory %s - all permission flags are set", Filename.c_str());
} }
else else
{ {
if (File::Exists(Filename.c_str())) if (File::Exists(Filename.c_str()))
{ {
LOG(WII_IPC_FILEIO, "FS: GET_ATTR %s - ni", Filename.c_str()); LOG(WII_IPC_FILEIO, "FS: GET_ATTR %s - all permission flags are set", Filename.c_str());
} }
else else
{ {
@ -355,15 +411,12 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
case CREATE_FILE: case CREATE_FILE:
{ {
//LOGV(WII_IPC_FILEIO, 0, "==============================================================");
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
u32 Addr = _BufferIn; u32 Addr = _BufferIn;
u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4;
u16 GroupID = Memory::Read_U16(Addr); Addr += 2; u16 GroupID = Memory::Read_U16(Addr); Addr += 2;
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64)); std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64)); Addr += 64;
Addr += 64;
u8 OwnerPerm = Memory::Read_U8(Addr); Addr++; u8 OwnerPerm = Memory::Read_U8(Addr); Addr++;
u8 GroupPerm = Memory::Read_U8(Addr); Addr++; u8 GroupPerm = Memory::Read_U8(Addr); Addr++;
u8 OtherPerm = Memory::Read_U8(Addr); Addr++; u8 OtherPerm = Memory::Read_U8(Addr); Addr++;
@ -377,7 +430,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
LOG(WII_IPC_FILEIO, " OtherPerm: 0x%02x", OtherPerm); LOG(WII_IPC_FILEIO, " OtherPerm: 0x%02x", OtherPerm);
LOG(WII_IPC_FILEIO, " Attributes: 0x%02x", Attributes); LOG(WII_IPC_FILEIO, " Attributes: 0x%02x", Attributes);
// check if the file allready exist // check if the file already exist
if (File::Exists(Filename.c_str())) if (File::Exists(Filename.c_str()))
{ {
LOG(WII_IPC_FILEIO, " result = FS_RESULT_EXISTS", Filename.c_str()); LOG(WII_IPC_FILEIO, " result = FS_RESULT_EXISTS", Filename.c_str());
@ -385,7 +438,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
} }
// create the file // create the file
// F|RES: i think that we dont need this - File::CreateDirectoryStructure(Filename); File::CreateDirectoryStructure(Filename); // just to be sure
bool Result = File::CreateEmptyFile(Filename.c_str()); bool Result = File::CreateEmptyFile(Filename.c_str());
if (!Result) if (!Result)
{ {
@ -402,6 +455,6 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
PanicAlert("CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter); PanicAlert("CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter);
break; break;
} }
//LOGV(WII_IPC_FILEIO, 0, "==============================================================");
return FS_RESULT_FATAL; return FS_RESULT_FATAL;
} }

View File

@ -46,6 +46,7 @@ private:
GET_STATS = 0x02, GET_STATS = 0x02,
CREATE_DIR = 0x03, CREATE_DIR = 0x03,
IOCTL_READ_DIR = 0x04, IOCTL_READ_DIR = 0x04,
SET_ATTR = 0x05,
GET_ATTR = 0x06, GET_ATTR = 0x06,
DELETE_FILE = 0x07, DELETE_FILE = 0x07,
RENAME_FILE = 0x08, RENAME_FILE = 0x08,