TurboPack / MustangpeakVirtualshellTools

Delphi and CBuilder Components to create Explorer type programs
Other
49 stars 24 forks source link

Problem with long paths > 256 characters #29

Open luebbe opened 1 year ago

luebbe commented 1 year ago

There seems to be a problem when paths longer than 256 characters are involved.

I have the classical combination of TVirtualExplorerComboBox and TVirtualExplorerTreeView to create a custom "File Open" Dialog. I can navigate to any directory in the long path fine using the explorer tree. TVirtualExplorerComboBox.Path returns the desired path and I can work with it (MyPath := TVirtualExplorerComboBox.Path) and store it away.

When I try to open this dialog in the same location by setting (TVirtualExplorerComboBox.Path := MyPath), this fails when MyPath has more than 256 characters.

In TCustomVirtualExplorerCombobox.SetPath(const Value: string);, the call to PIDL := PathToPIDL(Value); returns nil when a very long path is involved. This results in not being able to set the path.

Assigning to TVirtualExplorerComboBox.Path, it doesn't make a difference whether the value is UNC/non UNC or whether it uses the extended prefix \\? or not.

Is there a way to initialize TVirtualExplorerComboBox in a path with more than 256 characters?

romankassebaum commented 1 year ago

Are you on the master or on the Cache branch? Do you have a test project?

luebbe commented 1 year ago

I am on the master branch, but just noticed that it is a quite old version from around January this year. I will first update and see if the problem magically goes away. If not I'll try to reproduce it in a minimal example and attach it here.

luebbe commented 1 year ago

Here is an example that displays some of the problems. It shows less of them than my real-life application, so I have to find out, what the differences are. It is built using the head revision of all three MP libraries.

First of all you have to create a path longer than 256 characters. If you do this in the explorer by adding folder in folder in folder, windows will probably block you at some point and complain that the path is too long. In this case you can trick it into creating a longer path, by extending a folder name inside the path to make the total longer.

Example: C:\This\is\a\very\...\long\path with 255 characters. If you now try to add a new subfolder, windows won't allow it. But if you rename long to veryveryverylong you'll bypass the windows check. Result: C:\This\is\a\very\...\veryveryverylong\path with 255+12 = 267 characters.

ExplorerTree.zip

grafik

From the screenshot you can see that there is no problem navigating into the depths using the explorer tree. Once you get past the 256 characters, the path shown in the edit/memo switches to extended syntax.

Set Path does not work, when the path has extended syntax, no matter if it is longer or shorter than 256 characters. Set Path works, when the '\?\' is removed, no matter if it is longer or shorter than 256 characters.

Copy & pasting the path into the explorer combo box results in a '... can not be found by windows' error message if it is extended syntax or longer than 256 characters. Copy & pasting the path into the explorer combo box works if it is no extended syntax and shorter than 256 characters.

I tried the same stunt with a UNC path on a network share. You can also navigate into the depths. Here too the path returned by the combobox switches to UNC/extended once it passes the 256 characters, like \\?\UNC\fileshare\very\long\path\...\

Set Path was never succesful with a \\?\UNC prefix no matter if the path is longer or shorter than 256 characters Set Path was successful with a \\fileshare\not\so\long\path

romankassebaum commented 1 year ago

I can create a long path with the TotalCommander.

romankassebaum commented 1 year ago

PathToPIDL uses IShellFolder.ParseDisplayName. Maybe this method does not allow to work with the extended syntax. MSDN says: "ParseDisplayName is not expected to handle the relative path or parent folder indicators ("." or ".."). It is up to the caller to remove these appropriately."

luebbe commented 1 year ago

So this looks like I have to prevent the user from browsing into a path with > 256 characters. The problem is that he can select it once and everything looks fine. On the second try however, this path is used as default for the dialog, but the dialog doesn't show anything anymore.