Skip to content

Commit 52e1ff4

Browse files
author
Alan Brown
committed
Added support to display argument and EXCEPTINFO in appropriate places.
1 parent 3a1f3c5 commit 52e1ff4

File tree

4 files changed

+162
-46
lines changed

4 files changed

+162
-46
lines changed

ext/com/COM.c

Lines changed: 80 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,14 @@ static PHP_MINFO_FUNCTION(COM)
102102
DISPLAY_INI_ENTRIES();
103103
}
104104

105-
PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult TSRMLS_DC)
105+
PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, char **ErrString TSRMLS_DC)
106106
{
107107
HRESULT hr;
108108
int failed = FALSE;
109109
unsigned int ArgErr;
110110
EXCEPINFO ExceptInfo;
111111

112-
/* TODO: Make use of the ArgError when hr==E_INVALIDARG */
113-
/* TODO: Deal with the ExceptInfo structure in the error message */
112+
*ErrString = NULL;
114113
if(C_ISREFD(obj))
115114
{
116115
if(C_HASTLIB(obj))
@@ -136,6 +135,33 @@ PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DIS
136135
hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, &ExceptInfo, &ArgErr);
137136
}
138137

138+
if (FAILED(hr))
139+
{
140+
switch (hr)
141+
{
142+
case DISP_E_EXCEPTION:
143+
{
144+
int srclen;
145+
char *src = php_OLECHAR_to_char(ExceptInfo.bstrSource, &srclen, 1, codepage TSRMLS_CC);
146+
int desclen;
147+
char *desc = php_OLECHAR_to_char(ExceptInfo.bstrDescription, &desclen, 1, codepage TSRMLS_CC);
148+
*ErrString = pemalloc(srclen+desclen+50, 1);
149+
sprintf(*ErrString, "<b>Source</b>: %s <b>Description</b>: %s", src, desc);
150+
pefree(src, 1);
151+
pefree(desc, 1);
152+
SysFreeString(ExceptInfo.bstrSource);
153+
SysFreeString(ExceptInfo.bstrDescription);
154+
SysFreeString(ExceptInfo.bstrHelpFile);
155+
}
156+
break;
157+
case DISP_E_PARAMNOTFOUND:
158+
case DISP_E_TYPEMISMATCH:
159+
*ErrString = pemalloc(25, 1);
160+
sprintf(*ErrString, "<b>Argument</b>: %d", pDispParams->cArgs-ArgErr+1);
161+
break;
162+
}
163+
}
164+
139165
return hr;
140166
}
141167
else
@@ -550,7 +576,7 @@ PHP_FUNCTION(com_load)
550576
{
551577
php_COM_destruct(obj TSRMLS_CC);
552578
error_message = php_COM_error_message(hr TSRMLS_CC);
553-
php_error(E_WARNING,"Invalid ProgID or Moniker: %s\n", error_message);
579+
php_error(E_WARNING,"Invalid ProgID, GUID string, or Moniker: %s", error_message);
554580
LocalFree(error_message);
555581
RETURN_FALSE;
556582
}
@@ -589,7 +615,7 @@ PHP_FUNCTION(com_load)
589615
{
590616
error_message = php_COM_error_message(hr TSRMLS_CC);
591617
clsid_str = php_string_from_clsid(&clsid TSRMLS_CC);
592-
php_error(E_WARNING,"Unable to obtain IDispatch interface for CLSID %s: %s",clsid_str,error_message);
618+
php_error(E_WARNING,"Unable to obtain IDispatch interface for CLSID %s: %s",clsid_str,error_message);
593619
LocalFree(error_message);
594620
efree(clsid_str);
595621
php_COM_destruct(obj TSRMLS_CC);
@@ -673,7 +699,7 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
673699
break;
674700

675701
default:
676-
php_error(E_WARNING,"Wrong argument count to IEnumVariant::Next()\n");
702+
php_error(E_WARNING,"Wrong argument count to IEnumVariant::Next()");
677703

678704
return FAILURE;
679705
}
@@ -696,7 +722,7 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
696722
if(FAILED(hr = C_ENUMVARIANT_VT(obj)->Next(C_ENUMVARIANT(obj), count, pSA->pvData, &count)))
697723
{
698724
char *error_message = php_COM_error_message(hr TSRMLS_CC);
699-
php_error(E_WARNING,"IEnumVariant::Next() failed: %s\n", error_message);
725+
php_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
700726
efree(error_message);
701727
VariantClear(var_result);
702728
return FAILURE;
@@ -708,7 +734,7 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
708734
if(FAILED(SafeArrayRedim(pSA, rgsabound)))
709735
{
710736
char *error_message = php_COM_error_message(hr TSRMLS_CC);
711-
php_error(E_WARNING,"IEnumVariant::Next() failed: %s\n", error_message);
737+
php_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
712738
efree(error_message);
713739
VariantClear(var_result);
714740
return FAILURE;
@@ -722,7 +748,7 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
722748
if(FAILED(hr = C_ENUMVARIANT_VT(obj)->Reset(C_ENUMVARIANT(obj))))
723749
{
724750
char *error_message = php_COM_error_message(hr TSRMLS_CC);
725-
php_error(E_WARNING,"IEnumVariant::Next() failed: %s\n", error_message);
751+
php_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
726752
efree(error_message);
727753
return FAILURE;
728754
}
@@ -744,13 +770,13 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
744770
break;
745771

746772
default:
747-
php_error(E_WARNING,"Wrong argument count to IEnumVariant::Skip()\n");
773+
php_error(E_WARNING,"Wrong argument count to IEnumVariant::Skip()");
748774
return FAILURE;
749775
}
750776
if(FAILED(hr = C_ENUMVARIANT_VT(obj)->Skip(C_ENUMVARIANT(obj), count)))
751777
{
752778
char *error_message = php_COM_error_message(hr TSRMLS_CC);
753-
php_error(E_WARNING,"IEnumVariant::Next() failed: %s\n", error_message);
779+
php_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
754780
efree(error_message);
755781
return FAILURE;
756782
}
@@ -759,14 +785,16 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
759785
}
760786
else
761787
{
788+
char *ErrString;
789+
762790
funcname = php_char_to_OLECHAR(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), codepage TSRMLS_CC);
763791

