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

Reply via email to