Reputation: 2934
I have two projects in C:
The first:
include windows.h
include stdio.h
include tchar.h
int main()
{
HANDLE hFile = CreateFile("D:\\f.txt",
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hFile == INVALID_HANDLE_VALUE)
_tprintf("Error: CreateFile %d\n",GetLastError());
Sleep(5000);
return 0;
}
The Second:
include windows.h
include stdio.h
include tchar.h
int main()
{
HANDLE hFile = CreateFile("D:\\f.txt",
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hFile == INVALID_HANDLE_VALUE)
_tprintf("Error: CreateFile %d\n",GetLastError());
return 0;
}
The first program is supposed to open the file for reading while allowing others to read from it. The second is supposed to open the file for reading.
When I run the program, the second one give me error 32 (ERROR_SHARING_VIOLATION).
I thought the whole point of FILE_SHARE_READ was to allow other threads/processes to open a file just for reading regardless of whether it's already open or not.
Can anyone help me solve this problem?
P.S. If the file were a mailslot, would that make any difference?
Upvotes: 2
Views: 3416
Reputation: 416
You cannot request a sharing mode that conflicts with the access mode that is specified in an existing request that has an open handle. CreateFile would fail and the GetLastError function would return ERROR_SHARING_VIOLATION.
Here in the first program, you specify the third parameter (dwShareMode) as granting "read" permission to other processes and requests "write" access for itself in the second parameter (dwDesiredAccess).
Then in the second program, you ask for "read" access in the second parameter (which is fine) and grant only "read" permission to other processes in the third parameter, which conflicts with the access mode specified in the first program ("write"). The opening of the file by the first program is an "existing request that has an open handle".
In the first program, you are saying that "I can write to "f.txt". Other people can only read it." and in the second program you are saying that "I can read "f.txt". Other people can only read it.", which is a contradiction, as the first program is already writing to "f.txt".
As has already been mentioned, reading and writing to a file simultaneously by two different processes is a good recipe for data corruption.
Upvotes: 3
Reputation: 942458
Your CreateFile() call explicitly denies write sharing, you specified FILE_SHARE_READ. That cannot work, the first program already gained write access since it used GENERIC_WRITE. You cannot deny a right that was already acquired so the call will fail with a sharing violation error.
To make it work, the second call will have to specify FILE_SHARE_WRITE instead. And deal with the headache of trying to read from a file that's being written to at unpredictable times and places. This typically only comes to a good end when the 1st process only appends to the file and doesn't seek. And you properly dealing with sometimes only getting a part of the appended data because some of it is still stuck in a buffer or in the process of being written. Tricky stuff. Consider a pipe in message mode if that's a problem.
Reiterating from the comments, the sharing flags do not control what you can do, they control what another process can do with the file. What you want to do is specified in the 2nd argument. So the missing FILE_SHARE_WRITE is the problem since it prevents another process from writing to the file. But it already does.
Upvotes: 7
Reputation: 3344
I think the answer in CreateFile documentation:
You cannot request a sharing mode that conflicts with the access mode that is specified in an existing request that has an open handle. CreateFile would fail and the GetLastError function would return ERROR_SHARING_VIOLATION.
i.e. you open file to write but you didn't indicate that this write can be shared.
Upvotes: 1