Ohforf's method does indeed work, I'm sorry for saying it didn't. In fact, it's the only method I've found that reconstructs the position faithfully. The reconstructed position maps are indistinguishable from the raw position maps, and it works great for deferred point lights.
Unfortunately, I couldn't get SSAO to work properly using position from depth. I tried two completely different implementations, both work perfectly when passing an actual position map (D3DFMT_A32B32G32R32F). I think the problem is where it samples from a small offset of the main point.
// ambient occlusion pixel shader // main point is working float3 p=getPosition(input.uv); // I think this is where the problems lie float3 p1=getPosition(input.uv+small_offset);
But like I wrote, it works perfectly using an actual position map. I don't get it.
Thanks for all the help.