Re: Truncate MIDI SysEx messages after termination byte

2013-01-18 Thread Christian Costa
2013/1/18  :
> Hi,
>
> Although I wouldn't mind inclusion of Christian's F0/F7 patch in upcoming Wine
> (barring decent formatting),

Well, it's not a formatting problem. It was intentional. The Wine
preferred style is 4 spaces indentation and no tab
but I didn't know that when I wrote the alsa midi driver. I took
wineoss one as a base without doing a cleanup.
I asked to Alexandre one day how to fix this kind of thing and he told
me to fix only the code I change as long as this fits
nicely with the code and it was for d3dxof which is 2 spaces
indentation. In this case it's a mix of tabs and space.
Replacing with space only looks the same and anyway last part of the
function is 4 spaces too. I admit I cleaned the whole function
whereas less than half of the code was changed. If something has
changed let me know.

Christian




Re: Truncate MIDI SysEx messages after termination byte

2013-01-15 Thread Christian Costa
2013/1/15  :
> Christian costa wrote:
>>> But I don't know whether there's some harmless general SysEx that we
>>> can send out.  Maybe some MIDI guru could suggest some?
>>What do you by harmless ? For what ? A midi HW device connected to the midi 
>>port ?
>
> A harmless MIDI message, perhaps there exists a NOP SysEx?
> E.g. a reset command is *not* harmless.
>
> Here are a few SysEx I gathered, looking for MIDI SysEx documentation
> Proteus SoundEngine System Reset SysEx F0 18 04 00 23 F7
> without knowing what they do:
> F0 56 64 4F 6C F7
> F0 7D 12 34 10 02 11 00 F7
>

SysEx are quite device specific and I don't kwnon about nop sysex.
Anyway I can take one of these.

>>we cannot verify the output.
> Sure, however increased code coverage *has* benefits.  E.g. sometimes I use 
> Valgrind.
>
Ok. Makes sense.




Truncate MIDI SysEx messages after termination byte

2013-01-15 Thread Joerg-Cyril.Hoehle
Christian costa wrote:
>> But I don't know whether there's some harmless general SysEx that we 
>> can send out.  Maybe some MIDI guru could suggest some?
>What do you by harmless ? For what ? A midi HW device connected to the midi 
>port ?

A harmless MIDI message, perhaps there exists a NOP SysEx?
E.g. a reset command is *not* harmless.

Here are a few SysEx I gathered, looking for MIDI SysEx documentation
Proteus SoundEngine System Reset SysEx F0 18 04 00 23 F7
without knowing what they do:
F0 56 64 4F 6C F7
F0 7D 12 34 10 02 11 00 F7

>we cannot verify the output.
Sure, however increased code coverage *has* benefits.  E.g. sometimes I use 
Valgrind.

Regards,
 Jörg



Re: Truncate MIDI SysEx messages after termination byte

2013-01-15 Thread Johannes Kroll
On Mon, 14 Jan 2013 11:42:46 +0100
 wrote:

> Hi,
> 
> Johannes Kroll wrote:
> >+for(i = 0; i < lpMidiOutHdr->dwBufferLength; i++)
> >+if((unsigned char)lpMidiOutHdr->lpData[i] == 0xF7 && i < 
> >lpMidiOutHdr->dwBufferLength-1)
> 
> What about
>  for(i = 0; i+1 < lpMidiOutHdr->dwBufferLength, i++)
>   without the redundant second if(&&) half?

Sure. That patch was quickly written, I was just happy to have
something which 'made it work'.


> I'm always happy when somebody with real MIDI HW speaks up, because
> I'm not convinced that the Wine MIDI code does TRT about SysEx --
> based on my readings, not experience, as I own no MIDI device...
> In particular, do you have any experience with multi-part SysEx
> messages (e.g. large data, such as uploads)?

I don't think so, no. I have the nanokontrol/nanokey/nanopad combo,
but they don't take large data blocks such as samples if that's what
you mean. They're also USB-MIDI devices, which might explain some
specific quirks. I.e. at the place I tried to fix with my patch, a
traditional MIDI device might just stop at the 0xF7 and get the SysEx
message OK (but it would still be confused by the rest of the bytes in
the buffer, there is still something wrong).

I have a really old keyboard/synth here with traditional MIDI but I
think it also doesn't use multipart SysEx messages.


> Still, I'm not persuaded that your patch is at the right place.
> I believe the midi* functions should be tiny wrappers around MODM_*
> messages, same for the wave* functions.  Every time I see somebody
> attempt to violate this 1:1 mapping, I'm suspicious.  Perhaps the
> logic that you're adding belongs to the individual wine*.drv/midi.c?

I'm not familiar with Wine code so if you think the fix should go to
some other place you're probably right.

I will investigate some more later when I have some time. Thanks.



