[Resolved] Physfs exception thrown


I’m trying to use Physfs in VS2019 win10pro 1809 with SDL but i’m stuck with the init in a fresh new empty test project
I call PHYSFS_init it return 0 (so there is an error) but the PHYSFS_getLastError() is empty.
When my program call PHYSFS_mount I get an exception thrown (if the lib is not init it seem normal).

I made a little picture showing more about that :

At first I tried to add that in my SDL project to create RWOPS and found everything I need but got the same errors and when I compiled it, it asked me to link : “Advapi32.lib User32.lib Shell32.lib”. (in the new test project it didn’t asked)

Thank’s for the help.

Maybe try PHYSFS_init(NULL); instead.

This is probably not an SDL issue but I will try assist.
Are you passing arguments into vs2019 when you run your program.

This is an example of building and passing argument in command line,
I am not sure how this works in vs2019, but I reckon this is your issue.
You have not passed any arguments or using arg[0] would be wrong I think.

Build Program
g++ Main.cpp -o main 

Pass the arguments when running the program
./a.out First Second Third

// Main.cpp
int main(int argc,char* argv[]) 
    //argv[0]: ./a.out
    //argv[1]: First
    //argv[2]: Second
    //argv[3]: Third

Thank’s for the help.

I tried outside the IDE with custom argument but it’s still the same.
I tried with NULL too and it has the same behavior.
My project in VS2019 doesn’t have argument while debug but argv[0] should be ok.


PS : I know it’s not really SDL related but I was trying to add it to my SDL Game engine and the creator of this lib is a maintener of SDL, so i though he might see this :slight_smile:

Did you try with arg[1] outside the IDE with custom argument .

I tried with argv[1] but I don’t understand why. The init really wait argv[0] (probably to know where it is).

I tried inside IDE, outside IDE, with GCC (mingw).

I could try clang but I think the problem will be the same

It seems args[0] is to be passed according to the documentation. NULL can also be used it seems also.

If you look at the docs for PHYSFS_getLastError:

As of PhysicsFS 2.1, this function has been nerfed. Before
PhysicsFS 2.1, this function was the only way to get error details
beyond a given function’s basic return value. This was meant to be a
human-readable string in one of several languages, and was not useful
for application parsing. This was a problem, because the developer and
not the user chose the language at compile time, and the PhysicsFS
maintainers had to (poorly) maintain a significant amount of
localization work. The app couldn’t parse the strings, even if they
counted on a specific language, since some were dynamically generated.
In 2.1 and later, this always returns a static string in English; you
may use it as a key string for your own localizations if you like, as
we’ll promise not to change existing error strings. Also, if your
application wants to look at specific errors, we now offer a better
option: use PHYSFS_getLastErrorCode() instead.

So I would try using PHYSFS_getLastErrorCode() and see what you get.

I tryed with the newed get error and got the same result
The code returned is 0 and the string is “no error”

Since you have the source, I would say the next step is to step into it
with a debugger and see what’s happening.

After some debug here what I found

So in fact the “UserDir” was empty so it lead to an abort of the init. The call of the function" rc = pGetDir(accessToken, &dummy, &psize);" to optain the &psize fail and lead to a psize = 0 so the next pGetDir fail too and the return value is 0.

So to get it work because I don’t know what to really do, and what the library wait for return value (my user directory ?) I made a little workaround image and it work but it’s hardcoded.

A less “hardcode” fix is that

just make psize = MAX_PATH. I added *2 because there is workaround in windows to get double of the path limit so i prefer to double it here.

So I looked in the mercurial and it already have a commit for that : https://hg.icculus.org/icculus/physfs/rev/ece6769c0676 and it is not included in the file provided in the “last” version 3.0.1 so I didn’t minded that there could be one.

The fix is that it doesn’t use a dummy but directly NULL (and I should have tried with that).

Yeah, sorry, Microsoft broke that API in Windows 10. We’re going to do a PhysicsFS 3.0.2 release eventually to deal with that.

1 Like

LOL, the comment right above that line

Also note that the second parameter can’t be NULL or the function fails.

(does this mean it’s broken on older Windows versions now? or is the comment incorrect?)

(FWIW, according to https://docs.microsoft.com/en-us/windows/desktop/api/userenv/nf-userenv-getuserprofiledirectoryw setting the second argument to NULL to get the size in the third argument is valid and normal)

Either I misread the docs 18 years ago, or this detail was changed in newer revisions. It definitely accepts NULL back to at least Windows XP, though. It’s 100% possible I was coding defensively for Windows 95 users, which were only six years old at the time.


As a followup: I tested this, and it definitely does not accept NULL on (at least 32-bit) WinXP. It wasn’t an issue on Win9x, since this API didn’t exist there. Microsoft made this work with NULL at some point (and broke the legit way you were originally meant to use it in WinXP times, too) and quietly changed the documentation. :frowning:


(Actually, it’s weirder than that: it does something different if built with Visual C++ 6.0, which suggests there’s some version field in the .exe that causes Windows to do something differently. Or I’m totally wrong here, or whatever. At any rate, there’s a fallback in PhysicsFS to handle both cases now and we can stop discussing this. :slight_smile: )