Register a thumbnail handler for a folder, rather than a specific file type - windows

I need to write a thumbnail handler for all the files under a given folder. This folder is a mounting point for a virtual file system (using Callback File System), and the files are actually not present physically on the local machine (they're stored in the cloud), so if I let the default thumbnail handler do its work, it will try to download the whole files from the server... which is obviously not what I want.
But now I just realized that a thumbnail handler must be registered per file type:
Registration of a thumbnail handler is based on standard file associations.
(from the documentation)
I don't want to register it per file type, because I don't want to change the behavior for files that are not in my virtual folder. Is there a way for my handler to be called for all the files in my virtual folder, and only them?

I see two ways for you to go.
The simple way: Register your own thumbnail handler and let it work on all files. When you don't support IInitializeWithStream but only IInitializeWithItem or IInitializeWithFile you can check if the item/file is in your virtual file system. If so you can return a thumbnail and otherwise return an error.
The problem with this approach is that only one thumbnail provider can be registered per file type.
The hard way: You can write a shell namespace extension. These can be used to display virtual folders, which can be customized in many ways. This is another way to do what you already did using cbfs, but it is restricted to Explorer only. It would add another way to display your virtual folders.
The shell namespace extension will only work for it's own virtual folder. If you mapped your virtual folders to a drive letter and the user opens that drive in Explorer (and not the shell namespace extension's virtual folder), the user would see regular Explorer view of the files, not your shell namespace extension.
Also: Documentation for shell namespace extensions is a pain, there is not much available. I wrote my own shell namespace extension and every time my objects where queried for an IID I traced that and learned a bit more. I saw that my extension is queried for IID_IThumbnailHandlerFactory, I also saw IIDs like IID_IExtractIconA or IID_IContextMenu, but I did not see IID_IThumbnailProvider, nor did I see IID_IExtractImage. This suggests that you cannot have your own IThumbnailProvider directly attached to the objects you create for the virtual folder, but it could also be that I just missed to set some flag somewhere else so that Explorer does not even try to query me.

Related

Is there a way to open a copy of a document(Word, PDF, ect.)in Windows, so that the master copy is always preserved?

I have some forms in various formats(Word and/or PDF) that have prefilled information pertaining to the function they are intended for--such as addresses and control numbers. Typically a user would create a copy of the document and then edit that copy, preserving the master copy. However, this is not always the case and mistakes are being introduced into the master.
Assuming all users are accessing these files in file explorer via a network share, and all utilizing Windows 10, is there a way to ensure that when a user clicks the file to open it they are actually opening a copy of that document?
You could try restricting the edit permissions of the file, which would force users to copy the file before hand.

Reason why folder associated with saved webpage gets deleted when we delete saved page

I have saved a complete webpage and there is also one folder saved with resources but when I delete webpage or move saved webpage to other directory then the folder associated with it also gets deleted or moved. So what is the code written behind it. Because I want to do same with my webpage and folder.
Thanks in advance for you kind help.
This "association" between the HTML file and its resources folder is a behaviour implemented by the Windows operating system.
It has nothing to due with a webpage in particular, with its HTML, JavaScript, or even with a particular browser.
Windows 2000 provides a simple way to connect a primary HTML file to its group of associated files. If Connected Files is enabled, when you perform any of the commands [Copy, Cut, Paste, Move, Delete, Send To] on a file or folder of associated files, the same command is performed on all connected files.
Even though the official page mentions "Windows 2000", the same behaviour is implemented in Windows XP and many (if not all) later versions of Windows.
See these pages:
Removing file / folder link after using “Save As…” then “Web Page, complete”
Operations on an HTML file or folder apply to similarly named folder or HTML file (from Microsoft support)

Windows Explorer and Reparse Point Files: keep Explorer from opening my files

I've implemented a user mode program and a Windows file system minifilter that creates a skeleton view of users files for a remote file storage system. It maps the remote files to the local drive. The user mode program creates a reparse tag for each file on the remote system. When a create request (e.g., CreateFile for read) is detected, the minifilter asks the user mode program to download the file. This should only happen when a program wants to open the file for viewing or editing.
But, I'm finding that Windows Explorer is triggering my files to download. I'd like to prevent the Explorer File windows and File Open/Save dialogs from
triggering downloads. And, I also want to display the file thumbnails and file
size.
[Update: I've found I can use Windows sparse files to show my remote
file size in Explorer. ]
Therefore, I have also implemented a Shell Extension, IThumbnailProvider, that downloads a rendition of the file. This provides the file thumbnails.
For my testing, I've registered the IThumbnailProvider for all files (*) and for .jpg files.
I'm seeing two interesting behaviors using a combination of Process Monitor and DebugView (both from SysInternals):
1. If I make my minifilter reject requests to open the file from Explorer, then my IThumbnailProvider is invoked.
2. If I permit open requests from Explorer, I see thumbcache.dll in the call stack trying to open the file and my IThumbnailProvider is not called. It appears that the default thumbnail provider reads the downloaded file and creates the thumbnail.
I must be missing something.
Update: if I use InitializeWithStream instead of InitializeWithFile, it appears my handler is invoked. But, that also triggers a download of the file.
There are many shell extension types which can access to your files. Icon handler can read file to create icon, Info tip handler can read file to create text hint, Data object handler can read file to create clipboard data and so on.
Questions from developer with the same problem: first and second. Solution was to create namespace shell extension. NSE can control all access to your files.