> Do you get to see this warning from winealsa.drv where it
> specifically checks for a terminating F7 (but not intermediate F7)?
> http://source.winehq.org/source/dlls/winealsa.drv/midi.c#L969
> 964 /* FIXME: MS doc is not 100% clear. Will lpData only contain system 
> exclusive
> 965  * data, or can it also contain raw MIDI data, to be split up and 
> sent to
> 966  * modShortData() ?
> 967  * If the latest is true, then the following WARNing will fire up
> 968  */
> 969 if (lpData[0] != 0xF0 || lpData[lpMidiHdr->dwBufferLength - 1] != 
> 0xF7) {
> 970 WARN("Alleged system exclusive buffer is not correct\n\tPlease 
> report with MIDI file\n");
> 971 lpNewData = HeapAlloc(GetProcessHeap(), 0, 
> lpMidiHdr->dwBufferLength + 2);
> 972 }
> 
> Therefore, I'd be happy if you could invest some more time and check,
> based on your real MIDI HW, and perhaps native w* machines,
> whether MODM_LONGDATA and midiOutLongMsg are equivalent
> or whether midiOut* does some additional processing.
> 
> Regards,
>   Jörg Höhle





Re: Truncate MIDI SysEx messages after termination byte

2013-01-15 Thread Christian Costa
Hi,

2013/1/15  :
> Hi,
>
> Christian costa wrote:
>>+lpNewData[lpMidiHdr->dwBufferLength + len_add] = 0xF7;
> Here you're using spaces only, whereas the surrounding code uses TAB8.

It was not intended for submission. If I submit a patch, I will
removed all these tabs.

>
>>I tested it with the unit test attached.
> Instead of some isolated unit test, it would be preferable to
> add to winmm/tests/midi.c such that midiOutLongMsg gets covered
> by the tests. But I don't know whether there's some harmless
> general SysEx that we can send out.  Maybe some MIDI guru could
> suggest some?
>

The unit test was just to check byte insertion code. I attached for info only.
I could add a test but this will be only for debug purpose as we
cannot verify the output.
What do you by harmless ? For what ? A midi HW device connected to the
midi port ?


>
> The fix looks good, however while we are busy fixing lpNewData handling,
> I'd like to see the same patch fix its broken memory handling:
>
> 1. In the MOD_FMSYNTH branch, no
>  HeapFree(GetProcessHeap(), 0, lpNewData);
> Here I'm surprised that the static analysers did not spot it.
>
> 2. Wrong pointer being freed -- is that an indirect proof by absence of
> crash that this missing F0/F7 situation was never seen in practice?
> 1007 if (lpNewData)
> 1008 HeapFree(GetProcessHeap(), 0, lpData);
> Also, Wine style is to suppress the if()
>
> 3. Not checking for success
> 971 lpNewData = HeapAlloc(GetProcessHeap(), 0, 
> lpMidiHdr->dwBufferLength + 2);
> Either exit or skip adding F0/F7
>

I saw the memory leak. That needs to be fixed as well. And indeed,
this code is definitely broken
and I doubt it has been ever exercised unless it has been coded first
and them break afterwards.

Christian




Truncate MIDI SysEx messages after termination byte

2013-01-15 Thread Joerg-Cyril.Hoehle
Hi,

Christian costa wrote:
>+lpNewData[lpMidiHdr->dwBufferLength + len_add] = 0xF7;
Here you're using spaces only, whereas the surrounding code uses TAB8.

>I tested it with the unit test attached.
Instead of some isolated unit test, it would be preferable to
add to winmm/tests/midi.c such that midiOutLongMsg gets covered
by the tests. But I don't know whether there's some harmless
general SysEx that we can send out.  Maybe some MIDI guru could
suggest some?


The fix looks good, however while we are busy fixing lpNewData handling,
I'd like to see the same patch fix its broken memory handling:

1. In the MOD_FMSYNTH branch, no
 HeapFree(GetProcessHeap(), 0, lpNewData);
Here I'm surprised that the static analysers did not spot it.

2. Wrong pointer being freed -- is that an indirect proof by absence of
crash that this missing F0/F7 situation was never seen in practice?
1007 if (lpNewData)
1008 HeapFree(GetProcessHeap(), 0, lpData);
Also, Wine style is to suppress the if()

3. Not checking for success
971 lpNewData = HeapAlloc(GetProcessHeap(), 0, 
lpMidiHdr->dwBufferLength + 2);
Either exit or skip adding F0/F7

Regards,
Jörg Höhle



Re: Truncate MIDI SysEx messages after termination byte

2013-01-14 Thread Christian Costa

Le 14/01/2013 19:04, Christian Costa a écrit :

2013/1/14 Christian Costa :

2013/1/14  :

Hi,

Christian Costa wrote:

I took a look at the
alsa code and this code simply does not do what it is supposed to.

I also looked at it today and noted those bogus lines you quote. Needs
a patch (+ fix memory leak).

I will take a look at it and send a patch unless someone plan to do it.
I will not  be able to test with my 2 HW midi devices right now so I need
someone to test it. That would be good to enter a bug report for that.
Johannes, can you do that?


However, Johannes' change is presumably different, as he wants to
scan the buffer contents for a F7 terminator and ignore subsequent
bytes.  If I were to decide, I'd like to see more supporting evidence.

In the case the first by is F0 and the last one is F7, the code passes

I meant "last one if not F7".


Here are a patch to fix modLongData.
I tested it with the unit test attached.
Please give it a try.


diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
index 7c496c5..3f895e9 100644
--- a/dlls/winealsa.drv/midi.c
+++ b/dlls/winealsa.drv/midi.c
@@ -984,15 +984,16 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
 	if (lpData[0] != 0xF0) {
 	/* Send start of System Exclusive */
 	len_add = 1;
-	lpData[0] = 0xF0;
-	memcpy(lpNewData, lpData, lpMidiHdr->dwBufferLength);
+	lpNewData[0] = 0xF0;
+	memcpy(lpNewData + 1, lpData, lpMidiHdr->dwBufferLength);
 	WARN("Adding missing 0xF0 marker at the beginning of "
 		 "system exclusive byte stream\n");
 	}
 	if (lpData[lpMidiHdr->dwBufferLength-1] != 0xF7) {
 	/* Send end of System Exclusive */
-	memcpy(lpData + len_add, lpData, lpMidiHdr->dwBufferLength);
-lpNewData[lpMidiHdr->dwBufferLength + len_add - 1] = 0xF0;
+	if (!len_add)
+		memcpy(lpNewData, lpData, lpMidiHdr->dwBufferLength);
+lpNewData[lpMidiHdr->dwBufferLength + len_add] = 0xF7;
 	len_add++;
 	WARN("Adding missing 0xF7 marker at the end of "
 		 "system exclusive byte stream\n");

#include 
#include 
#include 

unsigned char data[] = {0xF0, 1, 2, 3, 4, 0xF6};

int main(void)
{
int		len_add = 0;
unsigned char	*lpData = data, *lpNewData = NULL;
int dwBufferLength = sizeof(data);
int i = 0;

for (i = 0; i < dwBufferLength; i++)
printf("%#x ", data[i]);
printf("\n");

if (lpData[0] != 0xF0 || lpData[dwBufferLength - 1] != 0xF7) {
printf("Alleged system exclusive buffer is not correct\n\tPlease report with MIDI file\n");
lpNewData = malloc(dwBufferLength + 2);
}

if (lpData[0] != 0xF0) {
/* Send start of System Exclusive */
len_add = 1;
lpNewData[0] = 0xF0;
memcpy(lpNewData + 1, lpData, dwBufferLength);
printf("Adding missing 0xF0 marker at the beginning of "
   "system exclusive byte stream\n");
}
if (lpData[dwBufferLength-1] != 0xF7) {
/* Send end of System Exclusive */
if (!len_add)
memcpy(lpNewData, lpData, dwBufferLength);
lpNewData[dwBufferLength + len_add] = 0xF7;
len_add++;
printf("Adding missing 0xF7 marker at the end of "
   "system exclusive byte stream\n");
}

for (i = 0; i < dwBufferLength + len_add; i++)
printf("%#x ", lpNewData ? lpNewData[i] : lpData[i]);
printf("\n");

}



Re: Truncate MIDI SysEx messages after termination byte

2013-01-14 Thread Christian Costa
2013/1/14 Christian Costa :
> 2013/1/14  :
>> Hi,
>>
>> Christian Costa wrote:
>>>I took a look at the
>>>alsa code and this code simply does not do what it is supposed to.
>> I also looked at it today and noted those bogus lines you quote. Needs
>> a patch (+ fix memory leak).
>
> I will take a look at it and send a patch unless someone plan to do it.
> I will not  be able to test with my 2 HW midi devices right now so I need
> someone to test it. That would be good to enter a bug report for that.
> Johannes, can you do that?
>
>>
>> However, Johannes' change is presumably different, as he wants to
>> scan the buffer contents for a F7 terminator and ignore subsequent
>> bytes.  If I were to decide, I'd like to see more supporting evidence.
>
> In the case the first by is F0 and the last one is F7, the code passes

I meant "last one if not F7".




Re: Truncate MIDI SysEx messages after termination byte

2013-01-14 Thread Christian Costa
2013/1/14  :
> Hi,
>
> Christian Costa wrote:
>>I took a look at the
>>alsa code and this code simply does not do what it is supposed to.
> I also looked at it today and noted those bogus lines you quote. Needs
> a patch (+ fix memory leak).

I will take a look at it and send a patch unless someone plan to do it.
I will not  be able to test with my 2 HW midi devices right now so I need
someone to test it. That would be good to enter a bug report for that.
Johannes, can you do that?

>
> However, Johannes' change is presumably different, as he wants to
> scan the buffer contents for a F7 terminator and ignore subsequent
> bytes.  If I were to decide, I'd like to see more supporting evidence.

In the case the first by is F0 and the last one is F7, the code passes
a uninitialized buffer to the alsa function with a wrong terminating
byte F0 inserted which
is even worst because it opens a new sys ex sequence without end.
The Johanness patch prevents this case to happend by making last byte to be F7.

Bye
Christian




Truncate MIDI SysEx messages after termination byte

2013-01-14 Thread Joerg-Cyril.Hoehle
Hi,

Christian Costa wrote:
>I took a look at the
>alsa code and this code simply does not do what it is supposed to.
I also looked at it today and noted those bogus lines you quote. Needs
a patch (+ fix memory leak).

However, Johannes' change is presumably different, as he wants to
scan the buffer contents for a F7 terminator and ignore subsequent
bytes.  If I were to decide, I'd like to see more supporting evidence.

I'd appreciate if Johannes would open a bug report and attach some 
WINEDEBUG=+midi,+mmdevapi,+alsa,+winmm,+driver,+tid,+timestamp logs to bugzilla,
much like bug #26928. http://bugs.winehq.org/show_bug.cgi?id=26928
Having some logs with *complete* SysEx contents helps.

There's also a "closed as abandoned" bug about microKORG
http://bugs.winehq.org/show_bug.cgi?id=17608
which might be of interest to Johannes.

Regards,
Jörg Höhle



Re: Truncate MIDI SysEx messages after termination byte

2013-01-14 Thread Christian Costa
> Still, I'm not persuaded that your patch is at the right place.
> I believe the midi* functions should be tiny wrappers around MODM_*
> messages, same for the wave* functions.  Every time I see somebody
> attempt to violate this 1:1 mapping, I'm suspicious.  Perhaps the
> logic that you're adding belongs to the individual wine*.drv/midi.c?


Maybe it worth compare visually between builtin and native by adding
sysex dump code to one driver if needed as 1st and last 3 bytes are
currently dump.

>
>
> Therefore, I'd be happy if you could invest some more time and check,
> based on your real MIDI HW, and perhaps native w* machines,
> whether MODM_LONGDATA and midiOutLongMsg are equivalent
> or whether midiOut* does some additional processing.


I don't know if Johannes uses alsa driver but I took a look at the
alsa code and this code simply does not do what it is supposed to.
I think that would be better to fix this code first as it might be the
cause of the bug.


984 if (lpData[0] != 0xF0) {
985 /* Send start of System Exclusive */
986 len_add = 1;
987 lpData[0] = 0xF0;
988 memcpy(lpNewData, lpData, lpMidiHdr->dwBufferLength);
989 WARN("Adding missing 0xF0 marker at the beginning of "
990  "system exclusive byte stream\n");
991 }
992 if (lpData[lpMidiHdr->dwBufferLength-1] != 0xF7) {
993 /* Send end of System Exclusive */
994 memcpy(lpData + len_add, lpData, lpMidiHdr->dwBufferLength);
995 lpNewData[lpMidiHdr->dwBufferLength + len_add - 1] = 0xF0;
996 len_add++;
997 WARN("Adding missing 0xF7 marker at the end of "
998  "system exclusive byte stream\n");

999 }




Truncate MIDI SysEx messages after termination byte

2013-01-14 Thread Joerg-Cyril.Hoehle
Hi,

Johannes Kroll wrote:
>+for(i = 0; i < lpMidiOutHdr->dwBufferLength; i++)
>+if((unsigned char)lpMidiOutHdr->lpData[i] == 0xF7 && i < 
>lpMidiOutHdr->dwBufferLength-1)

What about
 for(i = 0; i+1 < lpMidiOutHdr->dwBufferLength, i++)
  without the redundant second if(&&) half?


I'm always happy when somebody with real MIDI HW speaks up, because
I'm not convinced that the Wine MIDI code does TRT about SysEx --
based on my readings, not experience, as I own no MIDI device...
In particular, do you have any experience with multi-part SysEx
messages (e.g. large data, such as uploads)?

Still, I'm not persuaded that your patch is at the right place.
I believe the midi* functions should be tiny wrappers around MODM_*
messages, same for the wave* functions.  Every time I see somebody
attempt to violate this 1:1 mapping, I'm suspicious.  Perhaps the
logic that you're adding belongs to the individual wine*.drv/midi.c?

Do you get to see this warning from winealsa.drv where it
specifically checks for a terminating F7 (but not intermediate F7)?
http://source.winehq.org/source/dlls/winealsa.drv/midi.c#L969
964 /* FIXME: MS doc is not 100% clear. Will lpData only contain system 
exclusive
965  * data, or can it also contain raw MIDI data, to be split up and sent 
to
966  * modShortData() ?
967  * If the latest is true, then the following WARNing will fire up
968  */
969 if (lpData[0] != 0xF0 || lpData[lpMidiHdr->dwBufferLength - 1] != 0xF7) 
{
970 WARN("Alleged system exclusive buffer is not correct\n\tPlease 
report with MIDI file\n");
971 lpNewData = HeapAlloc(GetProcessHeap(), 0, 
lpMidiHdr->dwBufferLength + 2);
972 }

Therefore, I'd be happy if you could invest some more time and check,
based on your real MIDI HW, and perhaps native w* machines,
whether MODM_LONGDATA and midiOutLongMsg are equivalent
or whether midiOut* does some additional processing.

Regards,
Jörg Höhle



Re: Truncate MIDI SysEx messages after termination byte

2013-01-10 Thread Christian Costa
2013/1/10 Johannes Kroll 

> On Thu, 10 Jan 2013 12:04:02 +0100
> Christian Costa  wrote:
>
> > In your code you stop checking F7 just before the last byte (until
> > position lpMidiOutHdr->dwBufferLength-2);
> > You can check the last byte as well. This is also valid and simplify the
> > condition.
> > The missing F7 byte case is handled by the for loop.
>
> Ah, you mean that check. Yes, it's not strictly necessary, it just
> decides whether it has to save & restore dwBufferSize or not.
>
>
> > Regarding the single MMDRV_Message call, I was thinking about something
> > like below.
> > This also enable printing a WARN when F7 is missing which can be useful
> for
> > debug.
> >
> > DWORD oldBufferLength = lpMidiOutHdr->dwBufferLength;
> > DWORD ret;
> >
> > for(i = 0; i < lpMidiOutHdr->dwBufferLength; i++)
> >
> >/* SysEx messages are terminated by a 0xF7 byte. If the buffer
> > contains additional
> >   bytes, send only the bytes up to the termination byte. */
> > if((unsigned char)lpMidiOutHdr->lpData[i] == 0xF7)
> > {
> > lpMidiOutHdr->dwBufferLength = i+1;
> >
> > break;
> >
> > }
> >
> >
> > if (i == lpMidiOutHdr->dwBufferLength)
> >
> > WARN("SysEx termination byte 0xF7 missing\n")
> >
> >
> >
> > ret =  MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr,
> > uSize);
> >
> > /* restore the midi header to its original state. */
> > lpMidiOutHdr->dwBufferLength = oldBufferLength;
> >
> >
> > return ret;
>
> I see nothing wrong with that apart from the broken formatting (please
> don't use HTML mail). Did you test it?
>
>
It was not intended to be used as is. It's just to show what I had in mind.


> I don't care which version is used, I would just be very happy if
> *something* is included which makes my MIDI device work with Wine.
>

There is no reason your patch will not get in. Generally, it's just patches
need
to have the quality required to be committed. Sometime it can takes several
iterations.



>
> How does this generally work here, will there be feedback from a
> maintainer on whether the patch will be included, or is it usually just
> silently included?


> Alexandre Julliard (or whoever decides this): Could you comment please?
>
>
>
For a patch which is ok, it will be committed silently by Alexandre. You
may already
know the patches status page at http://source.winehq.org/patches.
Usually maintainers or skilled people of a specific area look at patches and
give some feedback if something seems wrong or not clear.



> And Christian, please, configure your mail client. The list mails I get
> from you are directed to me, not the list, and they are missing the
> List-Id field.
>
>
> When I use gmail web client, I don't have good results sometimes. Maybe
there is a configuration for that.
I'm full open to any hint.
Regarding emails addresses, I write to someone with wine-devel in cc but
I'm ok to use
only wine-devel with you.



Re: Truncate MIDI SysEx messages after termination byte

2013-01-10 Thread Johannes Kroll
On Thu, 10 Jan 2013 12:04:02 +0100
Christian Costa  wrote:

> In your code you stop checking F7 just before the last byte (until
> position lpMidiOutHdr->dwBufferLength-2);
> You can check the last byte as well. This is also valid and simplify the
> condition.
> The missing F7 byte case is handled by the for loop.

Ah, you mean that check. Yes, it's not strictly necessary, it just
decides whether it has to save & restore dwBufferSize or not.


> Regarding the single MMDRV_Message call, I was thinking about something
> like below.
> This also enable printing a WARN when F7 is missing which can be useful for
> debug.
> 
> DWORD oldBufferLength = lpMidiOutHdr->dwBufferLength;
> DWORD ret;
> 
> for(i = 0; i < lpMidiOutHdr->dwBufferLength; i++)
> 
>/* SysEx messages are terminated by a 0xF7 byte. If the buffer
> contains additional
>   bytes, send only the bytes up to the termination byte. */
> if((unsigned char)lpMidiOutHdr->lpData[i] == 0xF7)
> {
> lpMidiOutHdr->dwBufferLength = i+1;
> 
> break;
> 
> }
> 
> 
> if (i == lpMidiOutHdr->dwBufferLength)
> 
> WARN("SysEx termination byte 0xF7 missing\n")
> 
> 
> 
> ret =  MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr,
> uSize);
> 
> /* restore the midi header to its original state. */
> lpMidiOutHdr->dwBufferLength = oldBufferLength;
> 
> 
> return ret;

I see nothing wrong with that apart from the broken formatting (please
don't use HTML mail). Did you test it?

I don't care which version is used, I would just be very happy if
*something* is included which makes my MIDI device work with Wine.

How does this generally work here, will there be feedback from a
maintainer on whether the patch will be included, or is it usually just
silently included?

Alexandre Julliard (or whoever decides this): Could you comment please?


And Christian, please, configure your mail client. The list mails I get
from you are directed to me, not the list, and they are missing the
List-Id field. 





Re: Truncate MIDI SysEx messages after termination byte

2013-01-10 Thread Christian Costa
2013/1/10 Johannes Kroll 

> On Thu, 10 Jan 2013 01:05:28 +0100
> Johannes Kroll  wrote:
>
> > On Thu, 10 Jan 2013 00:38:06 +0100
> > Christian Costa  wrote:
> >
> >
> > > After a better look the changes seem correct.
> > > The condition i < lpMidioutHdr->dwBufferLength-1 is not necessary
> tough.
> >
> > Without the buffer length check, there would be a buffer overflow when
> > an application tries to send a SysEx without an F7 byte.
>
> I meant a read past the end of the buffer of course, not an overflow.
>
>
>
In your code you stop checking F7 just before the last byte (until
position lpMidiOutHdr->dwBufferLength-2);
You can check the last byte as well. This is also valid and simplify the
condition.
The missing F7 byte case is handled by the for loop.

Regarding the single MMDRV_Message call, I was thinking about something
like below.
This also enable printing a WARN when F7 is missing which can be useful for
debug.

DWORD oldBufferLength = lpMidiOutHdr->dwBufferLength;
DWORD ret;

for(i = 0; i < lpMidiOutHdr->dwBufferLength; i++)

   /* SysEx messages are terminated by a 0xF7 byte. If the buffer
contains additional
  bytes, send only the bytes up to the termination byte. */
if((unsigned char)lpMidiOutHdr->lpData[i] == 0xF7)
{
lpMidiOutHdr->dwBufferLength = i+1;

break;

}


if (i == lpMidiOutHdr->dwBufferLength)

WARN("SysEx termination byte 0xF7 missing\n")



ret =  MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr,
uSize);

/* restore the midi header to its original state. */
lpMidiOutHdr->dwBufferLength = oldBufferLength;


return ret;



Re: Truncate MIDI SysEx messages after termination byte

2013-01-09 Thread Johannes Kroll
On Thu, 10 Jan 2013 01:05:28 +0100
Johannes Kroll  wrote:

> On Thu, 10 Jan 2013 00:38:06 +0100
> Christian Costa  wrote:
> 
> 
> > After a better look the changes seem correct.
> > The condition i < lpMidioutHdr->dwBufferLength-1 is not necessary tough.
> 
> Without the buffer length check, there would be a buffer overflow when
> an application tries to send a SysEx without an F7 byte. 

I meant a read past the end of the buffer of course, not an overflow.





Re: Truncate MIDI SysEx messages after termination byte

2013-01-09 Thread Johannes Kroll
On Thu, 10 Jan 2013 00:38:06 +0100
Christian Costa  wrote:


> After a better look the changes seem correct.
> The condition i < lpMidioutHdr->dwBufferLength-1 is not necessary tough.

Without the buffer length check, there would be a buffer overflow when
an application tries to send a SysEx without an F7 byte. 






Re: Truncate MIDI SysEx messages after termination byte

2013-01-09 Thread Christian Costa

Le 09/01/2013 19:32, Johannes Kroll a écrit :

On Wed, 9 Jan 2013 19:04:03 +0100
Christian Costa  wrote:


I would say consistency would be 2 spaces or none.

You are, of course, entitled to your opinion.
If my opinion does not matter as well as code style practices we can 
found in wine
that would be better to stick to file code style. Off course you're free 
to submit

what you want.




Using only 1 space for assignment does not seem very common in wine AFAIK.
In general it's better to follow the file style or the function to avoid
mixing styles
except if you work heavyly on these files.



If anybody sees non-style-related issues with the patch, please let me
know.


dwBytesRecorded is supposed to tell how many bytes are valid. What's wrong
with it ?

Is it? It was always zero in midiOutLongMsg when I checked. The program
works on Windows though. This means that either dwBytesRecorded is not
supposed to be valid in that place, possibly only when data is read from
some MIDI device. This would seem to be consistent with the "-Recorded"
in the variable name.

Or it is supposed to be valid, which would mean that there is a bug
somewhere else in Wine.

SysEx messages where the real message length equals dwBufferSize do get
through properly even without the patch, which means that the code in
MMDRV_Message and onwards does not care about dwBytesRecorded. It uses
dwBufferSize to check how many bytes it should send.

This applies only for recording which is not the case here.
After a better look the changes seem correct.
The condition i < lpMidioutHdr->dwBufferLength-1 is not necessary tough.
And a single call to MMDRV_Message would be better.





Please keep any replies on the list(s).



Good mail client which sucks.

This sentence makes no sense.

Yours too.




wine-patches is only for patch submission.

Use -devel then. Just don't send me copies.


...




Re: Truncate MIDI SysEx messages after termination byte

2013-01-09 Thread Johannes Kroll
On Wed, 9 Jan 2013 19:04:03 +0100
Christian Costa  wrote:

> I would say consistency would be 2 spaces or none.

You are, of course, entitled to your opinion.


> Using only 1 space for assignment does not seem very common in wine AFAIK.
> In general it's better to follow the file style or the function to avoid
> mixing styles
> except if you work heavyly on these files.
>
>
> > If anybody sees non-style-related issues with the patch, please let me
> > know.
> >
> 
> dwBytesRecorded is supposed to tell how many bytes are valid. What's wrong
> with it ?

Is it? It was always zero in midiOutLongMsg when I checked. The program
works on Windows though. This means that either dwBytesRecorded is not
supposed to be valid in that place, possibly only when data is read from
some MIDI device. This would seem to be consistent with the "-Recorded"
in the variable name.

Or it is supposed to be valid, which would mean that there is a bug
somewhere else in Wine.

SysEx messages where the real message length equals dwBufferSize do get
through properly even without the patch, which means that the code in
MMDRV_Message and onwards does not care about dwBytesRecorded. It uses
dwBufferSize to check how many bytes it should send.


> > Please keep any replies on the list(s).
> >
> >
> Good mail client which sucks.

This sentence makes no sense.


> wine-patches is only for patch submission.

Use -devel then. Just don't send me copies.







Re: Truncate MIDI SysEx messages after termination byte

2013-01-09 Thread Christian Costa
2013/1/9 Johannes Kroll 

> On Wed, 9 Jan 2013 16:10:18 +0100
> Christian Costa  wrote:
>
> > 2013/1/9 Johannes Kroll 
> >
> > > On Wed, 09 Jan 2013 10:19:54 +0100
> > > Christian Costa  wrote:
> > >
> > > > Le 09/01/2013 04:26, Johannes Kroll a écrit :
> > > > > Hi,
> > > > >
> > > > > On Wed, 09 Jan 2013 03:55:25 +0100
> > > > > Christian Costa  wrote:
> > > > >
> > > > >> Hi,
> > > > >>
> > > > >> Please be consistent when using space. 1 space before and after
> > > > >> operators (<, ==, =, ...).
> > > > > spaces inserted. HTH.
> > > > >
> > > > > J.
> > > > That's better. You forgot some occurences in the for loop though.
> > >
> > > Is it OK if I leave the rest of the formatting to you? Any style is
> > > fine with me, whatever makes you happy and hopefully gets the patch
> > > included.
> > >
> > > Formatting only patch are not allowed. Clean patch and consistency in
> code
> > style help your patch get in.
> > Alexandre Julliard is the only judge not me. If he is ok with your patch
> > that's fine.
> > Anyway having the for loop consistent with rest should not be that hard.
> >
> > for(i= 0; idwBufferLength; i++)
>
> The original patch was consistent with my coding style. To make
> assignments stick out visually, I use no space to the left of the
> assignment operator, one space to the right. On comparison operators, I
> use space either on both sides, or none. You will see this in all code
> I write.
>
> I attached another version of the patch. I added 3 more spaces and one
> line break in a long comment line. You or Alexandre can choose the
> version they like best. If you still see style issues, please consider
> changing the style to your liking. If that's not possible, the patch
> will have to be rejected.
>
>
I would say consistency would be 2 spaces or none.
Using only 1 space for assignment does not seem very common in wine AFAIK.
In general it's better to follow the file style or the function to avoid
mixing styles
except if you work heavyly on these files.



> If anybody sees non-style-related issues with the patch, please let me
> know.
>

dwBytesRecorded is supposed to tell how many bytes are valid. What's wrong
with it ?


>
> Please keep any replies on the list(s).
>
>
Good mail client which sucks.
wine-patches is only for patch submission.


> Have a nice day.
> Johannes
>
>
>
>
>
>



Re: Truncate MIDI SysEx messages after termination byte

2013-01-09 Thread Johannes Kroll
On Wed, 9 Jan 2013 16:10:18 +0100
Christian Costa  wrote:

> 2013/1/9 Johannes Kroll 
> 
> > On Wed, 09 Jan 2013 10:19:54 +0100
> > Christian Costa  wrote:
> >
> > > Le 09/01/2013 04:26, Johannes Kroll a écrit :
> > > > Hi,
> > > >
> > > > On Wed, 09 Jan 2013 03:55:25 +0100
> > > > Christian Costa  wrote:
> > > >
> > > >> Hi,
> > > >>
> > > >> Please be consistent when using space. 1 space before and after
> > > >> operators (<, ==, =, ...).
> > > > spaces inserted. HTH.
> > > >
> > > > J.
> > > That's better. You forgot some occurences in the for loop though.
> >
> > Is it OK if I leave the rest of the formatting to you? Any style is
> > fine with me, whatever makes you happy and hopefully gets the patch
> > included.
> >
> > Formatting only patch are not allowed. Clean patch and consistency in code
> style help your patch get in.
> Alexandre Julliard is the only judge not me. If he is ok with your patch
> that's fine.
> Anyway having the for loop consistent with rest should not be that hard.
> 
> for(i= 0; idwBufferLength; i++)

The original patch was consistent with my coding style. To make
assignments stick out visually, I use no space to the left of the
assignment operator, one space to the right. On comparison operators, I
use space either on both sides, or none. You will see this in all code
I write.

I attached another version of the patch. I added 3 more spaces and one
line break in a long comment line. You or Alexandre can choose the
version they like best. If you still see style issues, please consider
changing the style to your liking. If that's not possible, the patch
will have to be rejected.

If anybody sees non-style-related issues with the patch, please let me
know.

Please keep any replies on the list(s).

Have a nice day.
Johannes


>From b8b97bb56dd6460b2b422061cc565dafe9d94d46 Mon Sep 17 00:00:00 2001
From: Johannes Kroll 
Date: Wed, 9 Jan 2013 02:40:34 +0100
Subject: terminate sysex messages

---
 dlls/winmm/winmm.c |   17 +
 1 file changed, 17 insertions(+)

diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c
index aecb9cf..f4fecb1 100644
--- a/dlls/winmm/winmm.c
+++ b/dlls/winmm/winmm.c
@@ -531,11 +531,28 @@ UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut,
   MIDIHDR* lpMidiOutHdr, UINT uSize)
 {
 LPWINE_MLD wmld;
+int i;
 
 TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
 
 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
return MMSYSERR_INVALHANDLE;
+
+for(i = 0; i < lpMidiOutHdr->dwBufferLength; i++)
+{
+/* SysEx messages are terminated by a 0xF7 byte. If the buffer 
contains additional 
+   bytes, send only the bytes up to the termination byte. */
+if((unsigned char)lpMidiOutHdr->lpData[i] == 0xF7 && i < 
lpMidiOutHdr->dwBufferLength-1)
+{
+DWORD oldBufferLength = lpMidiOutHdr->dwBufferLength;
+DWORD ret;
+lpMidiOutHdr->dwBufferLength = i+1;
+ret = MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr, 
uSize);
+/* restore the midi header to its original state. */
+lpMidiOutHdr->dwBufferLength = oldBufferLength;
+return ret;
+}
+}
 
 return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr, uSize);
 }
