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
NULL, // default security
OPEN_EXISTING, // existing file
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:
Device Object: 0x89e51900 \Driver\Ftdisk
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.