File Writing on Non-Admin accounts
by Robert Fritzen · in Torque 3D Professional · 07/22/2012 (8:50 am) · 7 replies
There is a problem with file writing in T3D (and I think all of the engines). When you run your game on a non-administrator account, fileObjects cannot write to the game's directory (assuming you're installing it to program files or other typical protected folders).
I advise making the game's executable require UAC Elevation to give the game these administrator privileges to avoid these kind of issues. I've experienced multiple access violation errors reading/writing to 0x00000000 due to this issue.
I advise making the game's executable require UAC Elevation to give the game these administrator privileges to avoid these kind of issues. I've experienced multiple access violation errors reading/writing to 0x00000000 due to this issue.
About the author
Illinois Grad. Retired T3D Developer / Pack Dev.
#2
07/22/2012 (10:26 am)
I remember Thomas Dickerson and I tried to fix this in TGE. It wasn't easy - getting the path to AppData wasn't trivial, unless we were just being really dumb.
#3
Should work in anything from XP / Server 2003 and newer, according to MSDN. I tested it on XP.
It should be fairly easy to modify TGE to use the same system that it already uses on Linux to handle home directories.
Thanks for bringing this to my attention. I shall have to fix this in my game. I rail against software developers who require their apps to be run with Admin privileges; there's no way I could release my game in such a state. Frankly, it's shameful that this hasn't been done already in T3D.
07/22/2012 (11:26 am)
Quickly researched hastily tested pseudocode:#include <windows.h>
...
int size = GetEnvironmentVariable("AppData", buffer, BUFFER_SIZE);
if (size == 0) fail("WTF? No AppData defined?!");
else if (size == BUFFER_SIZE) fail("AppData path too long!")
else we're good!Should work in anything from XP / Server 2003 and newer, according to MSDN. I tested it on XP.
It should be fairly easy to modify TGE to use the same system that it already uses on Linux to handle home directories.
Thanks for bringing this to my attention. I shall have to fix this in my game. I rail against software developers who require their apps to be run with Admin privileges; there's no way I could release my game in such a state. Frankly, it's shameful that this hasn't been done already in T3D.
#4
Next, created the following TorqueScript utility function:
Note that the utility function will go ahead and try to create the directory for you so that you can make of use that path immediately after calling it. Here's also a truth table of what to expect out of GetUserDataPath():
Updated: Fixed bad handling of paths between Mac OS and UNIX/Linux paths.
07/22/2012 (3:05 pm)
I spent a couple of hours working on this, I hope you guys will find it useful. First we need to implement the ability to access environment variables, so let's do just that. I have the following console function stored in Engine/source/console/scriptFilename.cppDefineConsoleFunction( getEnvironmentVariable, const char*, (const char *variableName),,
"@brief Returns the value of the requested operating system's environment variable.\n"
"@param variableName Name of the environment variable\n"
"@return String value of the requested environment variable.\n"
"@ingroup Console")
{
// get requested environment variable value
const char *result = getenv(variableName);
// verify successful operation
if(result)
{
// success, allocate return space and return the result
char *ret = Con::getReturnBuffer(dStrlen(result) +1);
dStrcpy(ret, result);
return ret;
}
// fail, environment variable doesn't exist
return "";
}Next, created the following TorqueScript utility function:
// retrieves the absolute path to the game's writable file storage directory
function GetUserDataPath()
{
/*
Notes on how to determine the operating system.
$platform values determine OS:
"windows" Microsoft Windows
"macos" Apple Mac OS
"x86UNIX" UNIX (POSIX compliant) operating system, see $platformUnixType
"xenon" XBox 360
$platformUnixType values determine which UNIX OS:
"Linux" a Linux distribution
"OpenBSD" OpenBSD (engine uses __OpenBSD__ macro to determine this)
"Unknown" other UNIX operating system
*/
%separator = "/";
// retrieve the path to where programs should store their writable files
if($platform $= "windows")
{
// try getting the local application data path (typically available only on Vista and above)
%path = getEnvironmentVariable("LOCALAPPDATA");
// if it failed then we're on Windows XP or below
if(%path $= "")
{
// get Application Data path, note that this is not the Local Settings variant
%path = getEnvironmentVariable("APPDATA");
}
%path = %path @ %separator;
} else
{
// get home path
%path = getEnvironmentVariable("HOME");
if($platform $= "macos")
%path = %path @ "/Library/Application Support/";
else
%path = %path @ "/.";
}
// append game specific directory name
if($appDataDirName $= "")
%path = %path @ $appName @ %separator;
else
%path = %path @ $appDataDirName @ %separator;
// create the directory if it doesn't exist
// Note: createPath() only accepts '/' (not '\') as a trailing slash
if(!IsDirectory(%path))
createPath(%path);
// return the full path to the game's writable directory
return %path;
}Note that the utility function will go ahead and try to create the directory for you so that you can make of use that path immediately after calling it. Here's also a truth table of what to expect out of GetUserDataPath():
/*
GetUserDataPath() Truth Table:
When:
$appDataDirName = ""; // or not defined at all
$appName = "Playground2";
Results:
<= Windows XP: C:\Documents and Settings\{username}\Application Data\Playground2
>= Windows Vista: C:\Users\{username}\AppData\Local\Playground2
Mac OS X: /Users/{username}/Library/Application Support/Playground2
Linux: /home/{username}/.Playground2
When:
$appDataDirName = "MyCompany/Playgnd2";
$appName = "Playground2";
Results:
<= Windows XP: C:\Documents and Settings\{username}\Application Data\MyCompany/Playgnd2
>= Windows Vista: C:\Users\{username}\AppData\Local\MyCompany/Playgnd2
Mac OS X: /Users/{username}/Library/Application Support/MyCompany/Playgnd2
Linux: /home/{username}/.MyCompany/Playgnd2
*/Updated: Fixed bad handling of paths between Mac OS and UNIX/Linux paths.
#5
This should be a resource so it gets the visibility it deserves. This is excellent work.
07/22/2012 (3:42 pm)
@Nathan,This should be a resource so it gets the visibility it deserves. This is excellent work.
#6
07/22/2012 (6:52 pm)
Thanks, this will make things run more smoothly now.
#7
07/23/2012 (1:01 am)
I also thought that TGE and TGEA were 'sandboxed' to some extent, and unable to read/write/exec files that were in directories above the one where the .exe resided. I haven't actually checked if this is still the case with T3D.
Torque Owner Guy Allard
Default Studio Name