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: [EMAIL PROTECTED] > > 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 > passed by reference then the value in the embedded variant is copied to > the callers copy by a call to a new function php_com_copy_variant() > defined in com_variant.c. > > With this patch applied when the supplied testcase is run the navigation > is now cancelled as expected. > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php