764792
hr = php_COM_get_ids_of_names(obj, &funcname, &dispid TSRMLS_CC);
765793

766794
if(FAILED(hr))
767795
{
768796
error_message = php_COM_error_message(hr TSRMLS_CC);
769-
php_error(E_WARNING,"Unable to lookup %s: %s\n", Z_STRVAL_P(function_name), error_message);
797+
php_error(E_WARNING,"Unable to lookup %s: %s", Z_STRVAL_P(function_name), error_message);
770798
LocalFree(error_message);
771799
efree(funcname);
772800
return FAILURE;
@@ -785,7 +813,7 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
785813
dispparams.cArgs = arg_count;
786814
dispparams.cNamedArgs = 0;
787815

788-
hr = php_COM_invoke(obj, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result TSRMLS_CC);
816+
hr = php_COM_invoke(obj, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC);
789817

790818
efree(funcname);
791819
for (current_arg=0;current_arg<arg_count;current_arg++)
@@ -797,7 +825,15 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
797825
if(FAILED(hr))
798826
{
799827
error_message = php_COM_error_message(hr TSRMLS_CC);
800-
php_error(E_WARNING,"Invoke() failed: %s\n", error_message);
828+
if (ErrString)
829+
{
830+
php_error(E_WARNING,"Invoke() failed: %s %s", error_message, ErrString);
831+
pefree(ErrString, 1);
832+
}
833+
else
834+
{
835+
php_error(E_WARNING,"Invoke() failed: %s", error_message);
836+
}
801837
LocalFree(error_message);
802838
return FAILURE;
803839
}
@@ -945,7 +981,7 @@ static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property,
945981
OLECHAR *propname;
946982
char *error_message;
947983
DISPPARAMS dispparams;
948-
984+
char *ErrString;
949985

950986
/* obtain property handler */
951987
propname = php_char_to_OLECHAR(Z_STRVAL_P(arg_property), Z_STRLEN_P(arg_property), codepage TSRMLS_CC);
@@ -955,7 +991,7 @@ static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property,
955991
if(FAILED(hr))
956992
{
957993
error_message = php_COM_error_message(hr TSRMLS_CC);
958-
php_error(E_WARNING,"Unable to lookup %s: %s\n", Z_STRVAL_P(arg_property), error_message);
994+
php_error(E_WARNING,"Unable to lookup %s: %s", Z_STRVAL_P(arg_property), error_message);
959995
LocalFree(error_message);
960996
efree(propname);
961997
if(cleanup)
@@ -968,12 +1004,20 @@ static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property,
9681004
dispparams.cArgs = 0;
9691005
dispparams.cNamedArgs = 0;
9701006

971-
hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result TSRMLS_CC);
1007+
hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC);
9721008

