[RFC 1/11] Linux FF: Joystick control panel program
Elias Vanderstuyft
elias.vds at gmail.com
Tue Mar 4 13:19:16 CST 2014
a) When unloading conditional effects in joy.cpl, the program crashes:
When unloading the conditional effect array entries,
Wine tries to access an invalid (high) address because
dieffect.lpvTypeSpecificParams was not set at the time the
effect was created.
So declare a valid 'standard' (maxed out) conditional effect.
For other unknown effects:
- The same can happen when CustomForce effects are available,
but because Wine's FF dinput->linux translation does
not support this yet,
we simply print a FIXME to indicate a possible cause
if a crash would happen.
- The same for other (unsupported) effects (this is
probably not safe?),
but then we print a WARN.
=> This is probably not safe, but these effects won't be unloaded,
because they will never be allowed to be created:
I tested this by using a dummy FF device that
advertised to support CustomForce,
but because JoystickAImpl_EnumEffects() does not
handle CustomForce,
no CustomForce entry was generated in the joy.cpl application,
and there was no crash at exit.
Solution: After the code of joy.cpl/main.c:766 :
else if (IsEqualGUID(&pdei->guid, &GUID_Sine) ||
IsEqualGUID(&pdei->guid, &GUID_Square) ||
IsEqualGUID(&pdei->guid, &GUID_Triangle) ||
IsEqualGUID(&pdei->guid, &GUID_SawtoothUp) ||
IsEqualGUID(&pdei->guid, &GUID_SawtoothDown))
{
DIPERIODIC pforce;
pforce.dwMagnitude = DI_FFNOMINALMAX;
pforce.lOffset = 0;
pforce.dwPhase = 0;
pforce.dwPeriod = FF_PERIOD_TIME;
dieffect.cbTypeSpecificParams = sizeof(pforce);
dieffect.lpvTypeSpecificParams = &pforce;
dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS;
}
add the following code :
else if (IsEqualGUID(&pdei->guid, &GUID_Spring) ||
IsEqualGUID(&pdei->guid, &GUID_Damper) ||
IsEqualGUID(&pdei->guid, &GUID_Inertia) ||
IsEqualGUID(&pdei->guid, &GUID_Friction))
{
DICONDITION cxyforce[2];
int i;
for (i = 0; i < 2; ++i) {
cxyforce[i].lOffset = 0;
cxyforce[i].lPositiveCoefficient = DI_FFNOMINALMAX;
cxyforce[i].lNegativeCoefficient = DI_FFNOMINALMAX;
cxyforce[i].dwPositiveSaturation = DI_FFNOMINALMAX;
cxyforce[i].dwNegativeSaturation = DI_FFNOMINALMAX;
cxyforce[i].lDeadBand = 0;
}
dieffect.cbTypeSpecificParams = sizeof(cxyforce);
dieffect.lpvTypeSpecificParams = cxyforce;
dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS;
}
else if (IsEqualGUID(&pdei->guid, &GUID_CustomForce))
{
FIXME("Unhandled type specific parameters of CustomForce
effect, this may lead to memory errors later on.\n");
}
else
WARN("Possibly unhandled type specific parameters of
effect with guid %x.\n", pdei->guid);
b) Weirdly, I had to add these commands that evaluates the DIEFFECT
pointers at the end of each if-case,
otherwise the pointers seemed to point to other address or data on
that address was getting overwritten:
TRACE("&rforce=0x%x\n", &rforce);
TRACE("&cforce=0x%x\n", &cforce);
TRACE("&pforce=0x%x\n", &pforce);
TRACE("&cxyforce[0]=0x%x; &cxyforce[1]=0x%x\n",
&(cxyforce[0]), &(cxyforce[1]));
Elias
-------------- next part --------------
///////////////////////////// Joystick control panel program /////////////////////////////
a) When unloading conditional effects in joy.cpl, the program crashes:
When unloading the conditional effect array entries,
Wine tries to access an invalid (high) address because
dieffect.lpvTypeSpecificParams was not set at the time the effect was created.
So declare a valid 'standard' (maxed out) conditional effect.
For other unknown effects:
- The same can happen when CustomForce effects are available,
but because Wine's FF dinput->linux translation does not support this yet,
we simply print a FIXME to indicate a possible cause if a crash would happen.
- The same for other (unsupported) effects (this is probably not safe?),
but then we print a WARN.
=> This is probably not safe, but these effects won't be unloaded,
because they will never be allowed to be created:
I tested this by using a dummy FF device that advertised to support CustomForce,
but because JoystickAImpl_EnumEffects() does not handle CustomForce,
no CustomForce entry was generated in the joy.cpl application,
and there was no crash at exit.
Solution: After the code of joy.cpl/main.c:766 :
else if (IsEqualGUID(&pdei->guid, &GUID_Sine) ||
IsEqualGUID(&pdei->guid, &GUID_Square) ||
IsEqualGUID(&pdei->guid, &GUID_Triangle) ||
IsEqualGUID(&pdei->guid, &GUID_SawtoothUp) ||
IsEqualGUID(&pdei->guid, &GUID_SawtoothDown))
{
DIPERIODIC pforce;
pforce.dwMagnitude = DI_FFNOMINALMAX;
pforce.lOffset = 0;
pforce.dwPhase = 0;
pforce.dwPeriod = FF_PERIOD_TIME;
dieffect.cbTypeSpecificParams = sizeof(pforce);
dieffect.lpvTypeSpecificParams = &pforce;
dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS;
}
add the following code :
else if (IsEqualGUID(&pdei->guid, &GUID_Spring) ||
IsEqualGUID(&pdei->guid, &GUID_Damper) ||
IsEqualGUID(&pdei->guid, &GUID_Inertia) ||
IsEqualGUID(&pdei->guid, &GUID_Friction))
{
DICONDITION cxyforce[2];
int i;
for (i = 0; i < 2; ++i) {
cxyforce[i].lOffset = 0;
cxyforce[i].lPositiveCoefficient = DI_FFNOMINALMAX;
cxyforce[i].lNegativeCoefficient = DI_FFNOMINALMAX;
cxyforce[i].dwPositiveSaturation = DI_FFNOMINALMAX;
cxyforce[i].dwNegativeSaturation = DI_FFNOMINALMAX;
cxyforce[i].lDeadBand = 0;
}
dieffect.cbTypeSpecificParams = sizeof(cxyforce);
dieffect.lpvTypeSpecificParams = cxyforce;
dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS;
}
else if (IsEqualGUID(&pdei->guid, &GUID_CustomForce))
{
FIXME("Unhandled type specific parameters of CustomForce effect, this may lead to memory errors later on.\n");
}
else
WARN("Possibly unhandled type specific parameters of effect with guid %x.\n", pdei->guid);
b) Weirdly, I had to add these commands that evaluates the DIEFFECT pointers at the end of each if-case,
otherwise the pointers seemed to point to other address or data on that address was getting overwritten:
TRACE("&rforce=0x%x\n", &rforce);
TRACE("&cforce=0x%x\n", &cforce);
TRACE("&pforce=0x%x\n", &pforce);
TRACE("&cxyforce[0]=0x%x; &cxyforce[1]=0x%x\n", &(cxyforce[0]), &(cxyforce[1]));
More information about the wine-devel
mailing list