Application Directory Writes

edited 2009 Mar 8 in Developers
<i>This post was originally made by <b>danij</b> on the dengDevs blog. It was posted under the categories: Beta 6, Engine, Windows.</i>

Currently Doomsday will make various write attempts to the application directory during startup, even if the working directory is set to some other location.

Under versions of Windows prior to Windows Vista this is no big issue but under Vista, this is leading to UAC throwing various errors during startup.

I have used Microsoft's Windows Application Verifier to locate some of these potential issues. The first of which is the font manager which for some reason is attempting to create the directory <i>C:\Program Files (x86)\Doomsday\dataonts</i>. Doomsday.exe runs with the privileges of the current user by default and if that user does not have administrator privileges, this directory will not be created. Subsequently, Doomsday will then attempt to read the file <i>C:\Program Files (x86)\Doomsday\dataonts
ormal18.dfn</i> which will obviously fail.

Firstly, why is Doomsday creating this folder? Secondly, why is it trying to read a file without first checking that the path is valid?

Should the fonts be installed into the application directory by the Doomsday windows installer? If so, I'll make the necessary changes but that doesn't explain why Doomsday.exe is attempting to create that folder in the application directory.

Here follows an excerpt from the log produced by Windows Application Verifier:
<code><avrf:logEntry Time="2009-03-04 : 17:40:27" LayerName="LuaPriv" StopCode="0x332E" Severity="Warning">

<avrf:message>
The application called an API that failed unexpectedly, possibly due to bad parameters.
</avrf:message>

<avrf:formatmessage>
CreateFileA: File (C:\Program Files (x86)\Doomsday\dataonts
ormal18.dfn) is denied 'GENERIC_READ' access with error 0x3.
</avrf:formatmessage>
<avrf:parameter1>3 - Error returned</avrf:parameter1>
<avrf:parameter2>80000000 - Access Requested (if applicable)</avrf:parameter2>
<avrf:parameter3>80000000 - Access Requested (for compatibility)</avrf:parameter3>
<avrf:parameter4>0 - n/a</avrf:parameter4>
<avrf:stackTrace>
<avrf:trace>
vfluapriv!NS_LuaPriv::LogApiFail+cc (d:\avrf\source\base\avrf\avrf30\providers\luapriv\misc.cpp @ 518)
</avrf:trace>
<avrf:trace>
vfluapriv!NS_LuaPriv::VfHookCreateFileA+e3 (d:\avrf\source\base\avrf\avrf30\providers\luapriv\luapriv.cpp @ 409)
</avrf:trace>
<avrf:trace>Doomsday!curl_formget+4e09 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!curl_formget+5424 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!curl_formget+5494 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!curl_formget+127d6 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!curl_formget+696a ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!curl_formget+69a1 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!Ordinal245+47a ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!Ordinal245+776 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!Ordinal109+7921 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!Ordinal331+165 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!Ordinal330+e0 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!Ordinal7+346 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!Ordinal213+18d9 ( @ 0)</avrf:trace>
<avrf:trace>Doomsday!curl_formget+9b1d ( @ 0)</avrf:trace>
<avrf:trace>KERNEL32!BaseThreadInitThunk+e ( @ 0)</avrf:trace>
<avrf:trace>ntdll!RtlCreateUserProcess+8c ( @ 0)</avrf:trace>
<avrf:trace>ntdll!RtlCreateProcessParameters+4e ( @ 0)</avrf:trace>
</avrf:stackTrace>
</avrf:logEntry></code>

Comments

  • <blockquote>Firstly, why is Doomsday creating this folder? Secondly, why is it trying to read a file without first checking that the path is valid?</blockquote> But that folder isn't actually created (at least on XP). My theory is that the function we use to test whether a file exists is triggering the UAC. I think it may be a plain fopen().

    There must be some Win32 API for checking whether files exist, though?

    It's perfectly fine to have the fonts in the PK3 as virtual files if we fix the existence detection that's used for checking if anything is overriding the virtual files.
  • If we are using an <tt>fopen</tt> attempt to determine whether a file exists that would certainly explain why UAC is triggered.

    <tt>M_CheckPath</tt> has the side effect that it will apparently create the tested path should it not exist.
  • <blockquote cite="#commentbody-3360">
    If we are using an <tt>fopen</tt> attempt to determine whether a file exists that would certainly explain why UAC is triggered.</blockquote> However, judging by <tt>F_Open</tt> it looks as though the real file access shouldn't even happen because the virtual files are checked first, and the font definitely should be found there. Unless the font is prepared before the PK3s have been loaded, like the first time busy mode is entered... Maybe that's when it tries to <tt>fopen</tt> it?

    <blockquote cite="#commentbody-3360"><tt>M_CheckPath</tt> has the side effect that it will apparently create the tested path should it not exist.</blockquote> <tt>M_CheckPath</tt> is not called unless the -fontdir option is used, which I think isn't used here? So that's OK. (Although I would argue that the function is misnamed, it should be something like <tt>M_MakePath</tt>.)
  • <blockquote>Unless the font is prepared before the PK3s have been loaded, like the first time busy mode is entered? Maybe that?s when it tries to <tt>fopen</tt> it?</blockquote>
    That very well could be the problem. As the vfs is not available at this time, it will then attempt to open it from the "real" fontdir, with <tt>M_CheckPath</tt> then attempting to create the path as it does not exist.
Sign In or Register to comment.