Skip to content

[ASR] Expose access to "special folder" paths #869

@apple1417

Description

@apple1417

Currently autosplitters can only get the path of the executable they're attached to. Sometimes the file you want to read is not relative to this - e.g. if it's in my documents or under %appdata%. There should be some way to get at these "special folders".

Rather than dealing with string substitutions, I think dotnet has a relatively clean interface we could borrow:

string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

Now dotnet tries to map the same enum values across platforms - e.g. my documents becomes XDG_DOCUMENTS_DIR on linux (source). Since we're trying to replicate whatever logic the game's doing, I think it's better for them to be explicitly different, any logic we implemented might not work the same as the game's.

My proposed API would be something like:

enum SpecialFolder : uint32_t {
    WIN_DOCUMENTS,
    WIN_APPDATA,
    WIN_LOCAL_APPDATA,
    // ...
    XDG_DOCUMENTS,
    // ...
};
bool runtime_get_special_folder(SpecialFolder folder, char8_t* buf, uintptr_t* len);

This would have the same semantics as process_get_path - so trying to get WIN_DOCUMENTS on a linux host would return false/0 length.


As an additional complication, when running a windows game under wine, you'll want to be able to get the special folders in the emulated windows filesystem, rather than on the host linux system. From what I can tell, the best process for finding these is:

  • Pick the process you want to get the path for - different processes may have different wine prefixes, and thus different filesystems
  • Search /proc/{pid}/environ for WINEPREFIX. If it doesn't exist, assume ~/.wine.
  • Read though $WINEPREFIX/user.reg (which stores HKEY_CURRENT_USER), and look for the shell folders. There are two sections, I'm not entirely sure which one takes priority, but I don't imagine many people are manually editing these files anyway, let alone only editing one.

Since this needs to be based on a specific process, it would need another export:

bool runtime_get_wine_special_folder(AttachedProcess process, SpecialFolder folder, char8_t* buf, uintptr_t* len);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions