I use latest stable version of CP2 on Windows 11 26H1. The file is Disk Copy 4.2 dImg/dCpy stored on HFS partition file.
Extracting by drag and dropping file from CP2 window with Add/Extract Drag & Copy mode and AppleDouble preservation to active Windows Explorer window produces corrupted file. At first glance it seems roughly okay, but on byte level it is exactly one byte smaller. Adding file back to HFS partition file produces file of one Data Len shorter in comparison with original file stored on HFS partition. Checksumming the file confirms corruption.
My findings:
Extracting by drag and dropping file from CP2 window with Add/Extract Drag & Copy mode and NAPS preservation to active Windows Explorer window produces good file.
Extracting by drag and dropping file from CP2 window with Add/Extract Drag & Copy mode and AppleSingle preservation to active Windows Explorer window produces good file.
Extracting using Action -> Extract file... with Add/Extract Drag & Copy mode and AppleDouble preservation produces good file.
I used drag and drop to add file back from Windows Explorer to CD2 partition file and it always produced good file.
It is safe to say drag and dropping CP2 to Explorer causes corruption, not Explorer to CP2.
It seems like the corruption happens in the extract drag and drop pipeline.
I can provide you with partition file in question if needed.
I can replicate the behavior, using the WPF version. I see the same issue with files extracted from ProDOS filesystems, so it's not specific to HFS. Initial observations:
- Extracted data files are consistently one byte shorter, due to truncation at the end of file (i.e. not something missing from the start or middle).
- Extracted header files (the "._" part) are correct.
- `Actions > Extract Files` works correctly; it's just drag & drop that fails.
- Drag & drop into a gmail window as an attachment works correctly, though gmail loses the leading '.' in the header filename. So this may only affect drag & drop into an Explorer window.
- Other preservation methods, such as NAPS, work correctly.
- The problem did NOT happen when I tried it with the new (Avalonia UI) version. (It also didn't lose the leading '.' on the header filename when dragging into gmail.) The new version extracts to the local filesystem rather than using "virtual files".
The data reported by the drag & drop target looks correct. For a 10240-byte file:
```
Found 4 formats:
• FileGroupDescriptorW:
0: 'BASIC.SYSTEM' len=10240: read 10240 bytes
1: '._BASIC.SYSTEM' len=-1: read 110 bytes
• FileContents: (shown in FileGroupDescriptorW section)
• faddenSoft:CiderPressII:md-v1:
0: 'BASIC.SYSTEM' part=DataFork len=10240: read 10240 bytes
{ [...]
```
This is pretty weird. I'll dig in more later today.
**More:**
I created an 8-byte file on an HFS volume and extracted it with the Actions menu, and got an 8-byte data file and a 145-byte header file. When I used drag & drop, I got a 7-byte data file and a 7-byte header file (which is invalid - the ADF signature alone is 8 bytes). A 16-byte file was 15/15. So the data file is one byte short, and the header file is capped to the same length.
My initial guess is that the lengths for the files are being added together, which subtracts one byte because the generated header file is a generated stream and hence has a length of -1 (see the drag & drop debug output above). The length is then used for both files. Things get even more interesting when the 8-byte and 16-byte files are dragged out in a single operation: both data files are full length, but their header files are both truncated to 22 bytes. Which I think it gets from 16+8 = 24, 24-1-1=22. So it appears Windows Explorer is summing up the lengths of every file and using that as the length to extract for each individual file.
If that's the case, this could actually be happening for all drag-out operations (not just AppleDouble), and it usually goes unnoticed because only AppleDouble has the "len=-1" for the generated header files. Windows Explorer is clearly getting the individual lengths, because the "do you want to replace" dialog shows the correct length for individual files, but somehow it's setting the read length for every file to the summed lengths of all files.
I can fix the issue, but this reduces my confidence in the virtual file approach.
The `ClipFileEntry.StreamGenerator.GetOutputLength()` function returns the length of the file part, or -1 if the value isn't fixed. For example, AppleSingle and AppleDouble header files are generated, so the length is set to -1. For AppleSingle this has no adverse effects, for AppleDouble it causes the problems observed.
Fortunately, the `StreamGenerator` class can easily generate the AppleDouble header file into a temporary stream and check its length. Resource forks are capped at 16MB, so a memory stream is fine. If I do this, AppleDouble files are created correctly.
However, I'm not sure why AppleSingle works correctly. One possibility is that Windows Explorer is looking at the first entry, and if it sees a length of -1 it uses a different approach. Or it's summing them all up, getting a negative value, and operating without a length. So it's likely that we only get into trouble if we mix & match generated files with non-generated files. If that's the case, then other situations should be fine, because I don't think there's another situation where both kinds of streams are present.
In a related story, dragging AppleDouble into gmail results in altered filenames for the header files. For `BASIC.SYSTEM` the initial '.' prefix was lost from `._BASIC.SYSTEM`, but for `ZZZ` the filename just appears as "download". I don't know what's going on there. The data file names come through fine.
On the bright side, the upcoming v2.0 app uses a completely different approach that appears to work correctly.
This fix, as well as the change for #76, are available in [v2.0.0-dev2](https://github.com/fadden/CiderPress2/releases/tag/v2.0.0-dev2). We're in the process of replacing the GUI app, so if you want the old GUI you will need to run `CiderPress2_wpf.exe` instead.