Changing default program for a file type (workaround)

I would like to specify that images of a certain type (for example, .png) open by default in a program I've written when the file is contained in a certain directory. I've seen by searching (Change Default Program for a specific folder) that this is not possible on Windows 7 or 8.
I am saving these images in this directory myself, so I have some leeway with how I name the files. For example, I could change the filename a bit... perhaps to be example.myprog.png or something similar. Is there a way to set it up so files that match this filename pattern get opened, while other .pngs (in other directories) still open in the default viewer?
I don't really want to name these PNG images example.myprog (i.e., fully change the extension), because when the user is browsing the directory in Windows Explorer, I would like the thumbnail images to still show up. Also, users will be eventually transferring these images to their own machines, where they'll want to use standard image viewers to look at them.
If this is not possible, does anyone have another suggestion for how to tackle this problem?
As you are mentioning that files should be opened in a program that you have written, try to change the code of your program to read files from the specific folder. So, by opening your program from anywhere in your pc, you should be able to open files from specified folder.

Windows API hook, custom save as file dialog to save directly to webserver via POST

I want to write a custom save as dialog that is hooked into the File -> "Save As" of most Windows program. This custom dialog will allow the user to enter their username, password, destination folder and uploads the file to the web server via a POST. If the user clicks cancel, it will call the original file dialog.
I've been reading up about Windows API hooking and this is vaguely how I think I would approach this:
Intercept "Save As"
Display my custom dialog, return some temporary path on the drive
Let the program write file to the temporary path, assume it calls WINAPI CreateFile(...) for now
Read the temporary file and upload to web server
Clean up temporary file
But I still can't get my head around the steps required to pull this off. Assuming I can intercept the "Save As" and CreateFile function, how do I detect the CreateFile was called from a "Save As" and not just any random file creation? I can think of a hack where I keep track of the time difference of when the File dialog got open and CreateFile got called.
My alternative solution is to use the existing file dialog and create a special folder on the disk, that is constantly monitored. When a file gets written there it will call an external program that uploads the file. I haven't looked into how to do this yet. I suspect this is easier.
UPDATE
As a first baby step, I wrote a .NET task tray application that allows the user to enter their login details and a folder to monitor. Whenever a file gets dropped in there there it will upload to the web server. So far it seems to work. Now I just need to figure out how to add a nice shortcut to the left pane of the file dialog. Once that's done I think I got a solution I'm happy with.
There is no need to hook or patch anything. Create a shell namespace extension that supports IStorage::CreateStream and implements it by returning a stream that POSTs its data to the Web server. The user can then choose to save the file to your namespace extension in order to upload the file.
Hooking the standard save dialog requires you to inject a DLL into every running process and have it replace the import stub of the the Win32 API GetSaveFileName() function in the process's PE header (something anti-virus and anti-malware apps are not likely to be happy about).
Then there is the new-style save dialog that was introduced in Vista using the new IFileSaveDialog COM interface instead of GetSaveFileName(). For that, you would have to uninstall and replace Microsoft's default FileDialog COM object with a custom implementation.
That does not count custom-made save dialogs, which you are not likely to hook.
If, by some miracle, you can hook the dialog and have it return a custom path of your own creation, you don't need to hook CreateFile() itself, Just monitor the folder that you create for your purposes. Place it where it is unlikely that any other app (or user) besides you will write files to. You can create a custom subfolder in the user's or system'ss AppData folder for that purpose. You can use SHGetSpecialFolderPath() and/or SHGetKnownFolderPath() to find those folders.
The tricky part will be detecting when the file is finished being written to and has been closed. You will have to monitor the folder for changes, such as with ReadDirectoryChangesW() or SHChangeNotifyRegister(), and periodically open new/modified files for exclusive access. If a file is still open by someone else, you won't be able to open it yourself. But once you do open it, you can do whatever you want with it.

Resources