Microsoft KB Archive/316609

From BetaArchive Wiki
Knowledge Base


PRB: ERROR_SHARING_VIOLATION Error Message When the CreateFile Function Fails

Article ID: 316609

Article Last Modified on 11/21/2006



APPLIES TO

  • Microsoft Win32 Application Programming Interface



This article was previously published under Q316609

SYMPTOMS

When you open a file with the FILE_SHARE_READ flag and the FILE_SHARE_WRITE flag, the CreateFile function may fail and return the following error message:

ERROR_SHARING_VIOLATION (error code 32)

STATUS

This behavior is by design.

MORE INFORMATION

When you open a file by using the CreateFile function or any function that uses CreateFile internally, you may experience an unexpected failure because of a sharing violation. Even if the file is only for a specific application, there are potentially other processes that may try to access the file at the same time. There are common system components and also other third-party applications that cause this problem. There are common system components and also third-party applications (such as virus-scanning software) that cause this problem.

The Microsoft Windows operating system is a preemptive, multiprocessing system, which gives the appearance of many applications running simultaneously. Any particular application must be "aware" that it is not the only process running on the system and that it is vying for resources with other processes. Problems that may occur because of resource handling must be addressed. In the case of files, any running process has the right to try to use the resource. There are always system components and third party services that compete for resources simultaneously. When an application tries to access files on the system, that application competes with the other processes.

There are two common causes for an ERROR_SHARING_VIOLATION:

  • There are multiple applications that use a particular file on disk (common shared data files). An application is currently accessing the file in a way that is incompatible with the way a second application tries to access the same file. For example, you may want to update the file, but another process is currently writing to the file and is only sharing the file for reading (FILE_SHARE_READ).
  • The file is a data file specific to your application, and you do not expect another application to have the file open. In this scenario, other processes may lock a file for a short duration for other reasons.

The most common problem occurs when a utility, such as a virus scanner, backup software, or a disk optimizer, that locks a file on disk for a short time. When another application tries to open the file, even with full sharing turned on, the attempt fails with a sharing violation. You can expect this result because the service must have exclusive access for the duration of the operation on the file. To resolve this issue, try again a short time later. Frequently, the service is completed with the file in a matter of milliseconds.

Both of the causes for sharing violations described earlier must be handled similarly. When you open a file, you must always handle a sharing violation in a graceful manner so that you do not affect the user of the system or cause the system to crash. You can do this by using a simple retry mechanism. You may have to perform multiple retries before the file is unlocked.

The following code sample demonstrates this technique:

#define MAXRETRIES  5
#define RETRYDELAY  250

HANDLE  hFile     = INVALID_HANDLE_VALUE
DWORD   dwRetries = 0;
BOOL    bSuccess  = FALSE;
DWORD   dwErr     = 0;

do
{
    hFile = CreateFile( szFile,
                        GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL);
    if ( INVALID_HANDLE_VALUE == hFile )
    {
        dwErr = GetLastError();

        if ( ERROR_SHARING_VIOLATION == dwErr )
        {
            dwRetries += 1;
            Sleep(RETRYDELAY);
            continue;
        }
        else
        {
            // An error occurred.
            break;
        }
    }

    bSuccess = TRUE;
    break;
} while ( dwRetries < MAXRETRIES );

if  ( bSuccess )
{
    // You succeeded in opening the file.
}
else
{
    // Failure occurs. Do graceful error handling.

    // Here, you must notify the user of the failure.

MessageBox( NULL,
            "Tried to update data file but it was already in use",
            "Update error...",
            MB_OK | MB_ICONSTOP );

    // You also want to put the software back in the state it was in
    // on entrance of the current function, as if the user had never
    // tried to do the update.

    // This may also require deallocating any resources that were
    // allocated because of this operation.
}
                

This method for gracefully handling the sharing violation error gives an application that has the file open time to complete. Each time that you receive a sharing violation error, you must permit the application to sleep for a while, and then try again. If a virus scanner or a system service has the file open, the virus scanner or the system service may finish after one or two retries. Make sure that you limit your retries to avoid an infinite loop. If another application currently has the file open (and may keep the file open for a long time), inform the user by breaking out of the loop, and then gracefully exit.

Keywords: kbfileio kbkernbase kbprb KB316609