-- 
1.7.9.5




Re: Truncate MIDI SysEx messages after termination byte

2013-01-09 Thread Johannes Kroll
On Wed, 09 Jan 2013 10:19:54 +0100
Christian Costa  wrote:

> Le 09/01/2013 04:26, Johannes Kroll a écrit :
> > Hi,
> >
> > On Wed, 09 Jan 2013 03:55:25 +0100
> > Christian Costa  wrote:
> >
> >> Hi,
> >>
> >> Please be consistent when using space. 1 space before and after
> >> operators (<, ==, =, ...).
> > spaces inserted. HTH.
> >
> > J.
> That's better. You forgot some occurences in the for loop though.

Is it OK if I leave the rest of the formatting to you? Any style is
fine with me, whatever makes you happy and hopefully gets the patch
included.





Re: Truncate MIDI SysEx messages after termination byte

2013-01-09 Thread Christian Costa

Le 09/01/2013 04:26, Johannes Kroll a écrit :

Hi,

On Wed, 09 Jan 2013 03:55:25 +0100
Christian Costa  wrote:


Hi,

Please be consistent when using space. 1 space before and after
operators (<, ==, =, ...).

spaces inserted. HTH.

J.

That's better. You forgot some occurences in the for loop though.

Christian




Re: Truncate MIDI SysEx messages after termination byte

