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
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()
{
_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);
}
}
// ================
// ===================================================
/* 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)
{
// scan device name and create the right one ^^
// scan device name and create the right one
IWII_IPC_HLE_Device* pDevice = NULL;
if (_rDeviceName.find("/dev/") != std::string::npos)
{
@ -207,26 +202,14 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName
return pDevice;
}
std::list<u32> m_Ack;
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. */
// ----------------
// This generates some kind of acknowledgment
bool AckCommand(u32 _Address)
{
//Debugger::PrintCallstack(LogTypes::WII_IPC_HLE);
// Debugger::PrintCallstack(LogTypes::WII_IPC_HLE);
LOG(WII_IPC_HLE, "AckCommand: 0%08x", _Address);
std::list<u32>::iterator itr = m_Ack.begin();
while (itr != m_Ack.end())
std::list<u32>::iterator itr = g_Ack.begin();
while (itr != g_Ack.end())
{
if (*itr == _Address)
{
@ -237,7 +220,7 @@ bool AckCommand(u32 _Address)
itr++;
}
m_Ack.push_back(_Address);
g_Ack.push_back(_Address);
return true;
}
@ -268,26 +251,8 @@ void CopySettingsFile(std::string DeviceName)
}
}
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;
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
@ -295,9 +260,8 @@ void ExecuteCommand(u32 _Address)
{
case COMMAND_OPEN_DEVICE:
{
LOG(WII_IPC_FILEIO, "===================================================================");
/* 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. */
// 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.
std::string DeviceName;
Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC));
@ -306,8 +270,8 @@ void ExecuteCommand(u32 _Address)
u32 Mode = Memory::Read_U32(_Address + 0x10);
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)
{
// create the new device
@ -333,12 +297,16 @@ void ExecuteCommand(u32 _Address)
}
else
{
// The device has already been opened and was not closed, reuse the same DeviceID.
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
/* 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,
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.
(Which was most likely the reason it created the file in the first place.) */
// 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,
// 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.
// (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)
{
@ -347,10 +315,10 @@ void ExecuteCommand(u32 _Address)
u32 Mode = Memory::Read_U32(_Address + 0x10);
/* 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
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. */
// 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
// 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.
if(pDevice->ReturnFileHandle())
Memory::Write_U32(DeviceID, _Address + 4);
else
@ -360,6 +328,7 @@ void ExecuteCommand(u32 _Address)
{
LOG(WII_IPC_HLE, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), pDevice->GetDeviceID(), Mode);
// We have already opened this device, return -6
Memory::Write_U32(u32(-6), _Address + 4);
}
@ -377,19 +346,9 @@ void ExecuteCommand(u32 _Address)
{
pDevice->Close(_Address);
/* Write log
if(pDevice->GetDeviceName().find("/dev/") == std::string::npos
|| pDevice->GetDeviceName().c_str() == std::string("/dev/fs")) {
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 */
// 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);
GenerateReply = true;
}
@ -447,8 +406,8 @@ void ExecuteCommand(u32 _Address)
break;
}
/* It seems that the original hardware overwrites the command after it has been
executed. We write 8 which is not any valid command. */
// It seems that the original hardware overwrites the command after it has been
// executed. We write 8 which is not any valid command.
Memory::Write_U32(8, _Address);
// Generate a reply to the IPC command
@ -464,35 +423,17 @@ void ExecuteCommand(u32 _Address)
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()
m_ReplyQueue.push(std::pair<u32, std::string>(_Address, pDevice->GetDeviceName()));
g_ReplyQueue.push(std::pair<u32, std::string>(_Address, pDevice->GetDeviceName()));
}
else
{
m_ReplyQueue.push(std::pair<u32, std::string>(_Address, "unknown"));
g_ReplyQueue.push(std::pair<u32, std::string>(_Address, "unknown"));
}
}
}
// ===================================================
/* This is called continouosly and WII_IPCInterface::IsReady() is controlled from
WII_IPC.cpp. */
// ----------------
// This is called continuously and WII_IPCInterface::IsReady() is controlled from WII_IPC.cpp.
void Update()
{
if (WII_IPCInterface::IsReady())
@ -504,39 +445,24 @@ void Update()
u32 CommandAddr = itr->second->Update();
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;
}
// 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
if(m_ReplyQueue.front().second.find("unknown") == std::string::npos
&& (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();
WII_IPCInterface::GenerateReply(g_ReplyQueue.front().first);
g_ReplyQueue.pop();
return;
}
// ...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();
m_Ack.pop_front();
u32 _Address = g_Ack.front();
g_Ack.pop_front();
ExecuteCommand(_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;
}
/// ----------------------------------------------------------------
// The FileIO class
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName )
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
, m_pFileHandle(NULL)
@ -74,56 +69,50 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
bool
CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
{
//LOG(WII_IPC_FILEIO, "===================================================================");
u32 ReturnValue = 0;
const char Modes[][128] =
// close the file handle if we get a reopen
if (m_pFileHandle != NULL)
{
{ "Unk Mode" },
{ "Read only" },
{ "Write only" },
{ "Read and Write" }
fclose(m_pFileHandle);
m_pFileHandle = NULL;
}
const char Modes[][128] =
{
{ "Unk Mode" },
{ "Read only" },
{ "Write only" },
{ "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]);
if (File::Exists(m_Filename.c_str())) {
switch(_Mode)
{
// Do "r+b" for all writing to avoid truncating the file
case 0x01:
m_pFileHandle = fopen(m_Filename.c_str(), "rb");
break;
case 0x02:
//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;
}
if (m_pFileHandle != NULL) {
m_FileLength = File::GetSize(m_Filename.c_str());
ReturnValue = GetDeviceID();
}
else {
LOG(WII_IPC_FILEIO, "Error opening file %s", m_Filename.c_str());
ReturnValue = -106;
}
} else {
LOG(WII_IPC_FILEIO, "File %s doesn't exist", m_Filename.c_str() );
m_Filename = std::string(HLE_IPC_BuildFilename(GetDeviceName().c_str(), 64));
if (File::Exists(m_Filename.c_str()))
{
switch(_Mode)
{
// Do "r+b" for all writing to avoid truncating the file
case 0x01: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break;
case 0x02: //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)
{
m_FileLength = File::GetSize(m_Filename.c_str());
ReturnValue = GetDeviceID();
}
else
{
LOG(WII_IPC_FILEIO, " failed - File doesn't exist");
ReturnValue = -106;
}
Memory::Write_U32(ReturnValue, _CommandAddress+4);
//LOG(WII_IPC_FILEIO, "===================================================================");
return true;
}

View File

@ -28,6 +28,7 @@
extern std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size);
#define FS_RESULT_OK (0)
#define FS_INVALID_ARGUMENT (-101)
#define FS_FILE_EXIST (-105)
#define FS_FILE_NOT_EXIST (-106)
#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)
{
u32 ReturnValue = 0;
u32 ReturnValue = FS_RESULT_OK;
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
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
thought it didn't exist. So this solution worked for Mario Kart. */
if (!File::Exists(Filename.c_str()) && !File::IsDirectory(Filename.c_str()))
thought it didn't exist. So this solution worked for Mario Kart.
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());
ReturnValue = -6;
LOG(WII_IPC_FILEIO, " No file and not a directory - return FS_INVALID_ARGUMENT", Filename.c_str());
ReturnValue = FS_INVALID_ARGUMENT;
break;
}
@ -131,26 +136,34 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
}
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);
size_t numFile = FileSearch.GetFileNames().size();
for (size_t i=0; i<numFile; i++)
size_t numFiles = 0;
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;
SplitPath(FileSearch.GetFileNames()[i], NULL, &filename, &ext);
std::string CompleteFilename = filename + ext;
memcpy(pDest, (filename + ext).c_str(), MAX_NAME);
pDest[MAX_NAME-1] = 0x00;
LOG(WII_IPC_FILEIO, " %s", pDest);
strcpy(pFilename, CompleteFilename.c_str());
pFilename += CompleteFilename.length();
*pFilename++ = 0x00; // termination
numFiles++;
LOG(WII_IPC_FILEIO, " %s", CompleteFilename.c_str());
}
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;
@ -190,7 +203,7 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
fsBlock = (u32)(overAllSize / (16 * 1024)); // one bock is 16kb
iNodes = (u32)(FileSearch.GetFileNames().size());
ReturnValue = 0;
ReturnValue = FS_RESULT_OK;
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;
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());
}
@ -218,14 +233,33 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
return true;
}
s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize)
{
switch(_Parameter)
{
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;
case CREATE_DIR:
{
_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;
u16 GroupID = Memory::Read_U16(Addr); Addr += 2;
std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64));
Addr += 64;
std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64)); Addr += 64;
Addr += 9; // owner attribs, permission
u8 Attribs = Memory::Read_U8(Addr);
@ -248,6 +281,30 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
}
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:
{
_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;
u16 GroupID = 0;
std::string Filename = HLE_IPC_BuildFilename((const char*)Memory::GetPointer(_BufferIn), 64);
u8 OwnerPerm = 0;
u8 GroupPerm = 0;
u8 OtherPerm = 0;
u8 Attributes = 0;
u8 OwnerPerm = 0x3; // read/write
u8 GroupPerm = 0x3; // read/write
u8 OtherPerm = 0x3; // read/write
u8 Attributes = 0x00; // no attributes
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
{
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
{
@ -355,15 +411,12 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
case CREATE_FILE:
{
//LOGV(WII_IPC_FILEIO, 0, "==============================================================");
_dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0);
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(Addr), 64));
Addr += 64;
std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(Addr), 64)); Addr += 64;
u8 OwnerPerm = Memory::Read_U8(Addr); Addr++;
u8 GroupPerm = 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, " Attributes: 0x%02x", Attributes);
// check if the file allready exist
// check if the file already exist
if (File::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
// 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());
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);
break;
}
//LOGV(WII_IPC_FILEIO, 0, "==============================================================");
return FS_RESULT_FATAL;
}

View File

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