Note that there are some explanatory texts on larger screens.

plurals
  1. PORandom MoveFileEx failures on Vista
    primarykey
    data
    text
    <p>I noticed that writing to a file, closing it and moving it to destination place randomly fails on Vista. Specifically, MoveFileEx() would return <code>ERROR_ACCESS_DENIED</code> for no apparent reason. This happens on Vista SP1 at least (32 bit). Does not happen on XP SP3.</p> <p>Found <a href="http://groups.google.com/group/microsoft.public.windows.file_system/browse_thread/thread/e9774e86e98eb623/3348d92b8ba5858d?lnk=raot&amp;pli=1" rel="nofollow noreferrer">this thread</a> on the internets about exactly the same problem, with no real solutions. So far it looks like the error is caused by Vista's search indexer, see below.</p> <p>The code example given there is enough to reproduce the problem. I'm pasting it here as well:</p> <pre><code>#include &lt;windows.h&gt; #include &lt;stdlib.h&gt; #include &lt;stdio.h&gt; bool test() { unsigned char buf[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }; HANDLE h; DWORD nbytes; LPCTSTR fn_tmp = "aaa"; LPCTSTR fn = "bbb"; h = CreateFile(fn_tmp, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, 0, 0); if (h == INVALID_HANDLE_VALUE) return 0; if (!WriteFile(h, buf, sizeof buf, &amp;nbytes, 0)) goto error; if (!FlushFileBuffers(h)) goto error; if (!CloseHandle(h)) goto error; if (!MoveFileEx(fn_tmp, fn, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH)) { printf("error=%d\n", GetLastError()); return 0; } return 1; error: CloseHandle(h); return 0; } int main(int argc, char** argv) { unsigned int i; for (i = 0;; ++i) { printf("*%u\n", i); if (!test()) return 1; } return 0; } </code></pre> <p>Build this as console app with Visual Studio. Correct behaviour would be infinite loop that prints test numbers. On Vista SP1, the program exits after random number of iterations (usually before 100 iterations are made).</p> <p>This does not happen on Windows XP SP2. There's no antivirus running at all; and no other strange background processes (machine is pretty much vanilla OS install + Visual Studio).</p> <p><strong>Edit</strong>: Digging further via Process Monitor (thanks @sixlettervariables), I can't see anything particularly bad. Each test iteration results in 176 disk operations, majority of them coming from SearchProtocolHost.exe (search indexer). If search indexing service is stopped, no errors occur, so it looks like it's the culprit.</p> <p>At the time of failure (when the app gets <code>ERROR_ACCESS_DENIED</code>), SearchProtocolHost.exe has two CreateFile(s) to the detination file (bbb) open with read/write/delete share modes, so it should be ok. One of the opens is followed by opportunistic lock (<code>FSCTL_REQUEST_FILTER_OPLOCK</code>), maybe that's the cause?</p> <p>Anyway, I found out that I can avoid the problem by setting <code>FILE_ATTRIBUTE_TEMPORARY</code> and <code>FILE_ATTRIBUTE_NOT_CONTENT_INDEXED</code> flags on the file. It looks like <code>FILE_ATTRIBUTE_NOT_CONTENT_INDEXED</code> is enough by itself, but marking file as temporary also dramatically cuts down disk operations caused by search indexer.</p> <p>But this is <strong>not a real solution</strong>. I mean, if an application can't expect to be able to create a file and rename it because some Vista's search indexer is messing with it, <strong>it's totally crazy</strong>! Should it keep retrying? Yell at the user (which is very undesirable)? Do something else?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload