Android vs WPD bug. Wrong filesizes reported

I stumbled upon a strange bug in what Android can report to e.g. Windows trough the MTP/WPD interface.

Under some circumstances it reports a VERY wrong file size, but if you by WPD open a stream and copy the file until it sends no more bytes, it returns the correct full content.

I had inadvertently triggered the bug by manually moving the DCIM folder to a SD card, and then regretted and moved it back, both with “Astro” on a BB Priv on 6.0.1.

After this about half the files in the Camera sub-dir no longer reported the correct size. e.g a 7MB file might report as 1.5MB. There were no clear logic to the error. Not any obvious factor or any difference or bit-pattern that indicated what had happened. It wasn’t neither especially new or old ones, or any clear pattern. Just about 60% of the files. (And only files older than when I moved the folder a few weeks ago)

I tried on a different pc, to attempt to see if it was a Windows bug, and also reset the phablet. No difference, and same incorrect numbers.

I modified the PortableDevicesIncrementalCopy to handle this situation, but then realised that it was in the folder I recently messed with only. I then got he idea that with a little luck moving the images to a different folder and back on the internal memory fixed it, and it did!

Googling for this, it seems to be a known quite old bug, at least back to 2012 and 2013,  but it is a rather elusive one, that has been hard to provoke/reproduce and thus fix….

Of course since reading to the end of the streams works, I tried to see if I was allowed to seek in the stream. But this is not allowed, not even seek to the beginning. I do not know if the limitation is in WPD, Android or my specific phablet.

Here a part of the code (from the above linked) that returns the incorrect results

            // Get the size of the object
            //int objSiz;
            long objSiz;
            property = new _tagpropertykey();
            property.fmtid = WPD_OBJECT_;
            property.pid = 11;//WPD_OBJECT_SIZE;
            //values.GetSignedIntegerValue(property, out objSiz);
            values.GetSignedLargeIntegerValue(property, out objSiz);

(Both the Int32 and Int64 call returns the same incorrect sizes)

PS: The above image was taken from https://journal.hovatek.com/how-to-fix-an-android-phones-mass-storage-sd-card-that-wont-connect-to-pc-using-usb-cord/