Hi Andy,
I think this code and your explanations look good. I'll give the patch a
run tonight when I get home but I do not see any problems with it.
- Frank
> Hi Internals
> Attached is a suggested patch for COM defect 35464
> (http://bugs.php.net/bug.php?id=34564) Any comments; good or bad
welcome.
> Regards
> Andy
>
> Andy Wharmby
> IBM United Kingdom Limited
> Winchester, England SO21 2JN
> E-mail: andy_wharmby@uk.ibm.com
>
> COM defect 35464
> ================
>
> The following details 2 reasons why in/out parameters don't work; one
> caused by a problem with tetscase another a defect in COM extension
code.
> The testcase supplied by the raiser implements the DWebBrowserEvents2
> interface to register an handler for the BeforeNaviagte2 event. This
> handler is passed just one in/out parameter; a VARIANT_BOOL which can
> be set to TRUE by the handler to cancel the navigation operation.
> Doing so in PHP currently has no affect, for the 2 reasons I will
> describe below, so the navigation completes and the specified page is
> displayed by IE.
>
> Issue 1
> ======
> The users code is attempting to modify the variant directly in PHP code
> as follows:
>
> $cancel = true;
>
> rather than using the COM method variant_set as follows:
>
> variant_set($cancel, true);
>
> With this correction to the PHP script in place the variant for $cancel
> is correctly changed to TRUE but IE still navigates to the requested
page
> so the modification is having no effect. The reason for this is the
> subject of issue 2 below.
>
> Issue 2
> ======
> When an event notification is received by the COM extension
> disp_invokeex() processes the incoming parameters (variants) by taking
> each one
> and wrapping it in a php_com_dotnet_object object. At this time a COPY
> of the incoming variant is embedded into the php_com_dotnet_object so
we
> immediately have 2 copies of the variant and it is this copy in the
> php_com_dotnet_object which is processed (get and set) by the PHP code.
> I see no code that checks for modification to our copy in the
> php_com_dotnet_object before returning to the caller (in this case IE)
> so modification
> to in/out parameters by the PHP code has no affect.
>
> Given that the code copies an incoming variant in php_com_wrap_variant()
> I would have expected to see some code prior to return in
disp_invokeex()
> which checks for modifications to in/out parameters and copies any
> modified values back to the callers copy of the variant.
>
> I have hacked some code as follows:
> com_wrapper.c: http://www.pastebin.ca/328026
> com_variant.c: http://www.pastebin.ca/328022
> com_misc.c: http://www.pastebin.ca/328025
> php_com_dotnet_internal.h: http://www.pastebin.ca/328027
>
> The new code works as follows:
> (1) When a variant is modified by a call to variant_set() in
> com_variant.c a new flag (obj->modified) is set in the
> php_com_dotnet_object.
>
> (2) After a successful call to a event handler new code in
> com_wrapper.c function disp_invokeex() checks each of the event
> handlers arguments
> (php_com_dotnet_object's ) to see if any of their embedded variants
> have been modified. If so and the argument passed into the event handler
was