Determine share mode of opened file handle

If there is a file already opened and you also want to open it, you need to know the share mode: FILE_SHARE_* the previous CreateFile calls have specified. I came across the problem and the first thing I tried is to use Process Monitor, which shows all the flags passed in when CreateFile is called. For example, you have information like:

... EXCEL.EXE    5940    CreateFile    D:\temp\bbbb.xlsx    SUCCESS    Desired Access: Generic Read/Write, Disposition: OpenIf, Options: Synchronous IO Non-Alert, Non-Directory File, Open No Recall, Attributes: n/a, ShareMode: Read, ...

However, there can be many CreateFile calls. You have to go through them carefully. With that information, I tried to call:

HANDLE hFile = CreateFile( _T("d:\\temp\\bbbb.xlsx"),

GENERIC_READ, // open for reading

FILE_SHARE_READ,

NULL, // default security

OPEN_EXISTING, // existing file

FILE_ATTRIBUTE_NORMAL,

NULL);

 

However It does not work. I suspected whether the information I got from ProcessMonitor is correct. After some searching, I learned that FILE_OBJECT structure actually contains this information. You could use WinDBG to get it. What I did is to choose File->Kernel Debug...->Local. Then use Process Explorer to obtain the file handle address of the file and issue !fileobj on it like: 

lkd> !fileobj 0x8939F1C8

The output is like:

\temp\bbbb.xlsx

Device Object: 0x89e51900   \Driver\Ftdisk
Vpb: 0x89e21070
Event signalled
Access: Read Write SharedRead

It basically has the same information as what I got from ProcessMonitor. Now staring at it longer, I realized I didn't read Raymond Chen's blog carefully: the FILE_SHARE_* mode needs to be compatible with previous access mode. In my case, the file has been opened as GENERIC_READ | GENERIC_WRITE, the share mode in the latter CreateFile has to be at least FILE_SHARE_READ | FILE_SHARE_WRITE. Changing that and the file can now be opened.