I am trying to implement file security for my virtual drive. To do that I enable the GetFileSecurity and SetFileSecurity callbacks by calling SetOnGetFileSecurity and SetOnSetFileSecurity.

In my initial try at this I coded up these callbacks as stubs that actually did absolutely nothing except the return statement. In the debugger I saw that the stubs were actually called and the input parameters were as I would expect them to be.

The problem I encountered was when I tried to save a Word document I got the Windows error message that is shown in the attached file and therefore at the bottom of this post.

This error does not occur when saving just normal text files using Notepad, it seems to be an error that is specific to Word. It also doesn't occur if I remove the calls to SetOnGetFileSecurity and SetOnSetFileSecurity. It seems odd to me that an error would occur when the callbacks do absolutely nothing.

I've also coded the callbacks to do things like set up Windows security descriptors, etc. and those callbacks all seem to do the right things, and by that I mean that when I right click my virtual file and click on the Properties, Security Tab I see the correct permissions that I am expecting to present. But, even in those cases this Word error still occurs.

I thought it might be a permissions issue where I wasn't setting the security descriptor correctly and not setting it at all in the case of the stub callbacks, but again the one where I do set the security descriptors seems to present the correct permissions, and moreover when saving a text file the error doesn't occur no matter what the permissions are. Also, I know that Word creates some files that it later deletes in the background, so I thought that could be the issue. It is true that one of those files, the one with the ~$ at the beginning of the file name, doesn't get deleted when I encounter the error, the way it would when the error doesn't occur. So, I went directly to my database and set the permissions on that file to allow deletion by my user, but that didn't solve the problem. When I did that I also ran everything under the debugger and I saw the calls to GetFileSecurity and they were setting the security descriptor correctly.

So, this whole thing is very puzzling to me and I would appreciate some help with it. Thank you very much.

Try the Mapper sample with the OnGet and OnSetFileSecurity callbacks enabled. By default they just call the system APIs SetFileSecurity and GetFileSecurity. It should be enough for correct security handling, but only if the ___root___ folder of another NTFS formatted disk is mapped (mirrored) in Mapper. The root folder must be mapped because of inherited attributes (inherited from the parent folder). I.e. for example if you map/mirror the "C:\1" folder then its obtained security attributes (via the system API GetFileSecurity) will be security attributes for your CallbackFS virtual disk ___root___ folder (which is "\"), but this is not what Windows expect for root folder (because the "C:\1" folder has its own attributes plus attributes which are inherited from the parent folder).
Actually you can then check what GetFileSecurity returns and implement your own security handling.

Thank you, Eugene and Vladimir. After investigating this further I determined that the problem was caused by something in my database system and once I corrected that my callbacks worked and Microsoft Word also did what it was supposed to do. So, I am happy again, Thanks again for your help.

Vladimir, I wondered if you could be so kind as to explain your answer above a little further. What exactly do you mean by "map" the "C:\1" folder?

My application just mounts a drive. I call it the "X:" drive. The files on the "X:" drive are not really files in Windows but instead they result in queries to my database system that result in displaying "pseudo-files" in Windows Explorer that can then be opened and edited just like as if they were real Windows files.

I want to implement security for these "pseudo-files" by using the security mechanisms that my database system provides. Like Windows we have ACLs and inheritance and all the similar structures that Windows has for its files. But, remember, since these are not really Windows files we do not have a Windows Handle for them, i.e. what you would get back from the Windows CreateFile API if you used that to create the file, which we do not do.

So, I cannot use the SetFileSecurity or GetFileSecurity APIs to get any sort of security information about my "pseudo-files" because Windows knows nothing about them. What happens is that when you right click the file in Windows Explorer and then click on the "Security" Tab, Windows fires off your OnGetFileSecurity event and I get control in the callback. I then construct a Windows Security Descriptor from the information that I obtain from my database system about the "pseudo-file" and pass that SecurityDescriptor back to Windows, which the displays the permissions on the "pseudo-file" exactly the way I want it to. This all works fine. I can even modify permissions, owner, and group information for my "pseudo-files", just the way I want to. As far as I understand it, I have not done the "mapping" that you talk about above.

The problem I am having is that when I display the security information for a "pseudo-folder", which in my database system is called a "collection", the information is displayed the way I want it, but if I try to modify it, the modification works the way I want it to, but Windows presents an error screen and claims that the security information was not changed. I believe that error is coming from the fact that Windows is trying to propagate the changed security information to objects within the "pseudo-folder" that Windows thinks should be inheriting the information and of course Windows knows nothing about those objects, so it gets somehow bent out of shape.

Because this has to do with inheritance, I thought what you said above might have some relevance for me, but I really do not understand your comments too well. Maybe you can elaborate on them for me with an example, or point me to one of your samples that does what you are talking about. Thank you in advance for any help you can give me, I really appreciate all the help you have given me in the past.

Forget about "C:\1" and your application for a while and try to map your disk C: using Mapper sample to a virtual drive. When using Mapper, uncomment security-related callbacks in it.

With the above you should get a working virtual drive with security supported.

Now start adding your security manipulations to Mapper sample. You can manipulate objects in some C:\TemporaryFolderForSecurity in order not to spoil the actual data on the disk. Instead of propagating security functionality to Windows API for files in this folder employ your custom mechnisms.

Debug your changes in the Mapper sample. Then you can move them to your real application.

Please note, that CBFS knows nothing about internals of security data blocks that you and the OS are passing to each other, so we can not help you with security descriptors etc. . We can only suggest how to easier debug this part of the code.

I debugged the program using a version that is basically your mapper sample with my callbacks.

I found one error that was causing the Windows error that I was seeing before, so I fixed that error in the version that uses the Mapper sample and it worked fine. But when I put that fix into my code I still get a Windows error, but this time it is "Access denied", which is a different error than I was getting before. The callbacks in my version of the code run in a service that I create, so they run under the Windows SYSTEM user (\NT AUTHORITY\SYSTEM), while in the mapper sample you are running as the logged in user. I can't imagine why the SYSTEM user would have less access to one of my pseudo-files than the logged in user does, but this seems to be the problem.

Indeed the account under which services work by default is more restricted in certain aspects than the logged in account. You can check whether the account is the reason by running your service under your account and seeing whether the problem exists.

OK, I have something that is definite. I determined that the difference between my code and your mapper sample is that I add my mount point as a network mount point and the mapper sample does not. The following code snippet is what I use to add my mount point

The really odd thing about this is that when I put the same exact code into the mapper sample and mount the drive I get a CbFsException that says "Invalid parameter value". This does not occur when I have the same code in my code. This leads me to believe that I have some wierd versioning problem, where my code is getting a different version of the CbFs libraries than the mapper sample?

We use cookies to help provide you with the best possible online experience. By using this site, you agree that we may store and access cookies on your device. You can find out more about and set your own preferences here.