[Fixed in 10.00 b2] Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Bug reports will be moved here when the described bug has been fixed

Moderators: white, Hacker, petermad, Stefan2

Post Reply
Rob Weinstein
Junior Member
Junior Member
Posts: 45
Joined: 2006-06-10, 21:41 UTC
Location: Arizona

[Fixed in 10.00 b2] Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *Rob Weinstein »

Hello,

First, this is NOT about Right-Drag from TortoiseSVN to perform versioned copies or moves. That works fine.

This is about Left-Drag to perform an "unversioned" copy from TortoiseSVN's Repository Browser to TC. This doesn't work in TC but it does work in Windows Explorer. Steps to reproduce:
  1. In TC, right-click a versioned file and use Context Menu -> TortoiseSVN -> Repo-Browser.
  2. In Repository Browser, navigate to any file and left-drag that file to an open panel in TC.
  3. As you are dragging, the cursor shows a plus sign.
  4. When you release the left button in TC, the filename appears in the TC panel, but the file size is 0. And the file is indeed empty.
Compare to Windows Explorer:
  1. With Repository Browser still open...
  2. In Repository Browser, navigate to any file and left-drag that file to an open panel in Windows Explorer.
  3. As you are dragging, the cursor shows a plus sign and the text "Copy to <foldername>".
  4. When you release the left button in Explorer, the filename appears in the Explorer panel with the correct file size. The file is properly copied.
System Specifics:
Windows 10 Enterprise, x64, ver 1709
TC 9.5.1 x64
TortoiseSVN 1.10.1

I've tried this on two computers with the same results. Is this a bug or am I doing something wrong?

Thanks,

-Rob
Last edited by Rob Weinstein on 2021-03-18, 22:55 UTC, edited 1 time in total.
User avatar
Dalai
Power Member
Power Member
Posts: 9366
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *Dalai »

I suggest to try with Explorer++ to see if it works there. If it doesn't, it's probably an issue with the Tortoise shell extension (not with TC).

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
Rob Weinstein
Junior Member
Junior Member
Posts: 45
Joined: 2006-06-10, 21:41 UTC
Location: Arizona

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *Rob Weinstein »

Dalai,

My corporate antivirus (Sophos) refused to let me install Explorer++. So I installed DoubleCommander 0.9.9 beta. I can left-drag files from TortoiseSVN's Repsitory Browser into a panel on DoubleCommander. It copies the file correctly.

edit: fixed typo.

-Rob
gdpr deleted 6
Power Member
Power Member
Posts: 872
Joined: 2013-09-04, 14:07 UTC

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *gdpr deleted 6 »

I can confirm the issue of ending up with zero-length files.

TC 9.51 32-bit and 64-bit
Win 7 Pro x64
TortoiseSVN 1.13.1

I tested with Explorer++ x64 1.3.5 as suggested. Same issue as in TC, only zero-length files.
I also testes with Double Commander x64 0.9.9. No problems there.

I haven't had the time to troubleshoot any further. If time permits, i will later enable debug settings in TortoiseSVN and check again...
User avatar
Dalai
Power Member
Power Member
Posts: 9366
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *Dalai »

IIRC there are several different drag/drop methods. Is it possible that Tortoise uses some method not supported by TC and Explorer++?

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *ghisler(Author) »

It probably sends files in a format not understood by TC.
Author of Total Commander
https://www.ghisler.com
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *ghisler(Author) »

I found the reason for the 0 byte file! TortoiseSVN sends the data as a stream (IStream). When TC tries to read from the stream, it returns S_FALSE, which means that the read was successful, but there was no more data. The reason is that the current position is at the END of the stream! All other programs seem to send a stream which is positioned at the start of the stream, so read will work.

Solution: I need to call Seek to position 0 to be able to read the stream.
I will add this to the upcoming version of TC, the beta test will start soon.
Author of Total Commander
https://www.ghisler.com
Rob Weinstein
Junior Member
Junior Member
Posts: 45
Joined: 2006-06-10, 21:41 UTC
Location: Arizona

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *Rob Weinstein »

Great news!

Thanks,

-Rob
gdpr deleted 6
Power Member
Power Member
Posts: 872
Joined: 2013-09-04, 14:07 UTC

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *gdpr deleted 6 »

ghisler(Author) wrote: 2021-01-08, 10:00 UTC [...]The reason is that the current position is at the END of the stream!
FYI: That seems to be intentional. See here: https://devblogs.microsoft.com/oldnewthing/20140918-00/?p=44033
If IData­Object::Get­Data returns a stream, then the stream pointer must be positioned at the end of the stream before the stream is returned. In other words, the last thing you do before returning the stream is seek it to the end. The contents of the data object are assumed to extend from the start of the stream to the stream’s position as returned by IData­Object::Get­Data. (And no, I don’t know why this rule exists.)
Funnily enough, even Raymond Chen doesn't know why that rule exist (or at least didn't at the time of writing that article). :)

