-1

How can I check is specific directory opened by a user (Windows) in c++ (WinAPI)? For example, I have program in \user\My Documents\checker.exe. checker.exe is running in background and checking if user open My Documents directory. If this is true, program save system time to a file.txt. Thank you for help!

h3wro
  • 62
  • 1
  • 13
  • After a quick search handle command looks like it can retrieve the data you need. [https://technet.microsoft.com/en-us/sysinternals/bb896655.aspx ] It's a cmd command. You can call cmd commands with `system()` function. – Anže Jan 26 '17 at 10:00
  • only one way exactly do this - write minifilter (or legacy filter) for file system – RbMm Jan 26 '17 at 10:05
  • You might [check for the process (PID) that has the file open](http://stackoverflow.com/questions/6931972/how-to-find-which-process-has-a-handle-on-a-file-from-the-file-name) and then [try to find the user using that PID](http://stackoverflow.com/questions/3172392/detecting-user-name-from-process-id). I am not sure this works for folders though. – Simon Kraemer Jan 26 '17 at 11:19
  • you can got notification on **file** open by using [FSCTL_REQUEST_OPLOCK](https://msdn.microsoft.com/en-us/library/windows/desktop/ee681828(v=vs.85).aspx) with `OPLOCK_LEVEL_CACHE_READ|OPLOCK_LEVEL_CACHE_WRITE` but for **directory** you can work only with [shared](https://msdn.microsoft.com/en-us/library/windows/hardware/ff547128(v=vs.85).aspx) oplock - so got notify only on change but not open. so you can spy file open, but not directory open – RbMm Jan 26 '17 at 11:51
  • Can you indicate **exactly** what you mean by "user open `MyDcouments` directory"? There are more than a few different possible meanings, each with a different answer. – MSalters Jan 26 '17 at 12:06
  • @MSalters Just open `My Documents` by clicking two (Left Mouse Button) times on this icon. – h3wro Jan 26 '17 at 12:08
  • @h3wro - if you really want this (and notify for directory, but not for file open) - write minifilter driver for file system. register `IRP_MJ_CREATE` notification - and you got what you want – RbMm Jan 26 '17 at 12:24
  • @h3wro: So, you mean specifically it's open in Windows Explorer? Because you can also have it open in for instance the common "File Open" dialog. (Start Notepad, choose File>Open in menu, select My Documents) – MSalters Jan 26 '17 at 12:25
  • @MSalters Yes, in Windows Explorer. – h3wro Jan 26 '17 at 12:33
  • @h3wro: In future, dont change question, because at now your question is "If directory is opened in Explorer", but previous was "If directory was opened in any program" – user2120666 Jan 26 '17 at 12:35
  • @user2120666 Okey, sorry and thanks. – h3wro Jan 26 '17 at 12:37
  • Does this answer your question? [How to get the path of an active file explorer window in c++ winapi](https://stackoverflow.com/questions/43815932/how-to-get-the-path-of-an-active-file-explorer-window-in-c-winapi) – Donald Duck Aug 14 '22 at 12:43

1 Answers1

2

You must first get the PIDL of the user's "My Documents" folder using either:

Then, you can enumerate all Explorer windows, comparing the PIDLs from each window. If any window's PIDL matches/begins with the retrieved PIDL, that window has the "My Documents" folder open, or a (grand)child folder.

Community
  • 1
  • 1
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Upvote, but this works only for "My Documents" specifically and this is only OP example of the directory. – user2120666 Jan 26 '17 at 12:45
  • @user2120666: Well, that's because I put in the GUID for My Documents ! If you have a regular path, you'd call `ILCreateFromPath` instead. – MSalters Jan 26 '17 at 12:49
  • What if shell namespace extension, where directory lives, dont handle ParseDisplayName correctly? – user2120666 Jan 26 '17 at 12:51
  • @user2120666: Well, obviously, if there's a bug, then things might not work. But then with such a bug, it's even dubious whether Explorer can open the namepace extension in the first place! – MSalters Jan 26 '17 at 12:55
  • I remember one shell namespace extension many years ago from Germany big firm(not mention name), that ParseDisplayName returns E_FAIL. And MSDN also says"Some Shell folders may not implement IShellFolder::ParseDisplayName. Each folder that does will define its own parsing syntax." So problem may be in parsing subfolder, but not in parsing root folder. – user2120666 Jan 26 '17 at 12:58
  • 1
    Only the top-level desktop folder from `SHGetDesktopFolder()` knows how to parse `"::{guid}"` strings for pre-defined shell items into PIDLs. However, the *correct* way to get the PIDL of the user's "My Documents" folder is to use `SHGetFolderPath(CSIDL_MYDOCUMENTS)` or `SHGetKnownFolderPath(FOLDERID_Documents)` instead. – Remy Lebeau Jan 26 '17 at 21:00