How to create a software-implemented drive - winapi

There are some applications (let us call them providers), which (when running) provide a virtual file and directory structure under a new drive letter. Access requests from other processes to those files and directories are served by the provider.
One example of such provider could be the Google Drive for Windows (the new one, not the old Backup and Sync), which maps the contents of your Google Drive to a chosen drive letter.
I thought there should be some simple user-mode API, which should allow my app to provide a new drive and the contents of files and directories on it. I thought that many applications use such API, but I cannot find it. The closest I could get are IFS (installable file system drivers) and file system filter drivers, but those are kernel-mode and they seem too complex. They just seem not designed to accomplish such task.
So, what API should I use to make a simple software-implemented drive?

In addition to the suggestions in the comments there is also now the Projected Filesystem, which allows software to provide a drive-like interface though callbacks and not just by creating an actual disk image. It is my understanding that Projected FS is how, for instance, SQL Server does its table-backed files interface.

Related

How can I automate no, partial and full hydration of "cloud" files (OneDrive) for testing?

I would like to test some software and would like to make it well-behaved regarding cloud files. For reference functions like RtlIsPartialPlaceholder and RtlIsCloudFilesPlaceholder have been introduced in order to look at the information returned when traversing the folder hierarchy. The above links point to kernel mode documentation, but these functions also exist in user mode (ntdll.dll) and they are really implemented very trivially.
However, in order to test said software I would have to be able to somehow create the states a placeholder for a file on OneDrive can be in.
What functions (registered COM classes would also be fine) can I use to automate creation of a reproducible test set up which I can use to:
create placeholders
only partially hydrate a placeholder
achieve the same for both directories and files
PS: this question was the only one remotely connected to the topic, which I was able to find here on SO.
Standard file/directory operations (create/read/write, etc.) can be achieved transparently using the Win32 API. That's the whole point of this technology.
So, you can create a placeholder using the standard Win32 APIs.
If you create a file or directory in a "sync root" (like in the OneDrive folder hierarchy in the OneDrive case), the associated sync engine process (like OneDrive.exe) will ensure the file or directory is a placeholder. And you can't create a placeholder outside of a sync root hierarchy, AFAIK.
For a file (you can't hydrate or dehydrate a directory), reading/writing correspond to hydration. Note that some sync engines (and/or depending on their configuration) can decide to always fully hydrate a file even if only some bytes were asked by the end-user API (applications).
There are some specific Win32 APIs though for special operations.
You can dehydrate a file using CfDehydratePlaceholder. You can hydrate a file CfHydratePlaceholder. For all the Cloud Filter API, when creating directory handles, don't forget to use the FILE_FLAG_BACKUP_SEMANTICS flags.

How to detect Windows file closures locally and on network drives

I'm working on a Win32 based document management system that employs an automatic check in/check out model. The model it currently uses for tracking documents in use (monitoring the processes of the applications that open the documents) is not particularly robust so I'm researching alternatives.
Check outs are easy as the DocMgt application is responsible for launching the other application (Word, Adobe, Notepad etc) and passing it the document.
It's the automatic check-in requirement that is more difficult. When the user closes the document in Word/Adobe/Notepad ideally the DocMgt system would be automatically notified so it can perform an automatic check in of the updated document.
To complicate things further the document is likely to be stored on a network drive not a local drive.
Anyone got any tips on API calls, techniques or architectures to support this sort of functionality?
I'm not expecting a magic 3 line solution, the research I've done so far leads me to believe that this is far from a trivial problem and will require some significant work to implement. I'm interested in all suggestions whether they're for a full or part solution.
What you describe is a common task. It is perfectly doable, though not without its share of hassle. Here I assume that the files are closed on the computer where your code can run (even if the files are stored on the mounted network share).
There exist two approaches to controlling the files when they are used: the filter and the virtual filesystem.
The filter sits in the middle, between the process and the filesystem (any filesystem, either local, network or fully virtual) and intercepts file requests that go to this filesystem. Here it is required that the filter code is run on the computer, via which the requests are passed (this requirement seems to be met in your scenario).
The virtual filesystem is an endpoint for the requests that come from the applications. When you implement the virtual filesystem, you handle all requests, so you always fully control the lifetime of the files. As the filesystem is virtual, you are free to keep the files anywhere including the real disk (local or network) or even in the cloud.
The benefit of the filter approach is that you can control individual files that reside on the real disks, while the virtual filesystem can be mounted only to the new drive letter or into the empty directory on the NTFS drive, which is not always fisible. At the same time, sitting in the middle, the filter is to some extent more restricted at what it can do, and the files can be altered while the filter is not running. Finally, filters are more complicated and potentially error prone, as they sit in the middle and must play nice with other filters and with endpoints.
I don't have specific recommendations, but if the separate drive letter is an option, I would recommend the virtual filesystem.
Our company developed (and continues to maintain for the new owner) two products, CBFS Filter and CBFS Connect, which let you create a filter and a virtual filesystem respectively, all in the user mode. Those products are used in many software titles, including some Document Management Systems (which is close to what you do). You will find both products on their website.

How to start VbScript if someone access on my extern hard disk

i have an extern hard disk connected with my router. Now everyone in my homenetwork have access to the external hard disk. Is it possible to start an vbscript if someone access my external hard disk?
regards
There are ways to do this but they require that you change your design a little. The easiest way, would be to redirect the access of your external drive through a file server. (It could just be a Windows desktop).
Remove the share access from your external hard drive for everyone except your File Server, create a share on the file server that connects to this external drive, and have everyone use the hard drive through the share on the File Server.
Then you can get creative with scripts that monitor share usage like the link in
this example.
This comes with the drawback that your file server will need to be on in order for the hard drive to be accessible.

Very low disk access in Windows -disk.sys api

I'm looking for some documentation/clues about how would it be possible to read a disk in Windows without the using CreateFile() on a volume. For example the standard files functions only give an access to formated disk.
Is there any kind of documentation about the driver disk.sys such as an export list, functions prototypes etc ?
Would the direct use of the driver be the right approach ?

Windows Registry best practices

In what way is the Windows registry meant to be used? I know it's alright to store a small amount of user preferences, but is it considered bad practice to store all your users data there? I would think it would depend on the data set, so how about for small amounts of data, say, less than 2KB, in 100 or so different key/value pairs. Is this bad practice? Would a flat file or SQLite db be a better practice?
I'm going to take a contrarian view.
The registry is a fine place to put configuration data of all types. In general it is faster than most configuration files and more reliable (individual operations on the registry are transacted so if your app crashes during a write the registry isn't corrupted - in general that isn't the case with ini files).
Marcelo MD is totally right: Storing things like operation percentage complete in the registry (or any other non volitile storage) is a horrible idea. On the other hand storing data like the most recently used files is just fine - the registry was built for just that kind of problem.
A number of the other commenters on this post talking about the MRU list have discussed the problem of what happens when the MRU list gets out of sync due to application crashes. I'm wondering why storing the MRU list in a flat file in per-user storage is any better?
I'm also not sure what the "security implications" of storing your data in the registry are. The registry is just as secure as the filesystem - the registry and the filesystem use the same ACL mechanism to protect their data.
If you ARE going to store your user data in a file, you should absolutely put your data in %APPDATA%\CompanyName\ApplicationName at least - that way if two different developers create an application with the same name (how many "Media Manager" applications are there out there?) you won't have collisions.
For me, simple user configuration items and user data is better to be stored in either a simple XML configuration file, a SQLLite db, or a MS SQL Server Compact db. The exact storage medium depends on the specifics of the implementation.
I only use the registry for things that I need to set infrequently and that users don't need to be able to change/see. For example, I have stored encrypted license information in the registry before to avoid accidental user removal of the data.
Using the registry to store data has mainly one problem: It's not very user-friendly. Users have virtually no chance of backing up their settings, copying them to another computer, troubleshooting them (or resetting them) if they get corrupted, or generally just see what their software is doing.
My rule of thumb is to use the registry only to communicate with the OS. Filetype associations, uninstaller entries, processes to run at startup, those things obviously have to be in the registry.
But data that is for use in your application only belongs in a file in your App Data folder. (whiever one of the 3+ App Data folders Microsoft currently wants you to use, anyway)
As each user has directory space in Windows already dedicated to storing application user data, I use it to store the user-level data (preferences, for instance) there.
In C#, I would get it by doing something like this:
Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData);
Typically, I'll store SQLite files there or whatever is appropriate for the application.
If your app is going to be deployed "in the enterprise", keep in mind that administrators can tweak the registry using group policy tools. For example, if firefox used the registry for things like the proxy server, it would make deployment a snap because an admin can use the standard tools in active directory to set it up. If you use anything else, I dont think such things can be done very easily.
So don't dismiss the registry all together. If there is a chance an admin might want to standardize parts of your configuration across a network, put the setting in the registry.
I think Microsoft is encouraging use of isolated storage instead of the Windows registry.
Here's an article that explains how to use it in .Net.
You can find those files in Windows XP under Documents & Settings\\Local Settings\ App Data\Isolated Storage. The data is in .dat files
I would differentiate:
On the one hand there is application specific configuration data that is needed for the app to run, e.g. IP addresses to connect to, which folders to use for what sort of files etc, and non trivial per user settings.
Those I put in a config file, ini format for simple stuff, xml if it gets more complex.
On the other hand there is trivial per user settings (best example: window positions and layout). To avoid cluttering the config files (which some users will want to edit themselves, so few and clearly arranged entries are a must), I like to put those in the registry (with conservative defaults being set in the app if no settings in the registry can be found).
I mainly do it like istmatt sais: I store config files inside the %APPDATA% folder. Usually in %APPDATA%\ApplicationName, I don't like the .NET default of APPDATA%\CompanyName\ApplicationName\Version, that level of detail and complexity is counterproductive for most small to medium sized applications.
I disagree with the example of Marcelo MD of not storing recently used files in the registry. IMO this is exactly the volatile sort of user specific information that can be stored there.
(His example of what not to do is very good, though!)
To me it seems easier to think of what you should NOT put there.
e.g: dynamic data, such as an editor's "last file opened" and per project options. It is really annoying when your app loses sync with the registry (file deletion, system crash, etc) and retrieves information that is not valid anymore, possibly deadlocking the user.
At an earlier job I saw a guy that stored a data transfer completness percentage there, Writing the new values at every 10k or so and having the GUI retrieve this value every second so it could show on the titlebar.

Resources