Coder Social home page Coder Social logo

Comments (19)

Dijji avatar Dijji commented on June 9, 2024

[Dijji@02/10/2015]
Hi Thomas

Very interesting. I had considered chaining in the past, but never from this angle. I have always been hooked on the idea of giving the existing handler priority, because it stored the properties in-document, and therefore gave better portability. So my schemes involved writing first to the original handler, and only if that failed to the File Meta handler. But there are in fact some serious problems with this approach, which brought me stumbling to a halt.

Your scheme avoids the issues that blocked me by always writing only using the File Meta handler. The original handler is effectively used only to provide property values in the cases where the File Meta handler does not already have one.

You are still vulnerable to another worry that I had, which is a consequence of tweaking the registry. If the original handler was set up by a software installation (e.g. a PDF package), and its handler is subsequently chained, a potentially ugly situation can arise if the software that provided the original handler is then uninstalled. What we want is for the handler to be unchained, and for the extension to be handled only by the File Meta handler. But what we will actually get is the uninstallation attempting to remove the property handler that it installed from the registry. It might, for instance, remove the property handler reference from the extension, without noticing that it is no longer its own property handler. We also have to worry about being left trying to chain to a handler that is no longer on the system.

I don’t think that this is an insuperable issue, but I do think it needs some careful thought.

One more thought arising from your approach. Since the properties that are held in the document are read-only once chaining has occurred, can we instead copy all the values into File Meta metadata and mostly avoid the chaining mechanism at runtime altogether? Suppose we invent a custom marker that we write into an alternate stream to say that properties have been harvested from a file. Then, we only need to instantiate the chained property handler in cases where the marker is missing, at which time we simply iterate over all available properties and copy them.

Should there are also be a mechanism for copying metadata back into the body of the file for another form of portability? This could be done from the Metadata context menu.

Dijji

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[ThomasGat@02/10/2015]
Hi Dijji,

Thanks for your comments.

You’re right about the issue with uninstalling an original handler that has been replaced & chained with the File Meta handler. However, it doesn’t seem to be a big problem for the following reasons: We can’t know what an uninstaller does when it finds the current handler different than the original handler that it wants to uninstall. It can either remove the registration, or leave File Meta handler’s registration intact. Just in the first case, the user would need to re-run the association manager application and restore the handler registration. Also the likely orphaned entry in File Meta’s registry structure of chained handlers doesn’t cause problems either; the GUID will point to a COM object that isn’t available anymore (CoCreateInstance will fail). The patch code should supports this situation gracefully and behave just as if no chained handler is registered (_pChainedPropStore is NULL).

I can also imagine to have a utility application with File Meta that detects these issues, and automatically fixes them, e.g., detect when a File Meta handler registration has been removed without File Meta’s association manager, and restore it. And also it’s possible to detect when a chained handler GUID does no longer refer to something that CoCreateInstance could create. In that case, simply deleting this entry would fix it.

Regarding my design to treat chained property handlers as read-only: The idea was to keep both the implementation as well as the behavior simple and easy to understand: When File Meta is registered for a file type, it handles all writable properties, and the file (in NTFS terms: the main data stream) never gets modified. So it doesn’t pass any properties to the chained handler for writing. On the other hand, as I’ve mentioned before, I use my extension of File Meta with video files of type .mpg, .ts, etc.. The system property handlers for these types don’t support any writable properties, so I did never run into that situation anyway.

Thinking about this, maybe it is best when File Meta does not allow to chain a handler that supports writable properties, or it should at least explicitly warn about doing this. For example, the system’s .jpg handler supports some writable properties, the .gif handler doesn’t (AFAIK). It wouldn’t cause any problems to replace and chain the .gif handler, but the .jpg handler should not be replaced, or only at the user’s explicit confirmation.

Regarding copying all the values into File Meta metadata, I don’t think it will work. The system property handlers extract the values that they return as properties from the file content, and this content can change at any time, without File Meta’s knowing. E.g., consider we harvest the image dimension of a .gif file, and later the file’s content is updated with an image using different dimension. The File Meta metadata would not know about that, but the original system property handler reads that from the file, and returns the correct dimensions. Therefore I think it should always ask the original property handler. (Unless a value has been written in File Meta’s metadata – this one will override the original property handler’s value. However, that should not apply to read-only properties like the image dimensions in this example.)

