If I get it right, the correct fix is to add a thunk vtable for IDirectDraw4 that uses relaxed parameter checks on AddAttachedSurface.
Most likely yes
[1] In fact, an API test is required. Strict or relaxed semantics might
also > depend on how the surface was created (from IDirectDraw4 or
IDirectDraw7) instead of the interfaced used to add an attached surface. This would be strange IMO, as the idea about COM is that the interface describes semantics that work regardless how the object was created, but let's test that, nevertheless.
Yes, a test is needed, no way around that. Other IDirectDrawSurface methods depend on how the object was created indeed, like GetDDInterface.
On a sidenode, I think it is impossible to QueryInterface IDirectDrawSurface7 from IDirectDrawSurface < 7, or vice versa, but I am not sure. I think there are tests for IDirectDrawX, more tests would never hurt.
I wonder if there is an easy way to do an API abstraction of some sort... not with a flag perse but like you can in C++ with the different instanciations depending upon the parms passed. Then instead of thunking , which is inherently buggy and tends to be slow, you use the v7 structure and return it without the v7 specific items at the end. That way you store one table instead of 2
I recommend to read how object orientation and inheritance are implemented on assembler level by the C++ compiler. It's multiple vtables and thunking in many places.
The C++ equivalent here would be to keep 2 vtables, which differ only in the implementation of the AddAttachedSurface and Flip functions, and otherwise use the same function pointers without thunks. C++ uses thunks e.g. in the case of multiple inheritance. A vtable construct like IDirectDrawSurface3, IDirectDrawSurface4, IDirectDrawSurface7 and IDirectDrawGammaControl on the same object in the same time is not really expressable as far as I can see.
Thunks are not a pressing performance issue in general, but I want to avoid them if its possible in a clean way, since the 0.5-1.0% performance gains are where you gain your framerate differences that matter to the user.