summaryrefslogtreecommitdiff
path: root/ext/com
diff options
context:
space:
mode:
authorHarald Radi <phanto@php.net>2001-08-13 23:39:11 +0000
committerHarald Radi <phanto@php.net>2001-08-13 23:39:11 +0000
commit9c6b9eb76bb493f0166eb6c1661721c54d93129e (patch)
treefa230a9374a7fee31fa10210366ff73dff99393e /ext/com
parentbb0858db348ab3ce3b9cb1e480695b8ad1d65849 (diff)
downloadphp-git-9c6b9eb76bb493f0166eb6c1661721c54d93129e.tar.gz
merged from EXPERIMENTAL
lots of cleanup work
Diffstat (limited to 'ext/com')
-rw-r--r--ext/com/COM.c504
-rw-r--r--ext/com/VARIANT.c68
-rw-r--r--ext/com/com.h16
-rw-r--r--ext/com/conversion.c604
-rw-r--r--ext/com/conversion.h10
-rw-r--r--ext/com/php_COM.h36
-rw-r--r--ext/com/php_VARIANT.h11
-rw-r--r--ext/com/variant.h8
8 files changed, 698 insertions, 559 deletions
diff --git a/ext/com/COM.c b/ext/com/COM.c
index ee1fbc8c6c..0063f426b1 100644
--- a/ext/com/COM.c
+++ b/ext/com/COM.c
@@ -14,6 +14,7 @@
+----------------------------------------------------------------------+
| Author: Zeev Suraski <zeev@zend.com> |
| Harald Radi <h.radi@nme.at> |
+ | Alan Brown <abrown@pobox.com> |
+----------------------------------------------------------------------+
*/
@@ -60,31 +61,14 @@
#include "php.h"
#include "php_ini.h"
-#include "com.h"
-#include "conversion.h"
+#include "php_COM.h"
#include "php_VARIANT.h"
-zend_class_entry com_class_entry;
-
-PHP_FUNCTION(com_load);
-PHP_FUNCTION(com_invoke);
-PHP_FUNCTION(com_addref);
-PHP_FUNCTION(com_release);
-PHP_FUNCTION(com_propget);
-PHP_FUNCTION(com_propput);
-PHP_FUNCTION(com_load_typelib);
-PHP_FUNCTION(com_isenum);
-
-PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult);
-PHPAPI HRESULT php_COM_get_ids_of_names(comval *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId);
-PHPAPI HRESULT php_COM_release(comval *obj);
-PHPAPI HRESULT php_COM_addref(comval *obj);
-PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* pDisp, int cleanup);
-PHPAPI HRESULT php_COM_clone(comval *obj, comval *clone, int cleanup);
-
-PHPAPI int php_COM_get_le_comval();
-static ITypeLib *php_COM_find_typelib(char *search_string, int mode);
+static ITypeLib *php_COM_find_typelib(char *search_string, int mode TSRMLS_DC);
static int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC);
+static int do_COM_offget(VARIANT *result, comval *array, pval *property, int cleanup TSRMLS_DC);
+static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property, int cleanup TSRMLS_DC);
+static void php_register_COM_class(TSRMLS_D);
static int le_comval;
static int codepage;
@@ -118,19 +102,22 @@ static PHP_MINFO_FUNCTION(COM)
DISPLAY_INI_ENTRIES();
}
-PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult)
+PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, char **ErrString TSRMLS_DC)
{
HRESULT hr;
int failed = FALSE;
+ unsigned int ArgErr;
+ EXCEPINFO ExceptInfo;
+ *ErrString = NULL;
if(C_ISREFD(obj))
{
if(C_HASTLIB(obj))
{
- hr = C_TYPEINFO_VT(obj)->Invoke(C_TYPEINFO(obj), C_DISPATCH(obj), dispIdMember, wFlags, pDispParams, pVarResult, NULL, NULL);
+ hr = C_TYPEINFO_VT(obj)->Invoke(C_TYPEINFO(obj), C_DISPATCH(obj), dispIdMember, wFlags, pDispParams, pVarResult, &ExceptInfo, &ArgErr);
if(FAILED(hr))
{
- hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, NULL, NULL);
+ hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, &ExceptInfo, &ArgErr);
if(SUCCEEDED(hr))
{
/*
@@ -145,7 +132,34 @@ PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DIS
}
else
{
- hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, NULL, NULL);
+ hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, &ExceptInfo, &ArgErr);
+ }
+
+ if (FAILED(hr))
+ {
+ switch (hr)
+ {
+ case DISP_E_EXCEPTION:
+ {
+ int srclen;
+ char *src = php_OLECHAR_to_char(ExceptInfo.bstrSource, &srclen, 1, codepage TSRMLS_CC);
+ int desclen;
+ char *desc = php_OLECHAR_to_char(ExceptInfo.bstrDescription, &desclen, 1, codepage TSRMLS_CC);
+ *ErrString = pemalloc(srclen+desclen+50, 1);
+ sprintf(*ErrString, "<b>Source</b>: %s <b>Description</b>: %s", src, desc);
+ pefree(src, 1);
+ pefree(desc, 1);
+ SysFreeString(ExceptInfo.bstrSource);
+ SysFreeString(ExceptInfo.bstrDescription);
+ SysFreeString(ExceptInfo.bstrHelpFile);
+ }
+ break;
+ case DISP_E_PARAMNOTFOUND:
+ case DISP_E_TYPEMISMATCH:
+ *ErrString = pemalloc(25, 1);
+ sprintf(*ErrString, "<b>Argument</b>: %d", pDispParams->cArgs-ArgErr+1);
+ break;
+ }
}
return hr;
@@ -156,7 +170,7 @@ PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DIS
}
}
-PHPAPI HRESULT php_COM_get_ids_of_names(comval *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId)
+PHPAPI HRESULT php_COM_get_ids_of_names(comval *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId TSRMLS_DC)
{
HRESULT hr;
@@ -195,8 +209,10 @@ PHPAPI HRESULT php_COM_get_ids_of_names(comval *obj, OLECHAR FAR* FAR* rgszNames
}
}
-PHPAPI HRESULT php_COM_release(comval *obj)
+PHPAPI HRESULT php_COM_release(comval *obj TSRMLS_DC)
{
+ HRESULT hr;
+
if(obj->refcount > 1)
{
C_RELEASE(obj);
@@ -209,16 +225,16 @@ PHPAPI HRESULT php_COM_release(comval *obj)
}
if(C_HASENUM(obj))
{
- C_ENUMVARIANT_VT(obj)->Release(C_ENUMVARIANT(obj));
+ hr = C_ENUMVARIANT_VT(obj)->Release(C_ENUMVARIANT(obj));
}
- C_DISPATCH_VT(obj)->Release(C_DISPATCH(obj));
+ hr = C_DISPATCH_VT(obj)->Release(C_DISPATCH(obj));
C_RELEASE(obj);
}
return obj->refcount;
}
-PHPAPI HRESULT php_COM_addref(comval *obj)
+PHPAPI HRESULT php_COM_addref(comval *obj TSRMLS_DC)
{
if(C_ISREFD(obj))
{
@@ -228,13 +244,19 @@ PHPAPI HRESULT php_COM_addref(comval *obj)
return obj->refcount;
}
-PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* pDisp, int cleanup)
+PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* FAR* ppDisp, int cleanup TSRMLS_DC)
{
HRESULT hr = 1;
DISPPARAMS dispparams;
- VARIANT var_result;
+ VARIANT *var_result;
+ IDispatch FAR* pDisp;
- VariantInit(&var_result);
+ pDisp = *ppDisp;
+ if(cleanup)
+ {
+ *ppDisp = NULL;
+ }
+
C_REFCOUNT(obj) = 1;
C_DISPATCH(obj) = pDisp;
C_HASTLIB(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->GetTypeInfo(C_DISPATCH(obj), 0, LANG_NEUTRAL, &C_TYPEINFO(obj)));
@@ -244,22 +266,26 @@ PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* pDisp, int cleanup)
dispparams.cArgs = 0;
dispparams.cNamedArgs = 0;
+ ALLOC_VARIANT(var_result);
+
if(C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
- DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, &var_result, NULL, NULL)))
+ DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL)))
{
- if (V_VT(&var_result) == VT_UNKNOWN)
+ if(V_VT(var_result) == VT_UNKNOWN)
{
- C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(&var_result)->lpVtbl->QueryInterface(V_UNKNOWN(&var_result), &IID_IEnumVARIANT,
+ C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT,
(void**)&C_ENUMVARIANT(obj)));
}
- else if (V_VT(&var_result) == VT_DISPATCH)
+ else if(V_VT(var_result) == VT_DISPATCH)
{
- C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(&var_result)->lpVtbl->QueryInterface(V_DISPATCH(&var_result), &IID_IEnumVARIANT,
+ C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT,
(void**)&C_ENUMVARIANT(obj)));
}
}
+ FREE_VARIANT(var_result);
+
if(!cleanup)
{
hr = C_DISPATCH_VT(obj)->AddRef(C_DISPATCH(obj));
@@ -272,7 +298,7 @@ PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* pDisp, int cleanup)
return hr;
}
-PHPAPI HRESULT php_COM_clone(comval *obj, comval *clone, int cleanup)
+PHPAPI HRESULT php_COM_clone(comval *obj, comval *clone, int cleanup TSRMLS_DC)
{
HRESULT hr;
@@ -307,7 +333,7 @@ PHPAPI HRESULT php_COM_clone(comval *obj, comval *clone, int cleanup)
return hr;
}
-PHPAPI char *php_COM_error_message(HRESULT hr)
+PHPAPI char *php_COM_error_message(HRESULT hr TSRMLS_DC)
{
void *pMsgBuf;
@@ -323,28 +349,35 @@ PHPAPI char *php_COM_error_message(HRESULT hr)
return pMsgBuf;
}
-static char *php_string_from_clsid(const CLSID *clsid)
+static char *php_string_from_clsid(const CLSID *clsid TSRMLS_DC)
{
LPOLESTR ole_clsid;
char *clsid_str;
StringFromCLSID(clsid, &ole_clsid);
- clsid_str = php_OLECHAR_to_char(ole_clsid, NULL, 0, codepage);
+ clsid_str = php_OLECHAR_to_char(ole_clsid, NULL, 0, codepage TSRMLS_CC);
LocalFree(ole_clsid);
return clsid_str;
}
-static void php_comval_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+PHPAPI HRESULT php_COM_destruct(comval *obj TSRMLS_DC)
{
- comval *obj = (comval *)rsrc->ptr;
+ HRESULT hr = S_OK;
if(C_ISREFD(obj))
{
C_REFCOUNT(obj) = 1;
- php_COM_release(obj);
+ hr = php_COM_release(obj TSRMLS_CC);
}
efree(obj);
+
+ return hr;
+}
+
+static void php_comval_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+ php_COM_destruct(rsrc->ptr TSRMLS_CC);
}
static PHP_INI_MH(OnTypelibFileChange)
@@ -353,7 +386,6 @@ static PHP_INI_MH(OnTypelibFileChange)
char *typelib_name_buffer;
char *strtok_buf = NULL;
int interactive;
-
interactive = CG(interactive);
if(!new_value || (typelib_file = VCWD_FOPEN(new_value, "r"))==NULL)
@@ -407,12 +439,12 @@ static PHP_INI_MH(OnTypelibFileChange)
ptr--;
}
-
if(interactive)
{
printf("\rLoading %-60s\r", typelib_name);
}
- if((pTL = php_COM_find_typelib(typelib_name, mode)) != NULL)
+
+ if((pTL = php_COM_find_typelib(typelib_name, mode TSRMLS_CC)) != NULL)
{
php_COM_load_typelib(pTL, mode TSRMLS_CC);
pTL->lpVtbl->Release(pTL);
@@ -507,9 +539,9 @@ PHP_FUNCTION(com_load)
}
}
+ ALLOC_COM(obj);
convert_to_string_ex(&module_name);
- ProgID = php_char_to_OLECHAR(Z_STRVAL_P(module_name), Z_STRLEN_P(module_name), codepage);
- obj = (comval *) emalloc(sizeof(comval));
+ ProgID = php_char_to_OLECHAR(Z_STRVAL_P(module_name), Z_STRLEN_P(module_name), codepage TSRMLS_CC);
/* obtain CLSID */
if(FAILED(CLSIDFromString(ProgID, &clsid)))
@@ -542,9 +574,9 @@ PHP_FUNCTION(com_load)
if(FAILED(hr))
{
- efree(obj);
- error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "Invalid ProgID or Moniker: %s\n", error_message);
+ php_COM_destruct(obj TSRMLS_CC);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"Invalid ProgID, GUID string, or Moniker: %s", error_message);
LocalFree(error_message);
RETURN_FALSE;
}
@@ -564,7 +596,7 @@ PHP_FUNCTION(com_load)
server_info.dwReserved1=0;
server_info.dwReserved2=0;
- server_info.pwszName = php_char_to_OLECHAR(Z_STRVAL_P(server_name), Z_STRLEN_P(server_name), codepage);
+ server_info.pwszName = php_char_to_OLECHAR(Z_STRVAL_P(server_name), Z_STRLEN_P(server_name), codepage TSRMLS_CC);
server_info.pAuthInfo=NULL;
pResults.pIID = &IID_IDispatch;
@@ -581,17 +613,17 @@ PHP_FUNCTION(com_load)
if(FAILED(hr))
{
- error_message = php_COM_error_message(hr);
- clsid_str = php_string_from_clsid(&clsid);
- php_error(E_WARNING, "Unable to obtain IDispatch interface for CLSID %s: %s", clsid_str, error_message);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ clsid_str = php_string_from_clsid(&clsid TSRMLS_CC);
+ php_error(E_WARNING,"Unable to obtain IDispatch interface for CLSID %s: %s",clsid_str,error_message);
LocalFree(error_message);
efree(clsid_str);
- efree(obj);
+ php_COM_destruct(obj TSRMLS_CC);
RETURN_FALSE;
}
}
- php_COM_set(obj, C_DISPATCH(obj), TRUE);
+ php_COM_set(obj, &C_DISPATCH(obj), TRUE TSRMLS_CC);
if(INI_INT("com.autoregister_casesensitive"))
{
@@ -617,7 +649,7 @@ PHP_FUNCTION(com_load)
{
ITypeLib *pTL;
- if((pTL = php_COM_find_typelib(Z_STRVAL_P(typelib), mode)) != NULL)
+ if((pTL = php_COM_find_typelib(Z_STRVAL_P(typelib), mode TSRMLS_CC)) != NULL)
{
C_HASTLIB(obj) = SUCCEEDED(pTL->lpVtbl->GetTypeInfo(pTL, 0, &C_TYPEINFO(obj)));
/* idx 0 should deliver the ITypeInfo for the IDispatch Interface */
@@ -635,7 +667,7 @@ PHP_FUNCTION(com_load)
/* }}} */
-int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **arguments, int arg_count)
+int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **arguments, int arg_count TSRMLS_DC)
{
DISPID dispid;
HRESULT hr;
@@ -667,8 +699,7 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
break;
default:
- /* TODO: complain about wrong arg count */
- php_error(E_WARNING, "Wrong argument count to IEnumVariant::Next()\n");
+ php_error(E_WARNING,"Wrong argument count to IEnumVariant::Next()");
return FAILURE;
}
@@ -679,6 +710,7 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
if((pSA = SafeArrayCreate(VT_VARIANT, 1, rgsabound)) == NULL)
{
VariantInit(var_result);
+
return FAILURE;
}
else
@@ -689,11 +721,10 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
if(FAILED(hr = C_ENUMVARIANT_VT(obj)->Next(C_ENUMVARIANT(obj), count, pSA->pvData, &count)))
{
- char *error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "IEnumVariant::Next() failed: %s\n", error_message);
+ char *error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
efree(error_message);
- SafeArrayDestroy(pSA);
- VariantInit(var_result);
+ VariantClear(var_result);
return FAILURE;
}
@@ -702,11 +733,10 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
rgsabound[0].cElements = count;
if(FAILED(SafeArrayRedim(pSA, rgsabound)))
{
- char *error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "IEnumVariant::Next() failed: %s\n", error_message);
+ char *error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
efree(error_message);
- SafeArrayDestroy(pSA);
- VariantInit(var_result);
+ VariantClear(var_result);
return FAILURE;
}
}
@@ -717,8 +747,8 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
{
if(FAILED(hr = C_ENUMVARIANT_VT(obj)->Reset(C_ENUMVARIANT(obj))))
{
- char *error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "IEnumVariant::Next() failed: %s\n", error_message);
+ char *error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
efree(error_message);
return FAILURE;
}
@@ -740,13 +770,13 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
break;
default:
- php_error(E_WARNING, "Wrong argument count to IEnumVariant::Skip()\n");
+ php_error(E_WARNING,"Wrong argument count to IEnumVariant::Skip()");
return FAILURE;
}
if(FAILED(hr = C_ENUMVARIANT_VT(obj)->Skip(C_ENUMVARIANT(obj), count)))
{
- char *error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "IEnumVariant::Next() failed: %s\n", error_message);
+ char *error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
efree(error_message);
return FAILURE;
}
@@ -755,14 +785,16 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
}
else
{
- funcname = php_char_to_OLECHAR(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), codepage);
+ char *ErrString;
+
+ funcname = php_char_to_OLECHAR(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), codepage TSRMLS_CC);
- hr = php_COM_get_ids_of_names(obj, &funcname, &dispid);
+ hr = php_COM_get_ids_of_names(obj, &funcname, &dispid TSRMLS_CC);
if(FAILED(hr))
{
- error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "Unable to lookup %s: %s\n", Z_STRVAL_P(function_name), error_message);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"Unable to lookup %s: %s", Z_STRVAL_P(function_name), error_message);
LocalFree(error_message);
efree(funcname);
return FAILURE;
@@ -773,7 +805,7 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
for(current_arg=0; current_arg<arg_count; current_arg++)
{
current_variant = arg_count - current_arg - 1;
- php_pval_to_variant(arguments[current_arg], &variant_args[current_variant], codepage);
+ php_pval_to_variant(arguments[current_arg], &variant_args[current_variant], codepage TSRMLS_CC);
}
dispparams.rgvarg = variant_args;
@@ -781,15 +813,27 @@ int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **
dispparams.cArgs = arg_count;
dispparams.cNamedArgs = 0;
- hr = php_COM_invoke(obj, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result);
+ hr = php_COM_invoke(obj, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC);
efree(funcname);
+ for (current_arg=0;current_arg<arg_count;current_arg++)
+ {
+ VariantClear(&variant_args[current_arg]);
+ }
efree(variant_args);
if(FAILED(hr))
{
- error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "Invoke() failed: %s\n", error_message);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ if (ErrString)
+ {
+ php_error(E_WARNING,"Invoke() failed: %s %s", error_message, ErrString);
+ pefree(ErrString, 1);
+ }
+ else
+ {
+ php_error(E_WARNING,"Invoke() failed: %s", error_message);
+ }
LocalFree(error_message);
return FAILURE;
}
@@ -807,14 +851,14 @@ PHP_FUNCTION(com_invoke)
comval *obj;
int type;
int arg_count = ZEND_NUM_ARGS();
- VARIANT var_result;
+ VARIANT *var_result;
if(arg_count<2)
{
WRONG_PARAM_COUNT;
}
arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
- if(getParametersArray(ht, arg_count, arguments)==FAILURE)
+ if(getParametersArray(ht, arg_count, arguments) == FAILURE)
{
RETURN_FALSE;
}
@@ -827,20 +871,27 @@ PHP_FUNCTION(com_invoke)
obj = (comval *)zend_list_find(Z_LVAL_P(object), &type);
if(!obj || (type != IS_COM))
{
- php_error(E_WARNING, "%d is not a COM object handler", Z_STRVAL_P(function_name));
+ php_error(E_WARNING,"%d is not a COM object handler", Z_STRVAL_P(function_name));
RETURN_FALSE;
}
/* obtain property/method handler */
convert_to_string_ex(&function_name);
- if(do_COM_invoke(obj, function_name, &var_result, arguments+2, arg_count-2)==FAILURE)
+ ALLOC_VARIANT(var_result);
+
+ if(do_COM_invoke(obj, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE)
{
+ FREE_VARIANT(var_result);
+ efree(arguments);
+
RETURN_FALSE;
}
- efree(arguments);
- php_variant_to_pval(&var_result, return_value, 0, codepage);
+ php_variant_to_pval(var_result, return_value, FALSE, codepage TSRMLS_CC);
+
+ FREE_VARIANT(var_result);
+ efree(arguments);
}
/* }}} */
@@ -868,11 +919,11 @@ PHP_FUNCTION(com_release)
obj = (comval *)zend_list_find(Z_LVAL_P(object), &type);
if(!obj || (type != IS_COM))
{
- php_error(E_WARNING, "%d is not a COM object handler");
+ php_error(E_WARNING,"%d is not a COM object handler");
RETURN_FALSE;
}
- RETURN_LONG(php_COM_release(obj))
+ RETURN_LONG(php_COM_release(obj TSRMLS_CC))
}
/* }}} */
@@ -900,53 +951,52 @@ PHP_FUNCTION(com_addref)
obj = (comval *)zend_list_find(Z_LVAL_P(object), &type);
if(!obj || (type != IS_COM))
{
- php_error(E_WARNING, "%d is not a COM object handler");
+ php_error(E_WARNING,"%d is not a COM object handler");
RETURN_FALSE;
}
- RETURN_LONG(php_COM_addref(obj));
+ RETURN_LONG(php_COM_addref(obj TSRMLS_CC));
}
/* }}} */
-static int do_COM_offget(VARIANT *result, comval *array, pval *property, int cleanup)
+static int do_COM_offget(VARIANT *result, comval *array, pval *property, int cleanup TSRMLS_DC)
{
pval function_name;
int retval;
ZVAL_STRINGL(&function_name, "Item", 4, 0);
- retval = do_COM_invoke(array, &function_name, result, &property, 1);
+ retval = do_COM_invoke(array, &function_name, result, &property, 1 TSRMLS_CC);
if(cleanup)
{
- php_COM_release(array);
- efree(array);
+ php_COM_destruct(array TSRMLS_CC);
}
return retval;
}
-static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property, int cleanup)
+static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property, int cleanup TSRMLS_DC)
{
DISPID dispid;
HRESULT hr;
OLECHAR *propname;
char *error_message;
DISPPARAMS dispparams;
-
+ char *ErrString;
/* obtain property handler */
- propname = php_char_to_OLECHAR(Z_STRVAL_P(arg_property), Z_STRLEN_P(arg_property), codepage);
+ propname = php_char_to_OLECHAR(Z_STRVAL_P(arg_property), Z_STRLEN_P(arg_property), codepage TSRMLS_CC);
- hr = php_COM_get_ids_of_names(obj, &propname, &dispid);
+ hr = php_COM_get_ids_of_names(obj, &propname, &dispid TSRMLS_CC);
if(FAILED(hr))
{
- error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "Unable to lookup %s: %s\n", Z_STRVAL_P(arg_property), error_message);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"Unable to lookup %s: %s", Z_STRVAL_P(arg_property), error_message);
LocalFree(error_message);
efree(propname);
if(cleanup)
{
- php_COM_release(obj);
+ php_COM_destruct(obj TSRMLS_CC);
}
return FAILURE;
}
@@ -954,17 +1004,25 @@ static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property,
dispparams.cArgs = 0;
dispparams.cNamedArgs = 0;
- hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result);
+ hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC);
if(FAILED(hr))
{
- error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "PropGet() failed: %s\n", error_message);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ if (ErrString)
+ {
+ php_error(E_WARNING,"PropGet() failed: %s %s", error_message, ErrString);
+ pefree(ErrString, 1);
+ }
+ else
+ {
+ php_error(E_WARNING,"PropGet() failed: %s", error_message);
+ }
LocalFree(error_message);
efree(propname);
if(cleanup)
{
- php_COM_release(obj);
+ php_COM_destruct(obj TSRMLS_CC);
}
return FAILURE;
}
@@ -972,65 +1030,81 @@ static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property,
efree(propname);
if(cleanup)
{
- php_COM_release(obj);
+ php_COM_destruct(obj TSRMLS_CC);
}
return SUCCESS;
}
-static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property, pval *value)
+static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property, pval *value TSRMLS_DC)
{
DISPID dispid;
HRESULT hr;
OLECHAR *propname;
char *error_message;
- VARIANT *var_result;
+ VARIANT *var_result, *new_value;
DISPPARAMS dispparams;
- VARIANT new_value;
DISPID mydispid = DISPID_PROPERTYPUT;
-
+ char *ErrString;
ALLOC_VARIANT(var_result);
+ ALLOC_VARIANT(new_value);
/* obtain property handler */
- propname = php_char_to_OLECHAR(Z_STRVAL_P(arg_property), Z_STRLEN_P(arg_property), codepage);
+ propname = php_char_to_OLECHAR(Z_STRVAL_P(arg_property), Z_STRLEN_P(arg_property), codepage TSRMLS_CC);
- hr = php_COM_get_ids_of_names(obj, &propname, &dispid);
+ hr = php_COM_get_ids_of_names(obj, &propname, &dispid TSRMLS_CC);
if(FAILED(hr))
{
- error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "Unable to lookup %s: %s\n", Z_STRVAL_P(arg_property), error_message);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"Unable to lookup %s: %s", Z_STRVAL_P(arg_property), error_message);
LocalFree(error_message);
efree(propname);
+
+ FREE_VARIANT(var_result);
+ FREE_VARIANT(new_value);
+
RETURN_FALSE;
}
- php_pval_to_variant(value, &new_value, codepage);
- dispparams.rgvarg = &new_value;
+ php_pval_to_variant(value, new_value, codepage TSRMLS_CC);
+ dispparams.rgvarg = new_value;
dispparams.rgdispidNamedArgs = &mydispid;
dispparams.cArgs = 1;
dispparams.cNamedArgs = 1;
- hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYPUT, &dispparams, NULL);
+ hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYPUT, &dispparams, NULL, &ErrString TSRMLS_CC);
if(FAILED(hr))
{
- error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "PropPut() failed: %s\n", error_message);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ if (ErrString)
+ {
+ php_error(E_WARNING,"PropPut() failed: %s %s", error_message, ErrString);
+ pefree(ErrString, 1);
+ }
+ else
+ {
+ php_error(E_WARNING,"PropPut() failed: %s", error_message);
+ }
LocalFree(error_message);
efree(propname);
+
+ FREE_VARIANT(var_result);
+ FREE_VARIANT(new_value);
+
RETURN_FALSE;
}
dispparams.cArgs = 0;
dispparams.cNamedArgs = 0;
- hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result);
+ hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC);
if(SUCCEEDED(hr))
{
- php_variant_to_pval(var_result, return_value, 0, codepage);
+ php_variant_to_pval(var_result, return_value, FALSE, codepage TSRMLS_CC);
}
else
{
@@ -1038,7 +1112,14 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
zval_copy_ctor(return_value);
}
- efree(var_result);
+ if (ErrString)
+ {
+ pefree(ErrString, 1);
+ }
+
+ FREE_VARIANT(var_result);
+ FREE_VARIANT(new_value);
+
efree(propname);
}
@@ -1050,9 +1131,9 @@ PHP_FUNCTION(com_propget)
pval *arg_comval, *arg_property;
int type;
comval *obj;
- VARIANT var_result;
+ VARIANT *var_result;
- if(ZEND_NUM_ARGS()!=2 || getParameters(ht, 2, &arg_comval, &arg_property)==FAILURE)
+ if((ZEND_NUM_ARGS() != 2) || (getParameters(ht, 2, &arg_comval, &arg_property) == FAILURE))
{
WRONG_PARAM_COUNT;
}
@@ -1062,15 +1143,21 @@ PHP_FUNCTION(com_propget)
obj = (comval *)zend_list_find(Z_LVAL_P(arg_comval), &type);
if(!obj || (type != IS_COM))
{
- php_error(E_WARNING, "%d is not a COM object handler", Z_LVAL_P(arg_comval));
+ php_error(E_WARNING,"%d is not a COM object handler", Z_LVAL_P(arg_comval));
}
convert_to_string_ex(&arg_property);
- if(do_COM_propget(&var_result, obj, arg_property, 0)==FAILURE)
+ ALLOC_VARIANT(var_result);
+
+ if(do_COM_propget(var_result, obj, arg_property, FALSE TSRMLS_CC) == FAILURE)
{
+ FREE_VARIANT(var_result);
RETURN_FALSE;
}
- php_variant_to_pval(&var_result, return_value, 0, codepage);
+
+ php_variant_to_pval(var_result, return_value, FALSE, codepage TSRMLS_CC);
+
+ FREE_VARIANT(var_result);
}
/* }}} */
@@ -1094,11 +1181,11 @@ PHP_FUNCTION(com_propput)
obj = (comval *)zend_list_find(Z_LVAL_P(arg_comval), &type);
if(!obj || (type != IS_COM))
{
- php_error(E_WARNING, "%d is not a COM object handler", Z_LVAL_P(arg_comval));
+ php_error(E_WARNING,"%d is not a COM object handler", Z_LVAL_P(arg_comval));
}
convert_to_string_ex(&arg_property);
- do_COM_propput(return_value, obj, arg_property, arg_value);
+ do_COM_propput(return_value, obj, arg_property, arg_value TSRMLS_CC);
}
/* }}} */
@@ -1127,7 +1214,7 @@ PHP_FUNCTION(com_load_typelib)
}
convert_to_string_ex(&arg_typelib);
- pTL = php_COM_find_typelib(Z_STRVAL_P(arg_typelib), mode);
+ pTL = php_COM_find_typelib(Z_STRVAL_P(arg_typelib), mode TSRMLS_CC);
if(php_COM_load_typelib(pTL, mode TSRMLS_CC) == SUCCESS)
{
pTL->lpVtbl->Release(pTL);
@@ -1169,38 +1256,42 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
for(element=property_reference->elements_list->head; element; element=element->next)
{
overloaded_property = (zend_overloaded_element *) element->data;
- VariantInit(var_result);
switch(overloaded_property->type)
{
case OE_IS_ARRAY:
- if(do_COM_offget(var_result, obj, &overloaded_property->element, FALSE) == FAILURE)
+ if(do_COM_offget(var_result, obj, &overloaded_property->element, FALSE TSRMLS_CC) == FAILURE)
{
- efree(var_result);
- efree(obj_prop);
+ FREE_VARIANT(var_result);
+ FREE_COM(obj_prop);
+
return return_value;
}
break;
case OE_IS_OBJECT:
- if(do_COM_propget(var_result, obj, &overloaded_property->element, FALSE) == FAILURE)
+ if(do_COM_propget(var_result, obj, &overloaded_property->element, FALSE TSRMLS_CC) == FAILURE)
{
- efree(var_result);
- efree(obj_prop);
+ FREE_VARIANT(var_result);
+ FREE_COM(obj_prop);
+
return return_value;
}
break;
case OE_IS_METHOD:
{
+ FREE_VARIANT(var_result);
if(obj != obj_prop)
{
- efree(obj_prop);
+ FREE_COM(obj_prop);
+
return_value = *object;
ZVAL_ADDREF(&return_value);
}
-
- efree(var_result);
-
+ else
+ {
+ RETVAL_COM(obj);
+ }
return return_value;
}
break;
@@ -1210,26 +1301,28 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
{
if(V_DISPATCH(var_result) == NULL)
{
- efree(var_result);
- efree(obj_prop);
+ FREE_VARIANT(var_result);
+ FREE_COM(obj_prop);
+
return return_value;
}
obj = obj_prop;
- php_COM_set(obj, V_DISPATCH(var_result), TRUE);
-
- RETVAL_COM(obj);
+ php_COM_set(obj, &V_DISPATCH(var_result), TRUE TSRMLS_CC);
}
else
{
- efree(obj_prop);
+ php_variant_to_pval(var_result, &return_value, FALSE, codepage TSRMLS_CC);
+
+ FREE_COM(obj_prop);
obj_prop = NULL;
- php_variant_to_pval(var_result, &return_value, FALSE, codepage);
}
+ VariantInit(var_result); // to protect C_DISPATCH(obj) from being freed when var_result is destructed
pval_destructor(&overloaded_property->element);
}
- efree(var_result);
+
+ FREE_VARIANT(var_result);
return return_value;
}
@@ -1241,9 +1334,9 @@ PHPAPI int php_COM_set_property_handler(zend_property_reference *property_refere
zend_llist_element *element;
pval **comval_handle;
pval *object = property_reference->object;
- comval *obj;
+ comval *obj, *obj_prop;
int type;
- VARIANT var_result;
+ VARIANT *var_result;
TSRMLS_FETCH();
/* fetch the IDispatch interface */
@@ -1253,46 +1346,72 @@ PHPAPI int php_COM_set_property_handler(zend_property_reference *property_refere
{
return FAILURE;
}
- var_result.vt = VT_DISPATCH;
- var_result.pdispVal = C_DISPATCH(obj);
+
+ ALLOC_COM(obj_prop);
+ ALLOC_VARIANT(var_result);
- for(element=property_reference->elements_list->head; element && element!=property_reference->elements_list->tail; element=element->next)
+ for(element=property_reference->elements_list->head; element != property_reference->elements_list->tail; element=element->next)
{
overloaded_property = (zend_overloaded_element *) element->data;
switch(overloaded_property->type)
{
case OE_IS_ARRAY:
- break;
- case OE_IS_OBJECT:
- if(V_VT(&var_result) != VT_DISPATCH)
+ if(do_COM_offget(var_result, obj, &overloaded_property->element, FALSE TSRMLS_CC) == FAILURE)
{
+ FREE_VARIANT(var_result);
+ FREE_COM(obj_prop);
+
return FAILURE;
}
- else
+ break;
+
+ case OE_IS_OBJECT:
+ if(do_COM_propget(var_result, obj, &overloaded_property->element, FALSE TSRMLS_CC) == FAILURE)
{
- do_COM_propget(&var_result, obj, &overloaded_property->element, element!=property_reference->elements_list->head);
+ FREE_VARIANT(var_result);
+ FREE_COM(obj_prop);
+
+ return FAILURE;
}
break;
+
case OE_IS_METHOD:
/* this shouldn't happen */
return FAILURE;
+ break;
}
- pval_destructor(&overloaded_property->element);
- }
+ if(V_VT(var_result) == VT_DISPATCH)
+ {
+ if(V_DISPATCH(var_result) == NULL)
+ {
+ FREE_VARIANT(var_result);
+ FREE_COM(obj_prop);
- if(V_VT(&var_result) != VT_DISPATCH)
- {
- return FAILURE;
- }
- obj = (comval *) emalloc(sizeof(comval));
- C_HASTLIB(obj) = FALSE;
- C_DISPATCH(obj) = V_DISPATCH(&var_result);
+ return FAILURE;
+ }
+
+ obj = obj_prop;
+ php_COM_set(obj, &V_DISPATCH(var_result), TRUE TSRMLS_CC);
+ }
+ else
+ {
+ FREE_COM(obj_prop);
+ FREE_VARIANT(var_result);
+ return FAILURE;
+ }
+
+ VariantInit(var_result); // to protect C_DISPATCH(obj) from being freed when var_result is destructed
+ pval_destructor(&overloaded_property->element);
+ }
+ FREE_VARIANT(var_result);
+
overloaded_property = (zend_overloaded_element *) element->data;
- do_COM_propput(&result, obj, &overloaded_property->element, value);
+ do_COM_propput(&result, obj, &overloaded_property->element, value TSRMLS_CC);
+ FREE_COM(obj_prop);
+
pval_destructor(&overloaded_property->element);
- efree(obj);
return SUCCESS;
}
@@ -1349,12 +1468,12 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro
if(zend_llist_count(property_reference->elements_list)==1
&& !strcmp(Z_STRVAL_P(&function_name->element), "release"))
{
- RETVAL_LONG(php_COM_release(obj));
+ RETVAL_LONG(php_COM_release(obj TSRMLS_CC));
}
else if(zend_llist_count(property_reference->elements_list)==1
&& !strcmp(Z_STRVAL_P(&function_name->element), "addref"))
{
- RETVAL_LONG(php_COM_addref(obj));
+ RETVAL_LONG(php_COM_addref(obj TSRMLS_CC));
}
else
{
@@ -1363,22 +1482,21 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro
int arg_count = ZEND_NUM_ARGS();
ALLOC_VARIANT(var_result);
- VariantInit(var_result);
arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
getParametersArray(ht, arg_count, arguments);
- if(do_COM_invoke(obj , &function_name->element, var_result, arguments, arg_count)==FAILURE)
+ if(do_COM_invoke(obj , &function_name->element, var_result, arguments, arg_count TSRMLS_CC) == FAILURE)
{
RETVAL_FALSE;
}
else
{
- php_variant_to_pval(var_result, return_value, 0, codepage);
+ php_variant_to_pval(var_result, return_value, FALSE, codepage TSRMLS_CC);
}
+ FREE_VARIANT(var_result);
efree(arguments);
- efree(var_result);
}
if(property.refcount == 1)
@@ -1388,7 +1506,7 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro
pval_destructor(&function_name->element);
}
-static ITypeLib *php_COM_find_typelib(char *search_string, int mode)
+static ITypeLib *php_COM_find_typelib(char *search_string, int mode TSRMLS_DC)
{
ITypeLib *TypeLib = NULL;
char *strtok_buf, *major, *minor;
@@ -1409,7 +1527,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode)
major = php_strtok_r(NULL, ",", &strtok_buf);
minor = php_strtok_r(NULL, ",", &strtok_buf);
- p = php_char_to_OLECHAR(search_string, strlen(search_string), codepage);
+ p = php_char_to_OLECHAR(search_string, strlen(search_string), codepage TSRMLS_CC);
/* Is the string a GUID ? */
if(!FAILED(CLSIDFromString(p, &clsid)))
@@ -1483,7 +1601,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode)
/* at each version for a string match to the */
/* supplied argument */
- if(ERROR_SUCCESS != RegOpenKey(HKEY_CLASSES_ROOT, "TypeLib", &hkey))
+ if(ERROR_SUCCESS != RegOpenKey(HKEY_CLASSES_ROOT, "TypeLib",&hkey))
{
/* This is pretty bad - better bail */
return NULL;
@@ -1548,7 +1666,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode)
str = emalloc(strlen(keyname)+strlen(version)+20); /* 18 == safety, 2 == extra comma and \0 */
sprintf(str, "%s,%d,%d", keyname, major, minor);
efree(keyname);
- TypeLib = php_COM_find_typelib(str, mode);
+ TypeLib = php_COM_find_typelib(str, mode TSRMLS_CC);
efree(str);
/* This is probbaly much harder to read and follow */
/* But it is MUCH more effiecient than trying to */
@@ -1611,7 +1729,7 @@ static int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC)
TypeLib->lpVtbl->GetTypeInfo(TypeLib, i, &TypeInfo);
j=0;
- while(TypeInfo->lpVtbl->GetVarDesc(TypeInfo, j, &pVarDesc)==S_OK)
+ while(SUCCEEDED(TypeInfo->lpVtbl->GetVarDesc(TypeInfo, j, &pVarDesc)))
{
BSTR bstr_ids;
char *ids;
@@ -1624,7 +1742,7 @@ static int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC)
j++;
continue;
}
- ids = php_OLECHAR_to_char(bstr_ids, NULL, 1, codepage);
+ ids = php_OLECHAR_to_char(bstr_ids, NULL, 1, codepage TSRMLS_CC);
SysFreeString(bstr_ids);
c.name_len = strlen(ids)+1;
c.name = ids;
@@ -1634,14 +1752,14 @@ static int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC)
/* Check to see if they are the same */
if (!compare_function(&results, &c.value, &exists TSRMLS_CC) && INI_INT("com.autoregister_verbose"))
{
- php_error(E_WARNING, "Type library value %s is already defined and has a different value", c.name);
+ php_error(E_WARNING,"Type library value %s is already defined and has a different value", c.name);
}
free(ids);
j++;
continue;
}
- php_variant_to_pval(pVarDesc->lpvarValue, &c.value, FALSE, codepage);
+ php_variant_to_pval(pVarDesc->lpvarValue, &c.value, FALSE, codepage TSRMLS_CC);
c.flags = mode;
/* Before registering the contsnt, let's see if we can find it */
@@ -1678,7 +1796,7 @@ PHP_FUNCTION(com_isenum)
obj = (comval *) zend_list_find(Z_LVAL_PP(comval_handle), &type);
if(!obj || (type != IS_COM))
{
- php_error(E_WARNING, "%s is not a COM object handler", "");
+ php_error(E_WARNING,"%s is not a COM object handler", "");
RETURN_FALSE;
}
@@ -1686,14 +1804,14 @@ PHP_FUNCTION(com_isenum)
}
/* }}} */
-void php_register_COM_class(TSRMLS_D)
+static void php_register_COM_class(TSRMLS_D)
{
- INIT_OVERLOADED_CLASS_ENTRY(com_class_entry, "COM", NULL,
+ INIT_OVERLOADED_CLASS_ENTRY(COM_class_entry, "COM", NULL,
php_COM_call_function_handler,
php_COM_get_property_handler,
php_COM_set_property_handler);
- zend_register_internal_class(&com_class_entry TSRMLS_CC);
+ zend_register_internal_class(&COM_class_entry TSRMLS_CC);
}
PHP_MINIT_FUNCTION(COM)
diff --git a/ext/com/VARIANT.c b/ext/com/VARIANT.c
index 5d61100d64..b8f2590101 100644
--- a/ext/com/VARIANT.c
+++ b/ext/com/VARIANT.c
@@ -28,25 +28,20 @@
#include "php.h"
#include "php_ini.h"
-#include "variant.h"
-#include "conversion.h"
#include "ext/standard/info.h"
+#include "php_VARIANT.h"
#include <unknwn.h>
-PHP_MINIT_FUNCTION(VARIANT);
-PHP_MSHUTDOWN_FUNCTION(VARIANT);
-
-int php_VARIANT_get_le_variant();
-void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
-pval php_VARIANT_get_property_handler(zend_property_reference *property_reference);
-static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value);
-void php_register_VARIANT_class(TSRMLS_D);
-static void php_variant_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
+static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value TSRMLS_DC);
+static int php_VARIANT_set_property_handler(zend_property_reference *property_reference, pval *value);
+static pval php_VARIANT_get_property_handler(zend_property_reference *property_reference);
+static void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
+static void php_VARIANT_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
+static void php_register_VARIANT_class(TSRMLS_D);
static int le_variant;
static int codepage;
-
static zend_class_entry VARIANT_class_entry;
function_entry VARIANT_functions[] = {
@@ -66,7 +61,7 @@ zend_module_entry VARIANT_module_entry = {
PHP_MINIT_FUNCTION(VARIANT)
{
- le_variant = zend_register_list_destructors_ex(php_variant_destructor, NULL, "VARIANT", module_number);
+ le_variant = zend_register_list_destructors_ex(php_VARIANT_destructor, NULL, "VARIANT", module_number);
/* variant datatypes */
REGISTER_LONG_CONSTANT("VT_NULL", VT_NULL, CONST_CS | CONST_PERSISTENT);
@@ -97,10 +92,18 @@ PHP_MINIT_FUNCTION(VARIANT)
REGISTER_LONG_CONSTANT("CP_ACP", CP_ACP, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CP_MACCP", CP_MACCP, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CP_OEMCP", CP_OEMCP, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("CP_SYMBOL", CP_SYMBOL, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("CP_THREAD_ACP", CP_THREAD_ACP, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CP_UTF7", CP_UTF7, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CP_UTF8", CP_UTF8, CONST_CS | CONST_PERSISTENT);
+#ifdef CP_SYMBOL
+ REGISTER_LONG_CONSTANT("CP_SYMBOL", CP_SYMBOL, CONST_CS | CONST_PERSISTENT);
+#else
+# error "CP_SYMBOL undefined"
+#endif
+#ifdef CP_THREAD_ACP
+ REGISTER_LONG_CONSTANT("CP_THREAD_ACP", CP_THREAD_ACP, CONST_CS | CONST_PERSISTENT);
+#else
+# error "CP_THREAD_ACP undefined"
+#endif
php_register_VARIANT_class(TSRMLS_C);
return SUCCESS;
@@ -111,12 +114,12 @@ PHP_MSHUTDOWN_FUNCTION(VARIANT)
return SUCCESS;
}
-int php_VARIANT_get_le_variant()
+PHPAPI int php_VARIANT_get_le_variant()
{
return le_variant;
}
-void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
+static void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
{
pval *object = property_reference->object;
zend_overloaded_element *function_name = (zend_overloaded_element *) property_reference->elements_list->tail->data;
@@ -137,17 +140,17 @@ void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper
break;
case 1:
getParameters(ht, 1, &data);
- php_pval_to_variant(data, pVar, codepage);
+ php_pval_to_variant(data, pVar, codepage TSRMLS_CC);
codepage = CP_ACP;
break;
case 2:
getParameters(ht, 2, &data, &type);
- php_pval_to_variant_ex(data, pVar, type, codepage);
+ php_pval_to_variant_ex(data, pVar, type, codepage TSRMLS_CC);
codepage = CP_ACP;
break;
case 3:
getParameters(ht, 3, &data, &type, &code_page);
- php_pval_to_variant_ex(data, pVar, type, codepage);
+ php_pval_to_variant_ex(data, pVar, type, codepage TSRMLS_CC);
convert_to_long(code_page);
codepage = code_page->value.lval;
break;
@@ -173,14 +176,14 @@ void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper
}
}
-
-pval php_VARIANT_get_property_handler(zend_property_reference *property_reference)
+static pval php_VARIANT_get_property_handler(zend_property_reference *property_reference)
{
zend_overloaded_element *overloaded_property;
int type;
+ TSRMLS_FETCH();
+
pval result, **var_handle, *object = property_reference->object;
VARIANT *var_arg;
- TSRMLS_FETCH();
/* fetch the VARIANT structure */
zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &var_handle);
@@ -202,7 +205,7 @@ pval php_VARIANT_get_property_handler(zend_property_reference *property_referenc
case OE_IS_OBJECT:
if(!strcmp(overloaded_property->element.value.str.val, "value"))
{
- php_variant_to_pval(var_arg, &result, 0, codepage);
+ php_variant_to_pval(var_arg, &result, 0, codepage TSRMLS_CC);
}
else if(!strcmp(Z_STRVAL(overloaded_property->element), "type"))
{
@@ -226,13 +229,14 @@ pval php_VARIANT_get_property_handler(zend_property_reference *property_referenc
return result;
}
-int php_VARIANT_set_property_handler(zend_property_reference *property_reference, pval *value)
+static int php_VARIANT_set_property_handler(zend_property_reference *property_reference, pval *value)
{
zend_overloaded_element *overloaded_property;
int type;
+ TSRMLS_FETCH();
+
pval **var_handle, *object = property_reference->object;
VARIANT *var_arg;
- TSRMLS_FETCH();
/* fetch the VARIANT structure */
zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &var_handle);
@@ -242,12 +246,12 @@ int php_VARIANT_set_property_handler(zend_property_reference *property_reference
return FAILURE;
overloaded_property = (zend_overloaded_element *) property_reference->elements_list->head->data;
- do_VARIANT_propset(var_arg, &overloaded_property->element, value);
+ do_VARIANT_propset(var_arg, &overloaded_property->element, value TSRMLS_CC);
zval_dtor(&overloaded_property->element);
return SUCCESS;
}
-static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value)
+static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value TSRMLS_DC)
{
pval type;
@@ -415,17 +419,17 @@ static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value)
return FAILURE;
}
- php_pval_to_variant_ex(value, var_arg, &type, codepage);
+ php_pval_to_variant_ex(value, var_arg, &type, codepage TSRMLS_CC);
return SUCCESS;
}
-static void php_variant_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+static void php_VARIANT_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
- efree(rsrc);
+ FREE_VARIANT(rsrc->ptr);
}
-void php_register_VARIANT_class(TSRMLS_D)
+static void php_register_VARIANT_class(TSRMLS_D)
{
INIT_OVERLOADED_CLASS_ENTRY(VARIANT_class_entry, "VARIANT", NULL,
php_VARIANT_call_function_handler,
diff --git a/ext/com/com.h b/ext/com/com.h
index 13ac1d68b8..99c17782df 100644
--- a/ext/com/com.h
+++ b/ext/com/com.h
@@ -3,7 +3,9 @@
#if PHP_WIN32
-#include "oleauto.h"
+BEGIN_EXTERN_C()
+
+#include <oleauto.h>
typedef struct comval_ {
#ifdef _DEBUG
@@ -19,6 +21,8 @@ typedef struct comval_ {
} i;
} comval;
+END_EXTERN_C()
+
#define ZVAL_COM(z,o) { \
zval *handle; \
HashTable *properties; \
@@ -32,14 +36,18 @@ typedef struct comval_ {
\
zval_copy_ctor(handle); \
zend_hash_index_update(properties, 0, &handle, sizeof(zval *), NULL); \
- object_and_properties_init(z, &com_class_entry, properties); \
+ object_and_properties_init(z, &COM_class_entry, properties); \
}
-#define RETVAL_COM(o) ZVAL_COM(&return_value, o)
+#define RETVAL_COM(o) ZVAL_COM(&return_value, o);
#define RETURN_COM(o) RETVAL_COM(o) \
return;
-#define ALLOC_COM(z) (z) = (comval *) emalloc(sizeof(comval))
+#define ALLOC_COM(z) (z) = (comval *) emalloc(sizeof(comval)); \
+ C_REFCOUNT(z) = 0;
+
+#define FREE_COM(z) efree(z);
+
#define IS_COM php_COM_get_le_comval()
#define C_HASTLIB(x) ((x)->typelib)
diff --git a/ext/com/conversion.c b/ext/com/conversion.c
index 0f9bcbd32b..21dace5c18 100644
--- a/ext/com/conversion.c
+++ b/ext/com/conversion.c
@@ -37,12 +37,6 @@
/* prototypes */
-PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage TSRMLS_DC);
-PHPAPI void php_pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, pval *pval_type, int codepage TSRMLS_DC);
-PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, int codepage);
-PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage);
-PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int persistent, int codepage);
-
static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int codepage TSRMLS_DC);
static void comval_to_variant(pval *pval_arg, VARIANT *var_arg TSRMLS_DC);
@@ -50,7 +44,7 @@ static void comval_to_variant(pval *pval_arg, VARIANT *var_arg TSRMLS_DC);
PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage TSRMLS_DC)
{
int type = VT_EMPTY; /* default variant type */
-
+
switch(Z_TYPE_P(pval_arg))
{
case IS_NULL:
@@ -64,7 +58,7 @@ PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage T
case IS_OBJECT:
if(!strcmp(Z_OBJCE_P(pval_arg)->name, "VARIANT"))
{
- type = VT_VARIANT;
+ type = VT_VARIANT|VT_BYREF;
}
else if(!strcmp(Z_OBJCE_P(pval_arg)->name, "COM"))
{
@@ -93,10 +87,10 @@ PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage T
case IS_STRING:
type = VT_BSTR;
break;
- }
+ }
if(pval_arg->is_ref) /* deprecated, implemented for downwards compatiblity */
- {
+ {
type |= VT_BYREF;
}
@@ -116,22 +110,22 @@ static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int c
V_VT(var_arg) = type;
if(V_VT(var_arg) & VT_ARRAY)
- {
- /* For now we'll just handle single dimension arrays, we'll use the data type of the first element for the
- output data type */
- HashTable *ht = Z_ARRVAL(*pval_arg);
- int numberOfElements = zend_hash_num_elements(ht);
- SAFEARRAY *safeArray;
- SAFEARRAYBOUND bounds[1];
- VARIANT *v;
- zval **entry; /* An entry in the input array */
-
+ {
+ /* For now we'll just handle single dimension arrays, we'll use the data type of the first element for the
+ output data type */
+ HashTable *ht = Z_ARRVAL(*pval_arg);
+ int numberOfElements = zend_hash_num_elements(ht);
+ SAFEARRAY *safeArray;
+ SAFEARRAYBOUND bounds[1];
+ VARIANT *v;
+ zval **entry; /* An entry in the input array */
+
type &= ~VT_ARRAY;
if(V_VT(var_arg) == (VT_ARRAY|VT_BYREF)) /* == is intended, because VT_*|VT_BYREF|VT_ARRAY means something diffrent */
{
type &= ~VT_BYREF;
- ALLOC_VARIANT(V_VARIANTREF(var_arg));
+ ALLOC_VARIANT(V_VARIANTREF(var_arg));
var_arg = V_VARIANTREF(var_arg); /* put the array in that VARIANT */
}
@@ -141,7 +135,7 @@ static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int c
if(NULL == safeArray)
{
- php_error( E_WARNING, "Unable to convert php array to VARIANT array - %s", numberOfElements ? "" : "(Empty input array)");
+ php_error( E_WARNING,"Unable to convert php array to VARIANT array - %s", numberOfElements ? "" : "(Empty input array)");
ZVAL_FALSE(pval_arg);
}
else
@@ -158,20 +152,20 @@ static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int c
if((zend_hash_get_current_data(ht, (void **)&entry) == SUCCESS) && (entry != NULL)) /* Get a pointer to the php array element */
{
/* Add another value to the safe array */
- if(SUCCEEDED(SafeArrayPtrOfIndex( safeArray, &i, &v)))/* Pointer to output element entry retrieved successfully */
+ if(SUCCEEDED(SafeArrayPtrOfIndex( safeArray, &i, &v))) /* Pointer to output element entry retrieved successfully */
{
- if(type) /* explicit type */
- {
+ if(type) /* explicit type */
+ {
pval_to_variant_ex(*entry, v, type, codepage TSRMLS_CC); /* Do the required conversion */
- }
- else
- {
+ }
+ else
+ {
php_pval_to_variant(*entry, v, codepage TSRMLS_CC); /* Do the required conversion */
}
}
else
{
- php_error( E_WARNING, "phpArrayToSafeArray() - Unable to retrieve pointer to output element number (%d)", i);
+ php_error( E_WARNING,"phpArrayToSafeArray() - Unable to retrieve pointer to output element number (%d)", i);
}
}
zend_hash_move_forward(ht);
@@ -180,207 +174,210 @@ static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int c
}
else
{
- php_error( E_WARNING, "phpArrayToSafeArray() - Unable to lock safeArray");
+ php_error( E_WARNING,"phpArrayToSafeArray() - Unable to lock safeArray");
}
}
}
else
- {
- switch(V_VT(var_arg))
- {
- case VT_UI1:
- convert_to_long_ex(&pval_arg);
- V_UI1(var_arg) = (unsigned char)Z_LVAL_P(pval_arg);
- break;
-
- case VT_I2:
- convert_to_long_ex(&pval_arg);
- V_I2(var_arg) = (short)Z_LVAL_P(pval_arg);
- break;
-
- case VT_I4:
- convert_to_long_ex(&pval_arg);
- V_I4(var_arg) = Z_LVAL_P(pval_arg);
- break;
-
- case VT_R4:
- convert_to_double_ex(&pval_arg);
- V_R4(var_arg) = (float)Z_DVAL_P(pval_arg);
- break;
-
- case VT_R8:
- convert_to_double_ex(&pval_arg);
- V_R8(var_arg) = Z_DVAL_P(pval_arg);
- break;
-
- case VT_BOOL:
- convert_to_boolean_ex(&pval_arg);
- V_BOOL(var_arg) = (short)Z_LVAL_P(pval_arg);
- break;
-
- case VT_ERROR:
- convert_to_long_ex(&pval_arg);
- V_ERROR(var_arg) = Z_LVAL_P(pval_arg);
- break;
-
- case VT_CY:
- convert_to_double_ex(&pval_arg);
- VarCyFromR8(Z_DVAL_P(pval_arg), &V_CY(var_arg));
- break;
-
- case VT_DATE:
- {
- SYSTEMTIME wintime;
- struct tm *phptime;
-
- phptime = gmtime(&(pval_arg->value.lval));
- memset(&wintime, 0, sizeof(wintime));
-
- wintime.wYear = phptime->tm_year + 1900;
- wintime.wMonth = phptime->tm_mon + 1;
- wintime.wDay = phptime->tm_mday;
- wintime.wHour = phptime->tm_hour;
- wintime.wMinute = phptime->tm_min;
- wintime.wSecond = phptime->tm_sec;
-
- SystemTimeToVariantTime(&wintime, &V_DATE(var_arg));
- }
- break;
-
- case VT_BSTR:
- convert_to_string_ex(&pval_arg);
- unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage);
- V_BSTR(var_arg) = SysAllocString(unicode_str);
- efree(unicode_str);
- break;
-
- case VT_DECIMAL:
- convert_to_string_ex(&pval_arg);
- unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage);
- VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &V_DECIMAL(var_arg));
- break;
-
- case VT_DECIMAL|VT_BYREF:
- convert_to_string_ex(&pval_arg);
- unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage);
- VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, V_DECIMALREF(var_arg));
- break;
-
- case VT_UNKNOWN:
+ {
+ switch(V_VT(var_arg))
+ {
+ case VT_UI1:
+ convert_to_long_ex(&pval_arg);
+ V_UI1(var_arg) = (unsigned char)Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_I2:
+ convert_to_long_ex(&pval_arg);
+ V_I2(var_arg) = (short)Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_I4:
+ convert_to_long_ex(&pval_arg);
+ V_I4(var_arg) = Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_R4:
+ convert_to_double_ex(&pval_arg);
+ V_R4(var_arg) = (float)Z_DVAL_P(pval_arg);
+ break;
+
+ case VT_R8:
+ convert_to_double_ex(&pval_arg);
+ V_R8(var_arg) = Z_DVAL_P(pval_arg);
+ break;
+
+ case VT_BOOL:
+ convert_to_boolean_ex(&pval_arg);
+ V_BOOL(var_arg) = (short)Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_ERROR:
+ convert_to_long_ex(&pval_arg);
+ V_ERROR(var_arg) = Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_CY:
+ convert_to_double_ex(&pval_arg);
+ VarCyFromR8(Z_DVAL_P(pval_arg), &V_CY(var_arg));
+ break;
+
+ case VT_DATE:
+ {
+ SYSTEMTIME wintime;
+ struct tm *phptime;
+
+ phptime = gmtime(&(pval_arg->value.lval));
+ memset(&wintime, 0, sizeof(wintime));
+
+ wintime.wYear = phptime->tm_year + 1900;
+ wintime.wMonth = phptime->tm_mon + 1;
+ wintime.wDay = phptime->tm_mday;
+ wintime.wHour = phptime->tm_hour;
+ wintime.wMinute = phptime->tm_min;
+ wintime.wSecond = phptime->tm_sec;
+
+ SystemTimeToVariantTime(&wintime, &V_DATE(var_arg));
+ }
+ break;
+
+ case VT_BSTR:
+ convert_to_string_ex(&pval_arg);
+ unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage TSRMLS_CC);
+ V_BSTR(var_arg) = SysAllocString(unicode_str);
+ efree(unicode_str);
+ break;
+
+ case VT_DECIMAL:
+ convert_to_string_ex(&pval_arg);
+ unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage TSRMLS_CC);
+ VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &V_DECIMAL(var_arg));
+ break;
+
+ case VT_DECIMAL|VT_BYREF:
+ convert_to_string_ex(&pval_arg);
+ unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage TSRMLS_CC);
+ VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, V_DECIMALREF(var_arg));
+ break;
+
+ case VT_UNKNOWN:
comval_to_variant(pval_arg, var_arg TSRMLS_CC);
- if(V_VT(var_arg) != VT_DISPATCH)
- {
- VariantInit(var_arg);
- }
- else
- {
- V_VT(var_arg) = VT_UNKNOWN;
- V_UNKNOWN(var_arg) = (IUnknown *) V_DISPATCH(var_arg);
- }
- break;
-
- case VT_DISPATCH:
+ if(V_VT(var_arg) != VT_DISPATCH)
+ {
+ VariantInit(var_arg);
+ }
+ else
+ {
+ V_VT(var_arg) = VT_UNKNOWN;
+ V_UNKNOWN(var_arg) = (IUnknown *) V_DISPATCH(var_arg);
+ }
+ break;
+
+ case VT_DISPATCH:
comval_to_variant(pval_arg, var_arg TSRMLS_CC);
- if(V_VT(var_arg) != VT_DISPATCH)
- {
- VariantInit(var_arg);
- }
- break;
-
- case VT_UI1|VT_BYREF:
- convert_to_long(pval_arg);
- V_UI1REF(var_arg) = (unsigned char FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_I2|VT_BYREF:
- convert_to_long(pval_arg);
- V_I2REF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_I4|VT_BYREF:
- convert_to_long(pval_arg);
- V_I4REF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_R4|VT_BYREF:
- convert_to_double(pval_arg);
- V_R4REF(var_arg) = (float FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_R8|VT_BYREF:
- convert_to_double(pval_arg);
- V_R8REF(var_arg) = (double FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_BOOL|VT_BYREF:
- convert_to_boolean(pval_arg);
- V_BOOLREF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_ERROR|VT_BYREF:
- convert_to_long(pval_arg);
- V_ERRORREF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_CY|VT_BYREF:
- convert_to_double_ex(&pval_arg);
- VarCyFromR8(pval_arg->value.dval, var_arg->pcyVal);
- break;
-
- case VT_DATE|VT_BYREF:
- {
- SYSTEMTIME wintime;
- struct tm *phptime;
-
- phptime = gmtime(&(pval_arg->value.lval));
- memset(&wintime, 0, sizeof(wintime));
-
- wintime.wYear = phptime->tm_year + 1900;
- wintime.wMonth = phptime->tm_mon + 1;
- wintime.wDay = phptime->tm_mday;
- wintime.wHour = phptime->tm_hour;
- wintime.wMinute = phptime->tm_min;
- wintime.wSecond = phptime->tm_sec;
-
- SystemTimeToVariantTime(&wintime, var_arg->pdate);
- }
- break;
-
- case VT_BSTR|VT_BYREF:
- convert_to_string(pval_arg);
- V_BSTRREF(var_arg) = (BSTR FAR*) emalloc(sizeof(BSTR FAR*));
- unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage);
- *V_BSTRREF(var_arg) = SysAllocString(unicode_str);
- efree(unicode_str);
- break;
-
- case VT_UNKNOWN|VT_BYREF:
+ if(V_VT(var_arg) != VT_DISPATCH)
+ {
+ VariantInit(var_arg);
+ }
+ break;
+
+ case VT_UI1|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_UI1REF(var_arg) = (unsigned char FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_I2|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_I2REF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_I4|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_I4REF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_R4|VT_BYREF:
+ convert_to_double(pval_arg);
+ V_R4REF(var_arg) = (float FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_R8|VT_BYREF:
+ convert_to_double(pval_arg);
+ V_R8REF(var_arg) = (double FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_BOOL|VT_BYREF:
+ convert_to_boolean(pval_arg);
+ V_BOOLREF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_ERROR|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_ERRORREF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_CY|VT_BYREF:
+ convert_to_double_ex(&pval_arg);
+ VarCyFromR8(pval_arg->value.dval, var_arg->pcyVal);
+ break;
+
+ case VT_DATE|VT_BYREF:
+ {
+ SYSTEMTIME wintime;
+ struct tm *phptime;
+
+ phptime = gmtime(&(pval_arg->value.lval));
+ memset(&wintime, 0, sizeof(wintime));
+
+ wintime.wYear = phptime->tm_year + 1900;
+ wintime.wMonth = phptime->tm_mon + 1;
+ wintime.wDay = phptime->tm_mday;
+ wintime.wHour = phptime->tm_hour;
+ wintime.wMinute = phptime->tm_min;
+ wintime.wSecond = phptime->tm_sec;
+
+ SystemTimeToVariantTime(&wintime, var_arg->pdate);
+ }
+ break;
+
+ case VT_BSTR|VT_BYREF:
+ convert_to_string(pval_arg);
+ V_BSTRREF(var_arg) = (BSTR FAR*) emalloc(sizeof(BSTR FAR*));
+ unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage TSRMLS_CC);
+ *V_BSTRREF(var_arg) = SysAllocString(unicode_str);
+ efree(unicode_str);
+ break;
+
+ case VT_UNKNOWN|VT_BYREF:
comval_to_variant(pval_arg, var_arg TSRMLS_CC);
- if(V_VT(var_arg) != VT_DISPATCH)
- {
- VariantInit(var_arg);
- }
- else
- {
- V_VT(var_arg) = VT_UNKNOWN|VT_BYREF;
+ if(V_VT(var_arg) != VT_DISPATCH)
+ {
+ VariantInit(var_arg);
+ }
+ else
+ {
+ V_VT(var_arg) = VT_UNKNOWN|VT_BYREF;
V_UNKNOWNREF(var_arg) = (IUnknown **) &V_DISPATCH(var_arg);
- }
- break;
-
- case VT_DISPATCH|VT_BYREF:
+ }
+ break;
+
+ case VT_DISPATCH|VT_BYREF:
comval_to_variant(pval_arg, var_arg TSRMLS_CC);
- if(V_VT(var_arg) != VT_DISPATCH)
- {
- VariantInit(var_arg);
- }
- else
- {
+ if(V_VT(var_arg) != VT_DISPATCH)
+ {
+ VariantInit(var_arg);
+ }
+ else
+ {
V_VT(var_arg) = VT_DISPATCH|VT_BYREF;
V_DISPATCHREF(var_arg) = &V_DISPATCH(var_arg);
- }
- break;
-
- case VT_VARIANT|VT_BYREF:
+ }
+ break;
+
+ case VT_VARIANT:
+ php_error(E_WARNING,"VT_VARIANT is invalid. Use VT_VARIANT|VT_BYREF instead.");
+ /* break missing intentionally */
+ case VT_VARIANT|VT_BYREF:
{
int tp;
pval **var_handle;
@@ -392,9 +389,9 @@ static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int c
V_VARIANTREF(var_arg) = (VARIANT FAR*) zend_list_find(Z_LVAL_P(*var_handle), &tp);
if(!V_VARIANTREF(var_arg) && (tp != IS_VARIANT))
- {
- VariantInit(var_arg);
- }
+ {
+ VariantInit(var_arg);
+ }
}
/*
should be, but isn't :)
@@ -404,65 +401,65 @@ static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int c
VariantInit(var_arg);
}
*/
- break;
-
- case VT_I1:
- convert_to_long_ex(&pval_arg);
- V_I1(var_arg) = (char)Z_LVAL_P(pval_arg);
- break;
-
- case VT_UI2:
- convert_to_long_ex(&pval_arg);
- V_UI2(var_arg) = (unsigned short)Z_LVAL_P(pval_arg);
- break;
-
- case VT_UI4:
- convert_to_long_ex(&pval_arg);
- V_UI4(var_arg) = (unsigned long)Z_LVAL_P(pval_arg);
- break;
-
- case VT_INT:
- convert_to_long_ex(&pval_arg);
- V_INT(var_arg) = (int)Z_LVAL_P(pval_arg);
- break;
-
- case VT_UINT:
- convert_to_long_ex(&pval_arg);
- V_UINT(var_arg) = (unsigned int)Z_LVAL_P(pval_arg);
- break;
-
- case VT_I1|VT_BYREF:
- convert_to_long(pval_arg);
- V_I1REF(var_arg) = (char FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_UI2|VT_BYREF:
- convert_to_long(pval_arg);
- V_UI2REF(var_arg) = (unsigned short FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_UI4|VT_BYREF:
- convert_to_long(pval_arg);
- V_UI4REF(var_arg) = (unsigned long FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_INT|VT_BYREF:
- convert_to_long(pval_arg);
- V_INTREF(var_arg) = (int FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- case VT_UINT|VT_BYREF:
- convert_to_long(pval_arg);
- V_UINTREF(var_arg) = (unsigned int FAR*) &Z_LVAL_P(pval_arg);
- break;
-
- default:
- php_error(E_WARNING, "Type not supported or not yet implemented.");
- }
- }
+ break;
+
+ case VT_I1:
+ convert_to_long_ex(&pval_arg);
+ V_I1(var_arg) = (char)Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_UI2:
+ convert_to_long_ex(&pval_arg);
+ V_UI2(var_arg) = (unsigned short)Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_UI4:
+ convert_to_long_ex(&pval_arg);
+ V_UI4(var_arg) = (unsigned long)Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_INT:
+ convert_to_long_ex(&pval_arg);
+ V_INT(var_arg) = (int)Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_UINT:
+ convert_to_long_ex(&pval_arg);
+ V_UINT(var_arg) = (unsigned int)Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_I1|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_I1REF(var_arg) = (char FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_UI2|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_UI2REF(var_arg) = (unsigned short FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_UI4|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_UI4REF(var_arg) = (unsigned long FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_INT|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_INTREF(var_arg) = (int FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ case VT_UINT|VT_BYREF:
+ convert_to_long(pval_arg);
+ V_UINTREF(var_arg) = (unsigned int FAR*) &Z_LVAL_P(pval_arg);
+ break;
+
+ default:
+ php_error(E_WARNING, "Type not supported or not yet implemented.");
+ }
+ }
}
-PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, int codepage)
+PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, int codepage TSRMLS_DC)
{
/* Changed the function to return a value for recursive error testing */
/* Existing calls will be unaffected by the change - so it */
@@ -488,7 +485,7 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
/* For now just validate that the SafeArray has one dimension */
if (1 != (Dims = SafeArrayGetDim(array)))
{
- php_error(E_WARNING, "Unsupported: multi-dimensional (%d) SafeArrays", Dims);
+ php_error(E_WARNING,"Unsupported: multi-dimensional (%d) SafeArrays", Dims);
ZVAL_NULL(pval_arg);
return FAILURE;
}
@@ -529,18 +526,18 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
hr = SafeArrayGetElement(array, indices, (VOID *) &(vv.lVal));
}
if (FAILED(hr))
- {
+ {
/* Failure to retieve an element probably means the array is sparse */
/* So leave the php array sparse too */
continue;
- }
+ }
/* Create an element to be added to the array */
ALLOC_ZVAL(element);
/* Call ourself again to handle the base type conversion */
/* If SafeArrayGetElement proclaims to allocate */
/* memory for a BSTR, so the recursive call frees */
/* the string correctly */
- if (FAILURE == php_variant_to_pval(&vv, element, persistent, codepage))
+ if (FAILURE == php_variant_to_pval(&vv, element, persistent, codepage TSRMLS_CC))
{
/* Error occurred setting up array element */
/* Error was displayed by the recursive call */
@@ -560,10 +557,7 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
add_index_zval(pval_arg, ii, element);
}
}
- SafeArrayUnlock(array);
- /* Clean up the SafeArray since that is our responsibility */
- SafeArrayDestroyData(array);
- SafeArrayDestroyDescriptor(array);
+ SafeArrayUnlock(array);
}
else switch(var_arg->vt & ~VT_BYREF)
{
@@ -633,7 +627,7 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
switch(VarBstrFromDec(&V_DECIMAL(var_arg), LOCALE_SYSTEM_DEFAULT, 0, &unicode_str))
{
case S_OK:
- Z_STRVAL_P(pval_arg) = php_OLECHAR_to_char(unicode_str, &Z_STRLEN_P(pval_arg), persistent, codepage);
+ Z_STRVAL_P(pval_arg) = php_OLECHAR_to_char(unicode_str, &Z_STRLEN_P(pval_arg), persistent, codepage TSRMLS_CC);
Z_TYPE_P(pval_arg) = IS_STRING;
break;
@@ -676,20 +670,18 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
break;
case VT_VARIANT:
- php_variant_to_pval(V_VARIANTREF(var_arg), pval_arg, persistent, codepage);
+ php_variant_to_pval(V_VARIANTREF(var_arg), pval_arg, persistent, codepage TSRMLS_CC);
break;
case VT_BSTR:
if(V_ISBYREF(var_arg))
{
- Z_STRVAL_P(pval_arg) = php_OLECHAR_to_char(*V_BSTRREF(var_arg), &Z_STRLEN_P(pval_arg), persistent, codepage);
- SysFreeString(*V_BSTRREF(var_arg));
+ Z_STRVAL_P(pval_arg) = php_OLECHAR_to_char(*V_BSTRREF(var_arg), &Z_STRLEN_P(pval_arg), persistent, codepage TSRMLS_CC);
efree(V_BSTRREF(var_arg));
}
else
{
- Z_STRVAL_P(pval_arg) = php_OLECHAR_to_char(V_BSTR(var_arg), &Z_STRLEN_P(pval_arg), persistent, codepage);
- SysFreeString(V_BSTR(var_arg));
+ Z_STRVAL_P(pval_arg) = php_OLECHAR_to_char(V_BSTR(var_arg), &Z_STRLEN_P(pval_arg), persistent, codepage TSRMLS_CC);
}
Z_TYPE_P(pval_arg) = IS_STRING;
@@ -739,8 +731,8 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
{
char *error_message;
- error_message = php_COM_error_message(hr);
- php_error(E_WARNING, "Unable to obtain IDispatch interface: %s", error_message);
+ error_message = php_COM_error_message(hr TSRMLS_CC);
+ php_error(E_WARNING,"Unable to obtain IDispatch interface: %s", error_message);
LocalFree(error_message);
V_DISPATCH(var_arg) = NULL;
@@ -758,11 +750,9 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
}
else
{
- TSRMLS_FETCH();
-
ALLOC_COM(obj);
- php_COM_set(obj, V_DISPATCH(var_arg), TRUE);
-
+ php_COM_set(obj, &V_DISPATCH(var_arg), TRUE TSRMLS_CC);
+
ZVAL_COM(pval_arg, obj);
}
}
@@ -824,7 +814,7 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
break;
default:
- php_error(E_WARNING, "Unsupported variant type: %d (0x%X)", V_VT(var_arg), V_VT(var_arg));
+ php_error(E_WARNING,"Unsupported variant type: %d (0x%X)", V_VT(var_arg), V_VT(var_arg));
ZVAL_NULL(pval_arg);
ret = FAILURE;
break;
@@ -832,7 +822,7 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent,
return ret;
}
-PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage)
+PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage TSRMLS_DC)
{
OLECHAR *unicode_str;
@@ -854,17 +844,17 @@ PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage)
switch(GetLastError())
{
case ERROR_NO_UNICODE_TRANSLATION:
- php_error(E_WARNING, "No unicode translation available for the specified string");
+ php_error(E_WARNING,"No unicode translation available for the specified string");
break;
default:
- php_error(E_WARNING, "Error in php_char_to_OLECHAR()");
+ php_error(E_WARNING,"Error in php_char_to_OLECHAR()");
}
}
return unicode_str;
}
-PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int persistent, int codepage)
+PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int persistent, int codepage TSRMLS_DC)
{
char *C_str;
uint length = 0;
@@ -884,7 +874,7 @@ PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int per
C_str = (char *) pemalloc(sizeof(char), persistent);
*C_str = 0;
- php_error(E_WARNING, "Error in php_OLECHAR_to_char()");
+ php_error(E_WARNING,"Error in php_OLECHAR_to_char()");
}
if(out_length)
@@ -903,7 +893,7 @@ static void comval_to_variant(pval *pval_arg, VARIANT *var_arg TSRMLS_DC)
/* fetch the comval structure */
zend_hash_index_find(Z_OBJPROP_P(pval_arg), 0, (void **) &comval_handle);
- obj = (comval *) zend_list_find(Z_LVAL_P(*comval_handle), &type);
+ obj = (comval *)zend_list_find(Z_LVAL_P(*comval_handle), &type);
if(!obj || (type != IS_COM) || !C_ISREFD(obj))
{
VariantInit(var_arg);
@@ -915,4 +905,4 @@ static void comval_to_variant(pval *pval_arg, VARIANT *var_arg TSRMLS_DC)
}
}
-#endif /* PHP_WIN32 */
+#endif /* PHP_WIN32 */ \ No newline at end of file
diff --git a/ext/com/conversion.h b/ext/com/conversion.h
index 53d19a21de..a55d66c57b 100644
--- a/ext/com/conversion.h
+++ b/ext/com/conversion.h
@@ -3,11 +3,11 @@
BEGIN_EXTERN_C()
-extern void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage);
-extern void php_pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, pval *pval_type, int codepage);
-extern int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, int codepage);
-extern OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage);
-extern char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int persistent, int codepage);
+PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage TSRMLS_DC);
+PHPAPI void php_pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, pval *pval_type, int codepage TSRMLS_DC);
+PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, int codepage TSRMLS_DC);
+PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage TSRMLS_DC);
+PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int persistent, int codepage TSRMLS_DC);
END_EXTERN_C()
diff --git a/ext/com/php_COM.h b/ext/com/php_COM.h
index 3a2108f415..c44c808fe0 100644
--- a/ext/com/php_COM.h
+++ b/ext/com/php_COM.h
@@ -10,22 +10,30 @@ BEGIN_EXTERN_C()
PHP_MINIT_FUNCTION(COM);
PHP_MSHUTDOWN_FUNCTION(COM);
-PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult);
-PHPAPI HRESULT php_COM_get_ids_of_names(comval *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId);
-PHPAPI HRESULT php_COM_release(comval *obj);
-PHPAPI HRESULT php_COM_addref(comval *obj);
-PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* pDisp, int cleanup);
-PHPAPI HRESULT php_COM_clone(comval *obj, comval *clone, int cleanup);
-
-int php_COM_get_le_comval();
+PHP_FUNCTION(com_load);
+PHP_FUNCTION(com_invoke);
+PHP_FUNCTION(com_addref);
+PHP_FUNCTION(com_release);
+PHP_FUNCTION(com_propget);
+PHP_FUNCTION(com_propput);
+PHP_FUNCTION(com_load_typelib);
+PHP_FUNCTION(com_isenum);
+
+PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, char **ErrString TSRMLS_DC);
+PHPAPI HRESULT php_COM_get_ids_of_names(comval *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId TSRMLS_DC);
+PHPAPI HRESULT php_COM_release(comval *obj TSRMLS_DC);
+PHPAPI HRESULT php_COM_addref(comval *obj TSRMLS_DC);
+PHPAPI HRESULT php_COM_destruct(comval *obj TSRMLS_DC);
+PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* FAR* pDisp, int cleanup TSRMLS_DC);
+PHPAPI HRESULT php_COM_clone(comval *obj, comval *clone, int cleanup TSRMLS_DC);
+PHPAPI char *php_COM_error_message(HRESULT hr TSRMLS_DC);
+PHPAPI int php_COM_get_le_comval();
+PHPAPI int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value);
+PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_reference);
+PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
zend_module_entry COM_module_entry;
-zend_class_entry com_class_entry;
-
-pval php_COM_get_property_handler(zend_property_reference *property_reference);
-int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value);
-char *php_COM_error_message(HRESULT hr);
-void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
+zend_class_entry COM_class_entry;
#ifdef DEBUG
extern int resourcecounter;
diff --git a/ext/com/php_VARIANT.h b/ext/com/php_VARIANT.h
index 5e6d51f821..2447d066ad 100644
--- a/ext/com/php_VARIANT.h
+++ b/ext/com/php_VARIANT.h
@@ -3,14 +3,19 @@
#if PHP_WIN32
-#include "variant.h"
+BEGIN_EXTERN_C()
-extern int php_VARIANT_get_le_variant();
+#include "conversion.h"
+#include "variant.h"
PHP_MINIT_FUNCTION(VARIANT);
PHP_MSHUTDOWN_FUNCTION(VARIANT);
-extern zend_module_entry VARIANT_module_entry;
+PHPAPI int php_VARIANT_get_le_variant();
+
+zend_module_entry VARIANT_module_entry;
+
+END_EXTERN_C()
#define VARIANT_module_ptr &VARIANT_module_entry
diff --git a/ext/com/variant.h b/ext/com/variant.h
index ec25ee4e4b..ce5b4e66ae 100644
--- a/ext/com/variant.h
+++ b/ext/com/variant.h
@@ -3,7 +3,13 @@
#if PHP_WIN32
-#define ALLOC_VARIANT(v) (v) = (VARIANT *) emalloc(sizeof(VARIANT))
+#define ALLOC_VARIANT(v) (v) = (VARIANT *) emalloc(sizeof(VARIANT)); \
+ VariantInit(v);
+
+#define FREE_VARIANT(v) VariantClear(v); \
+ efree(v);
+
+
#define IS_VARIANT php_VARIANT_get_le_variant()
#endif /* PHP_WIN32 */