Br,
Thomas

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[Dijji@04/10/2015]
Hi Thomas,

Good. I think we can agree that the installation conflict issues are probably soluble, so let’s set them aside for now.

I also think that you are right in that the key is writable properties. Now, in File Meta to date, a property is writable if it appears in the profile, i.e. Full Details or Preview Details. So I thought I would have a look at what Windows configures for one of the extensions we are interested in. Here are the Preview Details for .mpg on my Windows 7 system:

"PreviewDetails"="prop:*System.Title;*System.Media.Duration;*System.Size;*System.Video.FrameWidth;*System.Video.FrameHeight;System.Rating;*System.Keywords;*System.Comment;*System.Music.Artist;*System.Music.Genre;*System.ParentalRating;*System.OfflineAvailability;*System.OfflineStatus;*System.DateModified;*System.DateCreated;*System.SharedWith;*System.Media.SubTitle;*System.Media.Year;*System.Video.FrameRate;*System.Video.EncodingBitrate;*System.Video.TotalBitrate"

I was surprised to see entries for Rating, Comment and Keywords (tags). But the implication is, that if these properties had values, they would show up in the preview pane. And the properties do indeed turn up under the details tab of properties. But they show there as read only. Why?

I have speculated in the past that it was to deal with the asterisk prefixing the property name, but I have edited the registry values to remove it, and it makes no difference.

Digging around further, I came across this: http://blogs.msdn.com/b/benkaras/archive/2006/11/14/the-deal-with-ipropertystorecapabilities.aspx . As it says, “We needed a way to mark which properties are writable and which aren't … So we invented IPropertyStoreCapabilities to let a property handler declare what properties it supports and those it doesn't. For example, the PNG property handler uses IPropertyStoreCapabilities to tell explorer that it supports writing System.Photo.DateTaken, but nothing else.”

IPropertyStoreCapabilities turns out to have only one method, IsPropertyWritable: you pass it a property key, and it returns true or false. The interesting characteristic for us is that you can only get this answer at runtime: you open a specific Property Store, then ask for this interface. Thus, we would need at least an instance of a file type to discover what properties could be written. And there is no guarantee that the same answer for a given property will be returned for different .mpg files, though this seems most likely in cases where a single handler supports multiple generations of a file format.

So, suppose we figure out using this interface that .mpg files do not have a writable Comment property, and therefore write it instead using the File Meta property handler. Now let’s consider the .gif file. It’s Preview Details look like this:

"PreviewDetails"="prop:*System.DateModified;*System.Image.Dimensions;*System.Size;*System.OfflineAvailability;*System.OfflineStatus;*System.DateCreated;*System.SharedWith"

Now, I think Windows Explorer will never ask us about file system properties like Date Modified or Size: it doesn’t look to the property handler for these values, but only for values which interpret the content of a file, like System.Image.Dimensions. That one, we do need to handle. And, using the same procedure, using IPropertyStoreCapabilities with a.gif file, we would find that it is read-only.

But in this case, we do not want to allow the value to be edited and stored using the File Meta property handler, because it is an intrinsic reflection of the contents of the file, and it would make no sense. But how do we know that? It looks in all regards exactly the same as the Comment property did on the .mpg file.
I don’t have an answer to this one at the moment. Any ideas?

Dijji

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[ThomasGat@04/10/2015]
Hi Dijji,

That are good points. When I worked on that patch some time ago, I found the following:

Explorer allows editing of a property when a) the property store says it is writable and b) when the property description says the property is not innate (isInnate = false). Regarding a), this can either be done by the handler supporting the IPropertyStoreCapabilities interface and returning true to the isPropertyWritable call (as you’ve mentioned), or by not supporting the IPropertyStoreCapabilities interface, in which case all properties are writable. This is the case for the File Meta handler.

For example: The standard property handler for .mpg files implements IPropertyStoreCapabilities that returns “not writable” for the System.Comment property. At the same time, the description for System.Comment specifies isInnate = false (https://msdn.microsoft.com/en-us/library/windows/desktop/bb760658(v=vs.85).aspx and https://msdn.microsoft.com/en-us/library/windows/desktop/bb773889(v=vs.85).aspx). However, since the property store says it is a read-only property, explorer shows it as read-only.

Now, when I install the File Meta handler, and chain it with the standard property handler, explorer will query the File Meta handler for IPropertyStoryCapabilites, which does not support it. So the System.Comment property is assumed writable by the store, and writable by the property description, so explorer allows editing.

And this is exactly what I wanted: to be able to update the otherwise useless read-only and empty “Comments” property!

And the behavior is also correct for properties that are derived from the file, like the video image size or media duration: Here the property descriptions for these properties already indicate isInnate=true, and so explorer shows them as read-only in any case, with or without File Meta handler.

I can only suggest to try out the patch with some media files like .mpg or .gif, and see how surprisingly good it works out. 

Also from the above description it seems that yes, you are right, it is not possible to find if a property handler has writable properties without a file (or stream) instance. (It would be possible to find if a property is always read-only be looking at the property description, but that usually doesn’t help, because any one property will most likely have isInnate=false set, and thus be potentially writable.)

Hmm, I think that maybe the best is still to leave it as an expert option to the user who confirms that once the File Meta property handler is in place, then many additional properties can be assigned and existing ones are now writable instead of read-only, but changing these properties is a File Meta only operation, and not reflected in the file contents itself.

Br,
Thomas

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[Dijji@06/10/2015]
Hi Thomas

Very good. I didn’t know about isInnate .

So it seems that Explorer considers a property writable if: isInnate is false, and the property handler either does not implement IPropertyStoreCapabilities or IsPropertyWritable returns true. Assuming this to be correct, your original patch is still looking viable, and in the examples we have looked at it does indeed hold up well.

It seems to me that the next step is to verify more broadly, with both Microsoft and third-party handlers if possible. I should be able to look over the next few days are writing a program to scan my systems and predict what properties will show up as writable, so that I can crosscheck against what actually happens in Explorer.

Once we are solid there, the only other topic that I can think of will be how to support the creation of a profile for an extension that includes both the built in Full Details and Preview Details, and also additional writable properties as desired.

Dijji

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[Dijji@08/10/2015]
Okay, I have surveyed the extension configurations that come with my (Windows 10) system.

To qualify, an extension had to appear under HKCR\SystemFileAssociation with at least a value for FullDetails, and also had to have a property handler defined. There turned out to be 114 extensions that met these criteria.

For each of them, I read the Full Details and Preview Details values, then checked each property to see if it was marked with fInnate. The attached spreadsheet, patch.csv, shows the results.

The Excess column is the count of properties that appear in Preview Details, but not Full Details. Innate properties are not listed in the columns breaking out the Details. It follows that the properties shown should be exactly those that would be writable with your patch as is.

I then went on to look at IPropertyStoreCapabilities. I invoked IsPropertyWritable on the configured property handler for every non-innate Full Details property of three sample extensions (.fon, .gif and .mpg), and found, to my surprise, that every single one of them reported that it was writable.

That led me to check whether I could in fact read and write the System.Comment property on an.mpg file. It turned out that I could read it, though the value was empty, but an attempt to write it was rejected with Access Denied.

Have a look and let me know your thoughts.

Dijji

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[UnknownUser@08/10/2015]

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[Dijji@08/10/2015]
patch.csv

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[UnknownUser@09/10/2015]

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[ThomasGat@09/10/2015]
Hi Dijji,

I tried to reproduce your results about the .mpg property handler, and that its IPropertyStoreCapabilities interface returns non innate properties as writable. I created a small test program (source, exe and test files attached here as prop1.zip); it has property handler GUIDs and the files it tests hardcoded, to simplify reproducibility. I used two mpeg-2 files, and two mpeg-4 files – they have different property handlers. To test the impact of the file itself, for each type there is a valid file (“white.”) and an empty, zero byte file (“empty.”). The output shows:

  • Is the System.Comment property in the property store?
  • When the IPropertyStoreCapabilities interface is supported, is the System.Comment property given as writable?
  • What’s the value of the System.Comment property?

The result when running the exe is this:

D:\Prop1>Release\Prop1.exe

File: empty.mpg
Property Handler: {1E589E9D-8A8D-46d9-A2F9-E6D4F8161EE9}
System.Comment : Property is NOT in the property store.
System.Comment : IsPropertyWritable = no
System.Comment : Value is empty.
// Windows Explorer: Property is read-only.

File: white.mpg
Property Handler: {1E589E9D-8A8D-46d9-A2F9-E6D4F8161EE9}
System.Comment : Property is NOT in the property store.
System.Comment : IsPropertyWritable = no
System.Comment : Value is empty.
// Windows Explorer: Property is read-only.

File: empty.mp4
Property Handler: {f81b1b56-7613-4ee4-bc05-1fab5de5c07e}
System.Comment : Property is NOT in the property store.
System.Comment : IsPropertyWritable = yes
System.Comment : Value is empty.
// Windows Explorer: Property is read-only.

File: white.mp4
Property Handler: {f81b1b56-7613-4ee4-bc05-1fab5de5c07e}
System.Comment : Property is NOT in the property store.
System.Comment : IsPropertyWritable = yes
System.Comment : Value is empty.
// Windows Explorer: Property is writable.
 
File: white2.mp4
Property Handler: {f81b1b56-7613-4ee4-bc05-1fab5de5c07e}
System.Comment : Property is in the property store.
System.Comment : IsPropertyWritable = yes
System.Comment : Value = Hello!
// Windows Explorer: Property is writable.

File: empty.mpg
Property Handler: {60211757-EF87-465E-B6C1-B37CF98295F9}
System.Comment : Property is NOT in the property store.
System.Comment : IPropertyStoreCapabilities interface NOT supported.
System.Comment : Value is empty.
// Windows Explorer: Property is writable.

I’ve added the lines with “//” to show the behavior of the details tab in the file properties shown by Windows explorer.
The white2.mpg file is a copy of the white.mpg file with the “comments” property edited to “Hello!”
The last entry is the empty.mpg file with the File Meta handler, chained with the original handler.

The result differs from your findings in the standard .mpg property handler: It does return S_FALSE (“The property cannot be edited.”) for properties like System.Comment, regardless if the file is invalid (empty) or valid. I tried it with Windows 10 and 8.1, and got the same results.

Anyway, the result is that the IPropertyStoreCapabilities interface is likely not useable for the File Meta properties association manager to statically distinguish read-only from writable properties. Also it dynamically depends upon the file that was used to initialize the property store.

Still, I think that it might be the best to leave it as an expert option. When the users selects the File Meta handler for a file type (that has some other, existing property handler), it should be noted that for the time the File Meta handler is installed, all changes of properties are stored in the File Meta store. And when the File Meta handler is removed, the previous metadata of files is shown again. I think it is more a question of explaining, documenting and notifying the user of the behavior, than an implementation issue. And on the other hand, the same problem exists already today: When the user registers the File Meta handler for some file type, e.g., .pdf, and then later install a software that overwrites the File Meta handler with its own. At that point, the properties that the user might have set to such files are changed to the original software ones, unless the user overwrites that handler again. Only that today it is not possible without chaining.

What do you think?

Br,
Thomas

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[Dijji@12/10/2015]
Hi Thomas

I’m not actually much of a believer in ‘expert’ options. I would much rather try and think things through so that the experience is ‘it just works’ wherever possible. Having been first line support for this project since its inception, I’m very aware that if you offer opportunities for getting into trouble, you should not be surprised when someone does.

Your code runs on my machine with the same results, which I think are definitive. I also played around applying your code to .gif files, with consistent results:

File: C:\Testtags\ext\3dlogo.gif
Property Handler: {a38b883c-1682-497e-97b0-0a3a9e801682}
System.Comment : Property is NOT in the property store.
System.Comment : IsPropertyWritable = no
System.Comment : Value is empty.

File: C:\Testtags\ext\3dlogo.gif
Property Handler: {a38b883c-1682-497e-97b0-0a3a9e801682}
System.Image.Dimensions : Property is in the property store.
System.Image.Dimensions : IsPropertyWritable = no
System.Image.Dimensions : Value = ?125 x 125?

So, where does all this leave us? As you say, IsPropertyWritable does not seem to give us any useful results. The best bet appears to be your original patch, relying upon Windows Explorer to render Innate properties as read-only (we don’t want the overhead of looking up the property description in the property handler methods). I do have a question mark about GetCount cases where a property appears in both File Meta and the chained handler, and so is counted twice and will return two potentially different values, depending on the index you use. Is that reasonable?

Otherwise, the biggest undiscussed aspect remaining is configuring Full Details and Preview Details. In some cases, like .mpg, the pre-existing settings will work fine. In others, like .gif, the standard settings contain nothing useful and so will need to be extended. Given that we will want to keep displaying Innate properties, a custom profile per chained extension will be needed.

The main work items remaining are implementing this, and the defences against installation and uninstallation issues.

Do you agree with this assessment?

Dave

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[ThomasGat@14/10/2015]
Hi Dijji,

Yes, I fully agree!

The configuration manager would need to support this for chained property handlers:

  • Replace the existing handler GUID. Both in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers, as well as in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\SystemPropertyHandlers, with all the difficulties of getting write access there as I described before.
  • Store the old handler GUID in the HKEY_LOCAL_MACHINE\SOFTWARE\FileMetadata\ChainedPropertyHandlers structure.
  • Undo the above in case the user deselects the File Meta handler in the chained handler case. At that time it would be good to check if the chained handler still is instantiable.
  • Configure Full Details and Preview Details. Likely this is the largest part. IIUC, the configuration manager assigns a property profile at the time the File Meta handler is installed, and you can choose from built-in and custom profiles. For chained property handler, it should support the chained (original) property profile too, including cloning and editing, but only for the specific extension, right? Alternatively it could use the profiles in the same way as it does today, but add them to the original properties. For example, if you would use the “Simple” profile with .mpg, you’d get the settings of that profile for Full Details and Preview Panel, appended and merged with those settings the system has already defined for .mpg. What do you think?

Regarding the GetCount/GetAt,

I do have a question mark about GetCount cases where a property appears in both File Meta and the chained handler, and so is counted twice and will return two potentially different values, depending on the index you use.

AFAIK, this is no problem: The IPropertyStore::GetCount and IPropertyStore::GetAt methods provides an abstraction over an array of property keys, not values. In other words, GetAt – and that is the only method working with such an index as input – does not give you the value of property at index x, but the property key you would use with IPropertyStore::GetValue when getting the value. In our case, that means that the same property key appears twice in the array, or, in other words, you would get the same property and same value from two indexes x and y. There seems to be no specification or API contract that disallows this – albeit unusual – behavior.

Br,
Thomas

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[Dijji@17/10/2015]
Hi Thomas

On the question of setting up a profile for a chained extension, I think I would create a new custom profile for each extension, named after that extension. This would be initialised as a copy of the system profile for the extension, which the user could then modify. One way to modify it would be to copy and paste another profile onto it: this would have the effect of copying any properties that were in the source profile, but not the target profile, into the target profile, in a way analogous to copying one file folder onto another.

It seems that this issue is now ready for work to be started, so I will mark it as assigned to me for delivery in 1.4. It will probably take me a little while to actually get to this, however, as I have some other work in progress at the moment. Are you interested in participating yourself? Do not feel under any pressure to do so: you have already been very generous with your time, for which I thank you very much.

Dijji

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[UnknownUser@17/10/2015]

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[UnknownUser@17/10/2015]

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[UnknownUser@07/12/2015]

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[UnknownUser@19/10/2016]

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

[UnknownUser@19/10/2016]

from filemeta.

Dijji avatar Dijji commented on June 9, 2024

Issue closed by Dijji with comment
Addressed in version 1.4

Reason closed
Fixed

from filemeta.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.