2013-01-08 Thread Johannes Kroll
Hi,

On Wed, 09 Jan 2013 03:55:25 +0100
Christian Costa  wrote:

> Hi,
> 
> Please be consistent when using space. 1 space before and after 
> operators (<, ==, =, ...).

spaces inserted. HTH.

J.>From edd15d7d71e7309937c27dd9e6eab56bf42cc589 Mon Sep 17 00:00:00 2001
From: Johannes Kroll 
Date: Wed, 9 Jan 2013 02:40:34 +0100
Subject: terminate sysex messages

---
 dlls/winmm/winmm.c |   16 
 1 file changed, 16 insertions(+)

diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c
index aecb9cf..1f8ea10 100644
--- a/dlls/winmm/winmm.c
+++ b/dlls/winmm/winmm.c
@@ -531,11 +531,27 @@ UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut,
   MIDIHDR* lpMidiOutHdr, UINT uSize)
 {
 LPWINE_MLD wmld;
+int i;
 
 TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
 
 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
return MMSYSERR_INVALHANDLE;
+
+for(i= 0; idwBufferLength; i++)
+{
+/* SysEx messages are terminated by a 0xF7 byte. If the buffer 
contains additional bytes, send only the bytes up to the termination byte. */
+if((unsigned char)lpMidiOutHdr->lpData[i] == 0xF7 && i < 
lpMidiOutHdr->dwBufferLength-1)
+{
+DWORD oldBufferLength = lpMidiOutHdr->dwBufferLength;
+DWORD ret;
+lpMidiOutHdr->dwBufferLength = i+1;
+ret = MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr, 
uSize);
+/* restore the midi header to its original state. */
+lpMidiOutHdr->dwBufferLength = oldBufferLength;
+return ret;
+}
+}
 
 return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr, uSize);
 }
-- 
1.7.9.5




Re: Truncate MIDI SysEx messages after termination byte

2013-01-08 Thread Christian Costa

Le 09/01/2013 03:12, Johannes Kroll a écrit :

While using the KORG Kontrol Editor software [1] under Wine to configure
my nanoPAD2 MIDI controller, I noticed that uploading parameters to the
hardware doesn't work. The program displays a timeout message.

The program relies on the MIDI driver to remove data after the SysEx
termination byte [2], but the Wine's winmm implementation doesn't do
this. The complete MIDIHDR buffer is sent, including excess bytes in the
case when the buffer is larger than the MIDI message.

The attached patch fixes the problem by truncating SysEx messages after
the termination byte, ignoring any excess bytes.

I tested the patch with KORG Kontrol Editor under Ubuntu 12.04 64-bit
(32-bit wine).

[1] http://www.korg.co.uk/support/downloads/nano2_dl.php
[2] http://home.roadrunner.com/~jgglatt/tech/midispec/sysex.htm



Hi,

Please be consistent when using space. 1 space before and after 
operators (<, ==, =, ...).


Christian