Descend through as many pointer types as necessary to find the
fundamental type and determine whether it needs a top-level parameter
conformance/variance expression to be written.
Add support for writing top-level parameter conformance/variance
expressions for non-encapsulated unions.
The 8 bytes are for the variance and offset and are added just before
the array, as seen in the marshalling code in rpcrt4. No offset needs
to be added for non-varying structures since the buffer mark is set
after the conformance in marshalled or unmarshalled.
Do so by calculating the alignment of members when iterating through
the structures and adding it onto the buffer and memory offsets.
Only call type_memsize once elsewhere in the embedded pointer
processing functions since the return value will be the same from the
second call.
The conformance needs to be added on to the offset in the buffer so
set this before calling each the writer of each class of pointer
description in write_pointer_description.
Pass the passed in offsets to buffer and memory to
write_pointer_description_offsets in
write_varying_array_pointer_descriptions.
This is because write_string_tfs has support for the full range of
string types, write_simple_pointer doesn't have access to the var
attributes which are needed to properly detect strings, and
write_string_tfs sets the typestring offset to after the pointer is
written and write_remoting_arg depends on this.
is_ptr cannot be used because it follows the chain of types into the
type which has the context_handle attribute, which is typically "void *"
and so causes these context handles to be incorrectly detected as
context handles. Instead, we can use is_aliaschain_ptr to follow the
chain of aliases without following pointers and the absence of the
context_handle attribute indicates that it must be present on a type
after following a pointer.
Fix the is_string_type function used for detecting strings by only
examining aliases instead of both aliases and pointers. This is due to
the requirement that pointers to strings be handled as pointers and so
not detected as strings.
It doesn't matter whether or not the array is declared as a pointer or
is declared using array subscripts - the array is still allocated by the
unmarshalling function and so needs to be freed.
Fix a typo that caused varying arrays never to be freed.
Fix another typo with the check for conformant arrays being performed
twice, redundantly.
Otherwise, writing a type at top-level could cause the pointer format
string to be used in non-top-level places which may cause memory
corruption during freeing.
write_embedded_types doesn't descend into all types contained by the
array or structure, so create a new function, type_has_pointers, for the
purpose of descending into all types and returning whether or not
pointers are present.
Therefore, needs_freeing would have to duplicate a lot of
write_remoting_arg in order to get the detection right. Because of
this, it is easier and will cause less problems in the future to
simply move the logic of needs_freeing into write_remoting_arg in the
appropriate handling code for the detected type.
There are other cases where calls to Free functions can be omitted (such
as types always unmarshalled using buffer memory with no embedded
pointers), but these are easier dealt with inside the relevent case in
write_remoting_arg.