As there seem to be quite a few programs whose IStream implementations do not seem to follow this rule, and Raymond even acknowledging scenarios where seeking to the stream end is not really possible, i am kinda curious about what the consequences could be, if any, if an IStream is not adhering to this rule, though. (As we have seen, if an IStream respecting this rule is being consumed by an application not adhering to it, stuff can and will break. And i am sorta curious as a cat about existing failure scenarios where a rule-violating IStream is being consumed by an application that blindly relies on the stream to respect the rule.)

(Also worth of note for putting Raymond Chen's article into the correct context is the fact that TortoiseSVN first writes the data of file being downloaded into a temp file, then creates an IStream for the temp file. So, technically, the IStream publicized through the clipboard does not represent a "live" download stream but rather a seekable local file stream.)


And last but not least, as referenced by Raymond Chan's article, here the relevant bits of that rule from the remarks section of the MSDN documentation for IDataObject::GetDataHere (https://docs.microsoft.com/en-gb/windows/win32/api/objidl/nf-objidl-idataobject-getdatahere):
When the transfer medium is a stream, OLE makes assumptions about where the data is being returned and the position of the stream's seek pointer. In a GetData call, the data returned is from stream position zero through just before the current seek pointer of the stream (that is, the position on exit). For GetDataHere, the data returned is from the stream position on entry through just before the position on exit.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *ghisler(Author) »

So do I need to check the current position, seek to the start, and then only get the data until that position? This would not work with streams where the pointer is already at the start. In other words, are there streams where the pointer is somewhere in the middle, and reading beyond that point would be a problem?
Author of Total Commander
https://www.ghisler.com
gdpr deleted 6
Power Member
Power Member
Posts: 872
Joined: 2013-09-04, 14:07 UTC

Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *gdpr deleted 6 »

ghisler(Author) wrote: 2021-01-11, 14:53 UTC So do I need to check the current position, seek to the start, and then only get the data until that position?
That's the idea according to the documentation.

Personally, I would see this as the best approach. The reasoning: i would assume the majority of such cases being an IStream producer who is taking the "extra" step of explicitly setting the stream position knowingly and intentionally. (Sure, one could argue that a stream position somewhere in the middle of the stream might be an unintended artifact of some in-memory stream compositing. But then again, i would argue that such cases of leaving the stream pointer unintentionally dangling at arbitrary meaningless non-zero stream positions should be in the minority...)

This would not work with streams where the pointer is already at the start.
If the stream position is at the beginning of the stream, i guess it is safe to assume that it is a stream not sticking to the rule.

In this case, as many bytes should be read as specified as the stream size (unless Read fails sooner with S_FALSE, of course). The stream size can be obtained by invoking IStream::Stat (https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-stat). Only if the stream size is also zero, i would solely rely on the Read method returning S_FALSE to indicate end of the offered data. I can't really fathom any situation aside from software bugs where a given non-zero stream size would not correlate with the stream position where Read would fail with S_FALSE, but better safe than sorry... :)

This approach should hopefully minimize the chances of something going awry. There would still be problems with (hypothetical?) infinite IStreams, but that's nothing that an IStream consumer can solve in a satisfactory way.

In other words, are there streams where the pointer is somewhere in the middle, and reading beyond that point would be a problem?
I have no idea and no example of a program that produces such IStreams. In the best case, both TC and the IStream-producing program would coincidentally agree to disagree with the rule in the same way, and everything goes to plan. Otherwise, TC would write additional data (whether meaningful data or garbage) into the file that is not supposed to be part of the data offered.

I don't know enough about OLE and COM to have an understanding of how to create infinite IStreams or other IStreams with content procedurally generated upon read or copy. (Is that even possible? i don't know). And i thus can't really do anything else than make wild and possibly unfounded speculations that would run the gamut from writing infinite streams into a file until the space in the file system is exhausted up to whatever forms of crashes or freezes of whatever code that might back a particular custom IStream/ISequentialStream implementation. :(
Rob Weinstein
Junior Member
Junior Member
Posts: 45
Joined: 2006-06-10, 21:41 UTC
Location: Arizona

[Fixed in 10.00 b2] Re: Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *Rob Weinstein »

I just installed v10.00 beta 2 and I found that left-drag copy from TortoiseSVN Repo-Browser to TC works perfectly now. Thanks everyone!

System Specifics:
Windows 10 Enterprise, x64, ver 1709
TC 10.00 beta 2 x64
TortoiseSVN 1.10.1

-Rob
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48028
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: [Fixed in 10.00 b2] Left-Drag Copy from TortoiseSVN Repo-Browser to TC Doesn't Work

Post by *ghisler(Author) »

Thanks for your feedback! All I had to to is move the data stream position from end to start to make it work.
Author of Total Commander
https://www.ghisler.com
Post Reply