Why is Windows's CreateFile(<no share access>) lying to me?
Asked Answered
T

1

6

I'm trying to prevent a third-party DLL in my process from reading a file I've opened, and I've found it to be... well, impossible.

No matter what I do, no matter what share flags I specify, their call always seems to succeed!

Here is the screenshot from Process Monitor -- the first CreateFile call is mine, and the rest are theirs:

Screenshot

How is this even possible? Why is the "Share Mode: None" lying to me, and how can I prevent this?


This code below is an example that reproduces the problem:

#include <stdio.h>
#include <Windows.h>

int main()
{
    LPCTSTR file = TEXT("C:\\Test1234.xml");
    HANDLE hFile1 =
        CreateFile(file, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_ALWAYS, 0, NULL);
    HANDLE hFile2 =
        CreateFile(file, FILE_READ_DATA, 0, NULL, OPEN_ALWAYS, 0, NULL);
    DWORD n;
    BYTE buf[1];
    printf("%d\n", ReadFile(hFile2, buf, sizeof(buf), &n, NULL));
    CloseHandle(hFile1);
    CloseHandle(hFile2);
    DeleteFile(file);
}
Taegu answered 21/12, 2012 at 3:41 Comment(9)
It's also worth mentioning I have no idea how they set the I/O priority of the file to "very low" right at the beginning. Doesn't every file have "normal" priority until it is changed?Taegu
Please show your code that opens the file.Highflown
You aren't checking for errors.Cockchafer
@DavidHeffernan: Yes I am, that's what printf is for. And I'm seeing 1 (aka TRUE). Process Monitor confirms that all the creation requests (and the read request) go through with no errors, aside from the "End Of File" message on ReadFile. Did you try and run it yourself?Taegu
You didn't check for errors on the first two API calls. Why use FILE_READ_DATA rather than GENERIC_READ? Perhaps that's the problem.Cockchafer
@DavidHeffernan: Like I said, I checked in Process Monitor, they're both successful. And GENERIC_READ doesn't make any difference -- ReadFile succeeds either way. Did you try reproducing the problem? The code is rather easy to run...Taegu
I'm not sure reproducing helps. I think you need insight and understanding. Not that I have that to offer!Cockchafer
If you set dwDesiredAccess parameter of both CreateFile() calls to GENERIC_READ then the second call to CreateFile() does fail as expected (I tested it). If the first call is then changed back to FILE_READ_ATTRIBUTES then the second call succeeds. So it seems that FILE_READ_ATTRIBUTES and FILE_READ_DATA are not restricted by sharing rights.Highflown
@RemyLebeau: Wow, I see... that's really weird, apparently FILE_READ_ATTRIBUTES is really special then. (And another funny thing I noticed is, apparently none of these tricks work on directory handles, only file handles -- you can't deny others access to a directory.) Would you mind posting your finding as an answer? Thanks!Taegu
N
1

Share modes are enforced for actually reading and writing the DATA of the file. Attributes (like file size, timestamps, etc) are not covered by the sharing rules and there is no way to prevent their access short of ACLs.

The best you can to is open the file for R/W/D access and not specify SHARE_READ|WRITE|DELETE.

Weird, but true.

Notional answered 22/12, 2012 at 5:12 Comment(2)
I wasn't trying to prevent the reading of attributes though... I was trying to prevent the reading of data.Taegu
What MJZ means is that you have to open the file for reading/writing of the file data in order to specify sharing rights for subsequent opens that read/write the file data. If you open the file for reading attributes only, you cannot share access for opens that read/write file data.Highflown

© 2022 - 2024 — McMap. All rights reserved.