(#23183) Use FFI to manage pointers in RootCerts module

Previously, we made assumptions about the layout of the CERT_CONTEXT
structure, specifically that PCERT_INFO (pointer to CERT_CONTEXT) was an
unsigned 32-bit integer ('L'), and magically accessed the size of the
returned structure as arr[2]. We were also memcpy 40-bytes which was
larger than the size of the CERT_CONTEXT structure in both x86 and x64 and
was the cause of infrequent segmentation faults.

This commit uses FFI to define the layout of the CERT_CONTEXT structure, uses
named fields, e.g. [:cbCertEncoded], to access offsets within the structure,
and uses the FFI::Pointer#null? method to check for NULL pointer.

Note that we use FFI::Pointer and not MemoryPointer, because the
CertEnumCertificatesInStore function is responsible for freeing the
previous CERT_CONTEXT pointer, not us.

Also in the motto of "don't stub what you don't own" it exercises the Win32
APIs to make the tests more meaningful.
Merge pull request #2079 from joshcooper/ticket/stable/23183-ffi-rootcerts

(#23183) Use FFI to manage pointers in RootCerts module
Merge branch 'stable'