On Wed, Feb 23, 2000 at 05:49:55PM +1100, Bradley Baetz wrote:
[snip very good explanation]
> When we are required to pass a pointer to the 32 bit struct (from
> mmioGetInfo) we do a copy (MMIO_infoMap16To32). When mmioAdvance is
> called we then have to update our 16 bit version of the struct at the
> same time we advance the 32 bit version which was passed to us. We then
> do pointer arithmatic on our internal 16 bit version to keep it up to
> date. The bit that got #if 0'd out points the internal version's pchNext
> member forward by the ammount which was read from the buffer passed in
> from the app. mmioSetInfo then calls MMIO_infoUnmap16To32, which unmaps
> the buffer by updating only the values which could have been changed
> (see the comment). Again, its impossible to do an MMIO_infoMap32To16,
> because of the pointer issue.
Yes, BUT:
The 32 bit version's pchNext points to *pchBuffer* after mmioAdvance,
and this probably is how it should be (due to the
mmioFlush(...,MMIO_EMPTYBUF) before).
If you *then* increment the 16 bit pchNext by the amount of data read,
you are doing a silly thing ;)
It should point to 16 bit pchBuffer as well, IMHO.
Not to mention that I'll put your whole previous paragraph at the top of
mmio.c. Thanks ! ;-)
> The mmioAdvance stuff was fixed to work with the new system, but not
> tested. I did ask on wine-devel if anyone had any apps which used
> mmioAdvance, but didn't get a response from anyone. Its quite possible
> that it doesn't work, but I think that the changes I made were right. I
> may have missed updating something somewhere though. See
>
>http://www.integrita.com/cgi-local/lwgate.pl/WINE-DEVEL/archives/1999-12/Author/article-416.html
> although the diff got modified a bit before I submitted it.
As I said before, I think it's the 16 bit pchNext pointer that's broken.
OK, I modified MMIO_infoMap16To32() at the beginning of my investigations.
Maybe that was wrong.
I should have verified that part later when I knew what was going on.
But something I just found out:
mmioSetInfo does:
lpmminfo->pchNext = (HPSTR)(lpmminfo->pchBuffer + (lpmmioinfo->pchNext -
lpmmioinfo->pchBuffer));
but mmioAdvance does:
lpmminfo->pchNext += (lpmmioinfo->pchNext - lpmminfo->pchBuffer);
^^^^^ ^^^^
This is wrong, no ?
And it is useless anyway (I'm glad it is, it would cause problems otherwise !),
because this follows immediately:
if (mmioFlush(hmmio, MMIO_EMPTYBUF)) {
GlobalUnlock16(hmmio);
return MMIOERR_CANNOTWRITE;
}
, which reinits the lpmminfo buffer to be empty and have its pchNext set to
pchBuffer.
And yet another problem:
*Internally* we very often use 32bit MMIOINFO.
If we don't use 16 bit MMIO functions at all (i.e.: a Win32 program),
the 16 bit buffer used by both Win16/32 will get assigned the 32 bit
(linear) buffer addresses as well somewhere (which is OK),
but the PTR_SEG_TO_LIN in MMIO_infoMap... fails and strips off the HIWORD
of the linear address during the conversion for the internal MMIOINFO.
That's why I introduced the b32bit flag for this function.
We *don't* just have a 16 bit structure to be converted into 32 bit.
The point is that this 16 bit structure is accessed by Win32 MMIO functions
as well.
And these let Wine store linear pointers there.
So we need to know when to do PTR_SEG_TO_LIN and when not.
I'll correct my patch as far as it needs to be corrected and add your
explanations there, OK ?
And I'll try to write an explanation of the algorithm of each complicated
I/O buffer function at its function header.
And finally I'll try to make some tests with mmioAdvance to find out
whether Wine really does The Right Thing (tm) here.
Andreas Mohr