Technically you need only create/write the files to a non-administrator folder/path and it will work; the saved games/documents/appdata are the recommended places, though. The user might not be too happy if you save the files in random places.
To get the path to one of these folders, you can use the
SHGetKnownFolderPath function. It only works on Vista and above, so if you are also targeting XP you can use the deprecated function
SHGetFolderPath.
The list of folders you can query for SHGetKnownFolderPath is
here (and for SHGetFolderPath
here).
For example, the following:
Code: Select all
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path);
will return the current user's local appdata folder (eg. "c:\users\username\appdata\local") on the pointer "path". You have to call
CoTaskMemFree to free the string when you're done with it (the function allocates the string for you). Also, it is a wide string in UTF-16 format.
After that, you can just create a folder for your game data in there and create/write the save files.
Take a look at the links above, as they properly describe what you can do with the function(s).
Alternatively, for some of the special folders, you can also get their path from the environment, using the
GetEnvironmentVariable function (I don't know if Windows has libc's getenv() function). For example, the same local appdata directory is in the environment variable %LOCALAPPDATA%.
If you'd like to provide an option for a portable installation (ie. save files in the same folder as the game), a common way to do it is to check for the existence of a specific file (eg. one named "portable.txt") in the game folder, and if it exists then it is a portable installation so the config/save files come from the same folder. Of course, now you still have a problem -- the possibility that the user puts the game in a privileged folder and runs it as non-admin -- but that is the user's problem at this point and you could just quit with an error message.
Another way would be to pass a command line argument to enforce reading/writing the save files from the game folder.
The downside of providing multiple save locations is that you have to think about the possibility that multiple save files exist and which should take precedence.
The functions above are from win32's C API. I don't know which language you're using, but there should be comparable bindings available.
Forgot to add: the save games folder token for the SHGetKnownFolderPath function is FOLDERID_SavedGames. The folder itself is "c:\users\username\saved games" and was introduced in Vista.