You can probably fix the immediate issue just by storing the return
value and releasing the reference if the QI failed.
The larger issue is that code becomes much easier to follow when you
can assume that functions are supposed to leave things (more or less)
the way they found them on failure. (Unless explicitly indicated.)
I.e., when d3drm_device_set_ddraw_device_d3d() releases all the
references it created when it fails, and d3drm1_CreateDeviceFromD3D()
can assume the device is in the same state as after calling
d3drm_device_create().
Of course the even larger issue is that
d3drm_device_set_ddraw_device_d3d() doesn't make a lot of sense. In a
way similar to e.g. d3drm3_CreateTexture(),
d3drm1_CreateDeviceFromD3D() should probably just call
IDirect3DRMDevice::InitFromD3D().