9731009
if(FAILED(hr))
9741010
{
9751011
error_message = php_COM_error_message(hr TSRMLS_CC);
976-
php_error(E_WARNING,"PropGet() failed: %s\n", error_message);
1012+
if (ErrString)
1013+
{
1014+
php_error(E_WARNING,"PropGet() failed: %s %s", error_message, ErrString);
1015+
pefree(ErrString, 1);
1016+
}
1017+
else
1018+
{
1019+
php_error(E_WARNING,"PropGet() failed: %s", error_message);
1020+
}
9771021
LocalFree(error_message);
9781022
efree(propname);
9791023
if(cleanup)
@@ -1001,6 +1045,7 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
10011045
VARIANT *var_result, *new_value;
10021046
DISPPARAMS dispparams;
10031047
DISPID mydispid = DISPID_PROPERTYPUT;
1048+
char *ErrString;
10041049

10051050
ALLOC_VARIANT(var_result);
10061051
ALLOC_VARIANT(new_value);
@@ -1013,7 +1058,7 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
10131058
if(FAILED(hr))
10141059
{
10151060
error_message = php_COM_error_message(hr TSRMLS_CC);
1016-
php_error(E_WARNING,"Unable to lookup %s: %s\n", Z_STRVAL_P(arg_property), error_message);
1061+
php_error(E_WARNING,"Unable to lookup %s: %s", Z_STRVAL_P(arg_property), error_message);
10171062
LocalFree(error_message);
10181063
efree(propname);
10191064

@@ -1029,12 +1074,20 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
10291074
dispparams.cArgs = 1;
10301075
dispparams.cNamedArgs = 1;
10311076

1032-
hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYPUT, &dispparams, NULL TSRMLS_CC);
1077+
hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYPUT, &dispparams, NULL, &ErrString TSRMLS_CC);
10331078

10341079
if(FAILED(hr))
10351080
{
10361081
error_message = php_COM_error_message(hr TSRMLS_CC);
1037-
php_error(E_WARNING,"PropPut() failed: %s\n", error_message);
1082+
if (ErrString)
1083+
{
1084+
php_error(E_WARNING,"PropPut() failed: %s %s", error_message, ErrString);
1085+
pefree(ErrString, 1);
1086+
}
1087+
else
1088+
{
1089+
php_error(E_WARNING,"PropPut() failed: %s", error_message);
1090+
}
10381091
LocalFree(error_message);
10391092
efree(propname);
10401093

@@ -1047,7 +1100,7 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
10471100
dispparams.cArgs = 0;
10481101
dispparams.cNamedArgs = 0;
10491102

1050-
hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result TSRMLS_CC);
1103+
hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC);
10511104

10521105
if(SUCCEEDED(hr))
10531106
{
@@ -1059,6 +1112,11 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
10591112
zval_copy_ctor(return_value);
10601113
}
10611114

1115+
if (ErrString)
1116+
{
1117+
pefree(ErrString, 1);
1118+
}
1119+
10621120
FREE_VARIANT(var_result);
10631121
FREE_VARIANT(new_value);
10641122

ext/com/php_COM.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ PHP_FUNCTION(com_propput);
1919
PHP_FUNCTION(com_load_typelib);
2020
PHP_FUNCTION(com_isenum);
2121

22-
PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult TSRMLS_DC);
22+
PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, char **ErrString TSRMLS_DC);
2323
PHPAPI HRESULT php_COM_get_ids_of_names(comval *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId TSRMLS_DC);
2424
PHPAPI HRESULT php_COM_release(comval *obj TSRMLS_DC);
2525
PHPAPI HRESULT php_COM_addref(comval *obj TSRMLS_DC);

0 commit comments

Comments
 (0)