Demirug
2005-11-12, 17:42:13
Bevor ich jetzt wieder anfange mehrere Lösungen auszuprobieren und zu Benchen frage ich doch erst mal nach.
Problembeschreibung:
Über ein COM Interface wird ein anderes COM Interface übergeben. Wird nun ein dabei ein ungültiger Zeiger übergeben kommt es zu einer Read Access Violation. Der damit verbundene Absturz muss verhindert werden
Der reale Fall:
Bei einer DirectX 6.1 Emulation werden alle relevanten Interfaces implementiert. Einiges dieser Interface Methode bekommen selbst wieder ein anderes DirectX Objekt als Zeiger auf ein entsprechendes Interface übergeben. Eines dieser Methode ist Blt aus dem IDirectDrawSurface4. Intern wird der Zeiger auf das Interface wieder in einen Zeiger auf das echte Objekt gewandelt. Dazu wird ein internes erweitertes IDirectDrawSurface4 Interface benutzt. Das ganze funktioniert auch ohne Probleme solange die übergebenen Interfacezeiger auch wirklich von einem solchen Objekt kommen. Leider gibt es nun mindestens ein Spiel von „Jane's Combat Simulations“ das an dieser Stelle plötzlich ohne erkennbaren Grund einen wilden Zeiger übergibt. DirectX 6.1 erkennt allerdings solche wilden Zeiger fängt sie ab und beendet die Methode mit einem Fehlercode. Das entsprechenden Spiel bleibt spielbar und es sind keine Beeinträchtigungen oder Fehldarstellungen zu sehen. Daraus ergibt sich nun das die Emulation sich entsprechend verhalten muss.
Aus diesem Grund habe ich die ursprüngliche Methode
DirectDrawSurface* GetDDSurface (D3D7::IDirectDrawSurface4* pSurface)
{
if (pSurface == NULL)
return NULL;
IDirectDrawSurface4Intern* pIntern = (IDirectDrawSurface4Intern*)pSurface;
return pIntern->GetOriginalObject ();
}
durch diese ersetzt
DirectDrawSurface* GetDDSurface (D3D7::IDirectDrawSurface4* pSurface , bool& rOK)
{
if (pSurface == NULL)
{
rOK = true;
return NULL;
}
try
{
IDirectDrawSurface4Intern* pIntern = (IDirectDrawSurface4Intern*)pSurface;
rOK = true;
return pIntern->GetOriginalObject ();
}
catch (...)
{
rOK = false;
return NULL;
}
}
Das Problem der Read Access Violation ist damit unterbunden und das Spiel läuft an dieser Stelle wie mit dem Original DirectX 6.1
Da diese Konvertierungsfunktion jedoch recht häufig ausgeführt werden muss bin ich an einer Lösung interessiert die performanter ist.
Problembeschreibung:
Über ein COM Interface wird ein anderes COM Interface übergeben. Wird nun ein dabei ein ungültiger Zeiger übergeben kommt es zu einer Read Access Violation. Der damit verbundene Absturz muss verhindert werden
Der reale Fall:
Bei einer DirectX 6.1 Emulation werden alle relevanten Interfaces implementiert. Einiges dieser Interface Methode bekommen selbst wieder ein anderes DirectX Objekt als Zeiger auf ein entsprechendes Interface übergeben. Eines dieser Methode ist Blt aus dem IDirectDrawSurface4. Intern wird der Zeiger auf das Interface wieder in einen Zeiger auf das echte Objekt gewandelt. Dazu wird ein internes erweitertes IDirectDrawSurface4 Interface benutzt. Das ganze funktioniert auch ohne Probleme solange die übergebenen Interfacezeiger auch wirklich von einem solchen Objekt kommen. Leider gibt es nun mindestens ein Spiel von „Jane's Combat Simulations“ das an dieser Stelle plötzlich ohne erkennbaren Grund einen wilden Zeiger übergibt. DirectX 6.1 erkennt allerdings solche wilden Zeiger fängt sie ab und beendet die Methode mit einem Fehlercode. Das entsprechenden Spiel bleibt spielbar und es sind keine Beeinträchtigungen oder Fehldarstellungen zu sehen. Daraus ergibt sich nun das die Emulation sich entsprechend verhalten muss.
Aus diesem Grund habe ich die ursprüngliche Methode
DirectDrawSurface* GetDDSurface (D3D7::IDirectDrawSurface4* pSurface)
{
if (pSurface == NULL)
return NULL;
IDirectDrawSurface4Intern* pIntern = (IDirectDrawSurface4Intern*)pSurface;
return pIntern->GetOriginalObject ();
}
durch diese ersetzt
DirectDrawSurface* GetDDSurface (D3D7::IDirectDrawSurface4* pSurface , bool& rOK)
{
if (pSurface == NULL)
{
rOK = true;
return NULL;
}
try
{
IDirectDrawSurface4Intern* pIntern = (IDirectDrawSurface4Intern*)pSurface;
rOK = true;
return pIntern->GetOriginalObject ();
}
catch (...)
{
rOK = false;
return NULL;
}
}
Das Problem der Read Access Violation ist damit unterbunden und das Spiel läuft an dieser Stelle wie mit dem Original DirectX 6.1
Da diese Konvertierungsfunktion jedoch recht häufig ausgeführt werden muss bin ich an einer Lösung interessiert die performanter ist.