(PUP-2738) - Refactor FFI memory consumption / usage

~~- Causes 14 test fails with Invalid Memory Object, so might
   be on to something here~~
~~- one of the MemoryPointer auto-free / block style calls has been
   removed from windows/file.rb ... resulting in 28 less failures
   need to investigate further~~
I think this is what you mean?

```ruby
rval = nil
FFI::MemoryPointer.new(REPARSE_DATA_BUFFER.size) do |reparse_data_buffer_ptr|
  device_io_control(handle, FSCTL_GET_REPARSE_POINT, nil, reparse_data_buffer_ptr)
  rval = REPARSE_DATA_BUFFER.new(reparse_data_buffer_ptr)
end

rval
```


If you look at the single caller (`resolve_symlink`), we can still index into the struct properly, and read out the string value, so we're yielding the struct.  

I will test your suggestion, but I don't think that it's going to work.  As it stands in the PR:

* First we allocate the bytes based on the struct size with MemoryPointer (which now owns it)
* That pointer to that unmanaged memory is passed to `device_io_control` and filled in by Win32 API
* The struct is used to essentially cast the `MemoryPointer`, and then that is returned to the caller, in this case `resolve_symlink`, so that values may be read out of the struct.

When an `FFI::Struct` is given a pointer, it doesn't allocate any memory / copy anything from the pointer.  It acts as basically a pointer arithmetic helper of sorts.  In other words, we don't want the `MemoryPointer` to get cleaned up before we've used the struct.

https://github.com/ffi/ffi/wiki/Structs#when-allocated