RPCS3 / rpcs3

PS3 emulator/debugger
https://rpcs3.net/
GNU General Public License v2.0
15.26k stars 1.9k forks source link

I/O functions prefer to return CELL_ENOTMOUNTED instead of correct error code #3327

Closed jjsat closed 6 years ago

jjsat commented 7 years ago

For any filename that is non-null but does not conform to the regex in vfs::get - such as relative paths - the CELL_ENOTMOUNTED error is returned. This is incorrect if compared to a PS3. The error should be E_NOENT or similar as some games assign the not-mounted error a special meaning and retry the access in hope that the device becomes available again.

For example:

From what I can see the PS3 only returns not mounted errors for non-relative paths (e.g. starting with a "/").

This issue is different from #3062 since the error is justified. The returned error code is wrong though.

jjsat commented 7 years ago

Test code:

char* test_strings[] =
{
    "MXR.DLL",
    "./SHADERS/",
    "file://scaleform\\others\\rootmovie\\rootmovie.gfx",
    "/invalid/device/path",
    "\\invalid\\device\\path",
    "/dev_hdd0/file/not/found",
    "\\dev_hdd0\\this\\is\\not\\windows",
    "\\dev_hdd0",
    "/dev_hdd0",
    "file://dev_hdd0",
    (char*)0
};

for (i = 0; i < sizeof(test_strings) / sizeof(test_strings[0]); i++)
{
    sysFSStat sysfsstat;
    memset(&sysfsstat, 0, sizeof(sysFSStat));
    unsigned int result = sysLv2FsStat(test_strings[i], &sysfsstat);

    printf("%s -> %08X\n", test_strings[i], result);
}

PS3:

MXR.DLL -> 80010006
./SHADERS/ -> 80010006
file://scaleform\others\rootmovie\rootmovie.gfx -> 80010006
/invalid/device/path -> 8001003A
\invalid\device\path -> 80010006
/dev_hdd0/file/not/found -> 80010006
\dev_hdd0\this\is\not\windows -> 80010006
\dev_hdd0 -> 80010006
/dev_hdd0 -> 00000000
file://dev_hdd0 -> 80010006
(null) -> 8001000D

RPCS3:

MXR.DLL -> 8001003A
./SHADERS/ -> 8001003A
file://scaleform\others\rootmovie\rootmovie.gfx -> 8001003A
/invalid/device/path -> 8001003A
\invalid\device\path -> 8001003A
/dev_hdd0/file/not/found -> 80010006
\dev_hdd0\this\is\not\windows -> 8001003A
\dev_hdd0 -> 8001003A
/dev_hdd0 -> 00000000
file://dev_hdd0 -> 8001003A
<crashes on null pointer: F {PPU[0x1000000] Thread (main_thread) [0x00010fa0]} MEM: Access violation reading location 0x0>
jjsat commented 7 years ago

For completion sake: if the bluray is ejected or no USB stick is inserted the error is also NOTMOUNTED on a PS3.

/dev_bdvd -> 8001003A
/dev_bdvd/does/not/exist -> 8001003A
/dev_usb001 -> 8001003A
jjsat commented 7 years ago

There is another issue if the file path is invalid as a Windows path, but would be just nonexisiting for the PS3 (and Linux I guess).

PS3:

/dev_hdd0/c:/some/windows/path -> 80010006
/dev_hdd0/c:\some\windows\path -> 80010006
c:/some/windows/path -> 80010006
c:\some\windows\path -> 80010006

RPCS3:

/dev_hdd0/c:/some/windows/path -> 8001002B
/dev_hdd0/c:\some\windows\path -> 8001002B
c:/some/windows/path -> 8001003A
c:\some\windows\path -> 8001003A

This behaviour should be new since ae1e9e78dbd80b7b348d5b0230f183501a1192d1. It makes Wolfenstein retry a file access like the first example forever. The game seems to expect ENOENT.

Nekotekina commented 7 years ago

Does #3454 help a bit?

jjsat commented 7 years ago

Now after #3454:

MXR.DLL -> 80010006
./SHADERS/ -> 80010006
file://scaleform\others\rootmovie\rootmovie.gfx -> 8001002B
/invalid/device/path -> 8001003A
\invalid\device\path -> 80010006
/dev_hdd0/file/not/found -> 80010006
\dev_hdd0\this\is\not\windows -> 80010006
\dev_hdd0 -> 80010006
/dev_hdd0 -> 00000000
file://dev_hdd0 -> 8001002B
/dev_bdvd -> 8001003A
/dev_bdvd/does/not/exist -> 8001003A
/dev_usb001 -> 8001003A
/dev_hdd0/c:/some/windows/path -> 8001002B
/dev_hdd0/c:\some\windows\path -> 8001002B
c:/some/windows/path -> 8001002B
c:\some\windows\path -> 8001002B

Everything returns the right code except for the paths with ":" in it and the null pointer which still crashes.

Nekotekina commented 7 years ago

I'd like to test pathes "" and "/" and if possible, open them as directories

jjsat commented 7 years ago

PS3:

 -> stat=80010006, dopen=80010006
/ -> stat=00000000, dopen=00000000

RPCS3:

 -> stat=00000000, dopen=00000000
/ -> stat=00000000, dopen=80010009

Not sure if opening root works like this if you don't have a custom firmware on the PS3.

jjsat commented 7 years ago

Referring to #3467, I was looking at a GTA V log and it does some wild stat calls, which give ENOENT on the PS3. It is the same issue with the ":" in the path unless this is some super-special syntax and not just garbage as I would assume: memory:$2c430000,148851,0:00001_font_lib_efigs_ps3.gfx -> stat=80010006

jjsat commented 6 years ago

3575 fixes the error code for paths containing ":"

Differences that remain are the behaviour if a null pointer is passed and the error code for an empty string.