From 49be36d70d9c15062df92729e5135a106cd5916a Mon Sep 17 00:00:00 2001 From: Harald Radi Date: Sun, 13 May 2001 14:22:19 +0000 Subject: [PATCH] modified because of the changes in com.c --- ext/com/VARIANT.c | 52 +- ext/com/com.h | 5 +- ext/com/conversion.c | 1183 +++++++++++++++++++------------------ ext/rpc/com/com_wrapper.h | 5 +- ext/rpc/com/conversion.c | 1183 +++++++++++++++++++------------------ ext/rpc/com/variant.c | 52 +- 6 files changed, 1262 insertions(+), 1218 deletions(-) diff --git a/ext/com/VARIANT.c b/ext/com/VARIANT.c index 4c4657b2a0..b2e9d4bee4 100644 --- a/ext/com/VARIANT.c +++ b/ext/com/VARIANT.c @@ -50,7 +50,6 @@ function_entry VARIANT_functions[] = { {NULL, NULL, NULL} }; - static PHP_MINFO_FUNCTION(VARIANT) { php_info_print_table_start(); @@ -58,12 +57,10 @@ static PHP_MINFO_FUNCTION(VARIANT) php_info_print_table_end(); } - zend_module_entry VARIANT_module_entry = { "variant", VARIANT_functions, PHP_MINIT(VARIANT), PHP_MSHUTDOWN(VARIANT), NULL, NULL, PHP_MINFO(VARIANT), STANDARD_MODULE_PROPERTIES }; - PHP_MINIT_FUNCTION(VARIANT) { le_variant = zend_register_list_destructors_ex(php_variant_destructor, NULL, "VARIANT", module_number); @@ -92,7 +89,7 @@ PHP_MINIT_FUNCTION(VARIANT) REGISTER_LONG_CONSTANT("VT_UINT", VT_UINT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("VT_ARRAY", VT_ARRAY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("VT_BYREF", VT_BYREF, CONST_CS | CONST_PERSISTENT); - + /* codepages */ REGISTER_LONG_CONSTANT("CP_ACP", CP_ACP, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CP_MACCP", CP_MACCP, CONST_CS | CONST_PERSISTENT); @@ -106,7 +103,6 @@ PHP_MINIT_FUNCTION(VARIANT) return SUCCESS; } - PHP_MSHUTDOWN_FUNCTION(VARIANT) { return SUCCESS; @@ -118,15 +114,15 @@ void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper zend_overloaded_element *function_name = (zend_overloaded_element *) property_reference->elements_list->tail->data; VARIANT *pVar; - if ((zend_llist_count(property_reference->elements_list)==1) && !strcmp(function_name->element.value.str.val, "variant")) + if((zend_llist_count(property_reference->elements_list)==1) && !strcmp(function_name->element.value.str.val, "variant")) { /* constructor */ pval *object_handle, *data, *type, *code_page; - + pVar = emalloc(sizeof(VARIANT)); VariantInit(pVar); - switch (ZEND_NUM_ARGS()) + switch(ZEND_NUM_ARGS()) { case 0: /* nothing to do */ @@ -155,7 +151,8 @@ void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper return_value->type = IS_LONG; return_value->value.lval = zend_list_insert(pVar, le_variant); - if (!zend_is_true(return_value)) { + if(!zend_is_true(return_value)) + { var_reset(object); return; } @@ -174,7 +171,7 @@ pval php_VARIANT_get_property_handler(zend_property_reference *property_referenc { zend_overloaded_element *overloaded_property; int type; - + pval result, **var_handle, *object = property_reference->object; VARIANT *var_arg; @@ -182,22 +179,31 @@ pval php_VARIANT_get_property_handler(zend_property_reference *property_referenc zend_hash_index_find(object->value.obj.properties, 0, (void **) &var_handle); var_arg = zend_list_find((*var_handle)->value.lval, &type); - if (!var_arg || (type != le_variant)) { + if(!var_arg || (type != le_variant)) + { var_reset(&result); - } else { + } + else + { overloaded_property = (zend_overloaded_element *) property_reference->elements_list->head->data; - switch (overloaded_property->type) { + switch(overloaded_property->type) + { case OE_IS_ARRAY: var_reset(&result); break; case OE_IS_OBJECT: - if(!strcmp(overloaded_property->element.value.str.val, "value")) { + if(!strcmp(overloaded_property->element.value.str.val, "value")) + { php_variant_to_pval(var_arg, &result, 0, codepage); - } else if(!strcmp(overloaded_property->element.value.str.val, "type")) { + } + else if(!strcmp(overloaded_property->element.value.str.val, "type")) + { result.value.lval = var_arg->vt; result.type = IS_LONG; - } else { + } + else + { var_reset(&result); php_error(E_WARNING, "Unknown member."); } @@ -206,11 +212,11 @@ pval php_VARIANT_get_property_handler(zend_property_reference *property_referenc var_reset(&result); php_error(E_WARNING, "Unknown method."); break; - - pval_destructor(&overloaded_property->element); + + pval_destructor(&overloaded_property->element); } } - + return result; } @@ -218,7 +224,7 @@ int php_VARIANT_set_property_handler(zend_property_reference *property_reference { zend_overloaded_element *overloaded_property; int type; - + pval **var_handle, *object = property_reference->object; VARIANT *var_arg; @@ -226,9 +232,9 @@ int php_VARIANT_set_property_handler(zend_property_reference *property_reference zend_hash_index_find(object->value.obj.properties, 0, (void **) &var_handle); var_arg = zend_list_find((*var_handle)->value.lval, &type); - if (!var_arg || (type != le_variant)) + if(!var_arg || (type != le_variant)) return FAILURE; - + overloaded_property = (zend_overloaded_element *) property_reference->elements_list->head->data; do_VARIANT_propset(var_arg, &overloaded_property->element, value); pval_destructor(&overloaded_property->element); @@ -240,7 +246,7 @@ static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value) pval type; type.type = IS_STRING; - + if(!strcmp(arg_property->value.str.val, "bVal")) { type.value.lval = VT_UI1; diff --git a/ext/com/com.h b/ext/com/com.h index c9ab0e4349..5492b983a3 100644 --- a/ext/com/com.h +++ b/ext/com/com.h @@ -7,15 +7,18 @@ typedef struct i_dispatch_ { int typelib; + int referenced; struct { IDispatch *dispatch; ITypeInfo *typeinfo; } i; } i_dispatch; -PHPAPI HRESULT php_COM_invoke(i_dispatch *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult); +PHPAPI HRESULT php_COM_invoke(i_dispatch *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult); PHPAPI HRESULT php_COM_get_ids_of_names(i_dispatch *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId); PHPAPI HRESULT php_COM_release(i_dispatch *obj); +PHPAPI HRESULT php_COM_addref(i_dispatch *obj); +PHPAPI int php_COM_check_ref(i_dispatch *obj); PHPAPI HRESULT php_COM_set(i_dispatch *obj, IDispatch FAR* pDisp, int cleanup); PHPAPI HRESULT php_COM_clone(i_dispatch *obj, i_dispatch *clone, int cleanup); diff --git a/ext/com/conversion.c b/ext/com/conversion.c index 14d5d13ce1..8da558fb90 100644 --- a/ext/com/conversion.c +++ b/ext/com/conversion.c @@ -34,614 +34,627 @@ PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int per PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage) { - OLECHAR *unicode_str; - - switch (pval_arg->type) - { - case IS_NULL: - var_arg->vt = VT_EMPTY; - break; - - case IS_BOOL: - var_arg->vt = VT_BOOL; - var_arg->boolVal = (short)pval_arg->value.lval; - break; - - case IS_OBJECT: - if(!strcmp(pval_arg->value.obj.ce->name, "VARIANT")) - { - int type; - pval **var_handle; - - /* fetch the VARIANT structure */ - zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &var_handle); - var_arg->pvarVal = (VARIANT FAR*) zend_list_find((*var_handle)->value.lval, &type); - var_arg->vt = VT_VARIANT|VT_BYREF; - } - else if(!strcmp(pval_arg->value.obj.ce->name, "COM")) - { - pval **idispatch_handle; - i_dispatch *obj; - int type; - - /* fetch the IDispatch interface */ - zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &idispatch_handle); - obj = (i_dispatch *)zend_list_find((*idispatch_handle)->value.lval, &type); - if (!obj || (type != php_COM_get_le_idispatch())) - var_arg->vt = VT_EMPTY; - else - { - var_arg->vt = VT_DISPATCH; - var_arg->pdispVal = obj->i.dispatch; - } - } - else - var_arg->vt = VT_EMPTY; - break; - - case IS_RESOURCE: - case IS_CONSTANT: - case IS_CONSTANT_ARRAY: - case IS_ARRAY: - var_arg->vt = VT_EMPTY; - break; - - case IS_LONG: - var_arg->vt = VT_I4; /* assuming 32-bit platform */ - var_arg->lVal = pval_arg->value.lval; - break; - - case IS_DOUBLE: - var_arg->vt = VT_R8; /* assuming 64-bit double precision */ - var_arg->dblVal = pval_arg->value.dval; - break; - - case IS_STRING: - var_arg->vt = VT_BSTR; - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - var_arg->bstrVal = SysAllocString(unicode_str); - efree(unicode_str); - } + OLECHAR *unicode_str; + + switch(pval_arg->type) + { + case IS_NULL: + var_arg->vt = VT_EMPTY; + break; + + case IS_BOOL: + var_arg->vt = VT_BOOL; + var_arg->boolVal = (short)pval_arg->value.lval; + break; + + case IS_OBJECT: + if(!strcmp(pval_arg->value.obj.ce->name, "VARIANT")) + { + int type; + pval **var_handle; + + /* fetch the VARIANT structure */ + zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &var_handle); + var_arg->pvarVal = (VARIANT FAR*) zend_list_find((*var_handle)->value.lval, &type); + var_arg->vt = VT_VARIANT|VT_BYREF; + } + else if(!strcmp(pval_arg->value.obj.ce->name, "COM")) + { + pval **idispatch_handle; + i_dispatch *obj; + int type; + + /* fetch the IDispatch interface */ + zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &idispatch_handle); + obj = (i_dispatch *)zend_list_find((*idispatch_handle)->value.lval, &type); + if(!obj || (type != php_COM_get_le_idispatch())) + var_arg->vt = VT_EMPTY; + else + { + php_COM_check_ref(obj); + var_arg->vt = VT_DISPATCH; + var_arg->pdispVal = obj->i.dispatch; + } + } + else + var_arg->vt = VT_EMPTY; + break; + + case IS_RESOURCE: + case IS_CONSTANT: + case IS_CONSTANT_ARRAY: + case IS_ARRAY: + var_arg->vt = VT_EMPTY; + break; + + case IS_LONG: + var_arg->vt = VT_I4; /* assuming 32-bit platform */ + var_arg->lVal = pval_arg->value.lval; + break; + + case IS_DOUBLE: + var_arg->vt = VT_R8; /* assuming 64-bit double precision */ + var_arg->dblVal = pval_arg->value.dval; + break; + + case IS_STRING: + var_arg->vt = VT_BSTR; + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + var_arg->bstrVal = SysAllocString(unicode_str); + efree(unicode_str); + } } PHPAPI void php_pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, pval *pval_type, int codepage) { - OLECHAR *unicode_str; - - var_arg->vt = (short) pval_type->value.lval; - - switch(var_arg->vt) - { - case VT_UI1: - convert_to_long_ex(&pval_arg); - var_arg->bVal = (unsigned char)pval_arg->value.lval; - break; - - case VT_I2: - convert_to_long_ex(&pval_arg); - var_arg->iVal = (short)pval_arg->value.lval; - break; - - case VT_I4: - convert_to_long_ex(&pval_arg); - var_arg->lVal = pval_arg->value.lval; - break; - - case VT_R4: - convert_to_double_ex(&pval_arg); - var_arg->fltVal = (float)pval_arg->value.dval; - break; - - case VT_R8: - convert_to_double_ex(&pval_arg); - var_arg->dblVal = pval_arg->value.dval; - break; - - case VT_BOOL: - convert_to_boolean_ex(&pval_arg); - var_arg->boolVal = (short)pval_arg->value.lval; - break; - - case VT_ERROR: - convert_to_long_ex(&pval_arg); - var_arg->scode = pval_arg->value.lval; - break; - - case VT_CY: - convert_to_double_ex(&pval_arg); - VarCyFromR8(pval_arg->value.dval, &(var_arg->cyVal)); - break; - - case VT_DATE: - { - SYSTEMTIME wintime; - struct tm *phptime; - - phptime = gmtime(&(pval_arg->value.lval)); - - 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->date)); - } - - case VT_BSTR: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - var_arg->bstrVal = SysAllocString(unicode_str); - efree(unicode_str); - break; - - case VT_DECIMAL: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &(var_arg->decVal)); - break; - - case VT_DECIMAL|VT_BYREF: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, var_arg->pdecVal); - break; - - case VT_UNKNOWN: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != VT_DISPATCH) - var_arg->vt = VT_EMPTY; - else - { - HRESULT hr; - - hr = var_arg->pdispVal->lpVtbl->QueryInterface(var_arg->pdispVal, &IID_IUnknown, &(var_arg->punkVal)); - - if (FAILED(hr)) - { - php_error(E_WARNING,"can't query IUnknown"); - var_arg->vt = VT_EMPTY; - } - else - var_arg->vt = VT_UNKNOWN; - } - break; - - case VT_DISPATCH: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != VT_DISPATCH) - var_arg->vt = VT_EMPTY; - break; - - case VT_UI1|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pbVal = (unsigned char FAR*) &(pval_arg->value.lval); - break; - - case VT_I2|VT_BYREF: - convert_to_long(pval_arg); - var_arg->piVal = (short FAR*) &(pval_arg->value.lval); - break; - - case VT_I4|VT_BYREF: - convert_to_long(pval_arg); - var_arg->plVal = (long FAR*) &(pval_arg->value.lval); - break; - - case VT_R4|VT_BYREF: - convert_to_double(pval_arg); - var_arg->pfltVal = (float FAR*) &(pval_arg->value.lval); - break; - - case VT_R8|VT_BYREF: - convert_to_double(pval_arg); - var_arg->pdblVal = (double FAR*) &(pval_arg->value.lval); - break; - - case VT_BOOL|VT_BYREF: - convert_to_boolean(pval_arg); - var_arg->pboolVal = (short FAR*) &(pval_arg->value.lval); - break; - - case VT_ERROR|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pscode = (long FAR*) &(pval_arg->value.lval); - 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)); - - 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); - } - - case VT_BSTR|VT_BYREF: - convert_to_string(pval_arg); - var_arg->pbstrVal = (BSTR FAR*) emalloc(sizeof(BSTR FAR*)); - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - *(var_arg->pbstrVal) = SysAllocString(unicode_str); - efree(unicode_str); - break; - - case VT_UNKNOWN|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != VT_DISPATCH) - var_arg->vt = VT_EMPTY; - else - { - HRESULT hr; - - hr = var_arg->pdispVal->lpVtbl->QueryInterface(var_arg->pdispVal, &IID_IUnknown, &(var_arg->punkVal)); - - if (FAILED(hr)) - { - php_error(E_WARNING,"can't query IUnknown"); - var_arg->vt = VT_EMPTY; - } - else - var_arg->vt = VT_UNKNOWN|VT_BYREF; - } - break; - - case VT_DISPATCH|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != VT_DISPATCH) - var_arg->vt = VT_EMPTY; - else - var_arg->vt |= VT_BYREF; - break; - - case VT_VARIANT|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != (VT_VARIANT | VT_BYREF)) - var_arg->vt = VT_EMPTY; - break; - - case VT_I1: - convert_to_long_ex(&pval_arg); - var_arg->cVal = (char)pval_arg->value.lval; - break; - - case VT_UI2: - convert_to_long_ex(&pval_arg); - var_arg->uiVal = (unsigned short)pval_arg->value.lval; - break; - - case VT_UI4: - convert_to_long_ex(&pval_arg); - var_arg->ulVal = (unsigned long)pval_arg->value.lval; - break; - - case VT_INT: - convert_to_long_ex(&pval_arg); - var_arg->intVal = (int)pval_arg->value.lval; - break; - - case VT_UINT: - convert_to_long_ex(&pval_arg); - var_arg->uintVal = (unsigned int)pval_arg->value.lval; - break; - - case VT_I1|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pcVal = (char FAR*) &pval_arg->value.lval; - break; - - case VT_UI2|VT_BYREF: - convert_to_long(pval_arg); - var_arg->puiVal = (unsigned short FAR*) &pval_arg->value.lval; - break; - - case VT_UI4|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pulVal = (unsigned long FAR*) &pval_arg->value.lval; - break; - - case VT_INT|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pintVal = (int FAR*) &pval_arg->value.lval; - break; - - case VT_UINT|VT_BYREF: - convert_to_long(pval_arg); - var_arg->puintVal = (unsigned int FAR*) &pval_arg->value.lval; - break; - - default: - php_error(E_WARNING, "Type not supportet or not yet implemented."); - } + OLECHAR *unicode_str; + + var_arg->vt = (short) pval_type->value.lval; + + switch(var_arg->vt) + { + case VT_UI1: + convert_to_long_ex(&pval_arg); + var_arg->bVal = (unsigned char)pval_arg->value.lval; + break; + + case VT_I2: + convert_to_long_ex(&pval_arg); + var_arg->iVal = (short)pval_arg->value.lval; + break; + + case VT_I4: + convert_to_long_ex(&pval_arg); + var_arg->lVal = pval_arg->value.lval; + break; + + case VT_R4: + convert_to_double_ex(&pval_arg); + var_arg->fltVal = (float)pval_arg->value.dval; + break; + + case VT_R8: + convert_to_double_ex(&pval_arg); + var_arg->dblVal = pval_arg->value.dval; + break; + + case VT_BOOL: + convert_to_boolean_ex(&pval_arg); + var_arg->boolVal = (short)pval_arg->value.lval; + break; + + case VT_ERROR: + convert_to_long_ex(&pval_arg); + var_arg->scode = pval_arg->value.lval; + break; + + case VT_CY: + convert_to_double_ex(&pval_arg); + VarCyFromR8(pval_arg->value.dval, &(var_arg->cyVal)); + break; + + case VT_DATE: + { + SYSTEMTIME wintime; + struct tm *phptime; + + phptime = gmtime(&(pval_arg->value.lval)); + + 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->date)); + } + + case VT_BSTR: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + var_arg->bstrVal = SysAllocString(unicode_str); + efree(unicode_str); + break; + + case VT_DECIMAL: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &(var_arg->decVal)); + break; + + case VT_DECIMAL|VT_BYREF: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, var_arg->pdecVal); + break; + + case VT_UNKNOWN: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != VT_DISPATCH) + var_arg->vt = VT_EMPTY; + else + { + HRESULT hr; + + hr = var_arg->pdispVal->lpVtbl->QueryInterface(var_arg->pdispVal, &IID_IUnknown, &(var_arg->punkVal)); + + if(FAILED(hr)) + { + php_error(E_WARNING,"can't query IUnknown"); + var_arg->vt = VT_EMPTY; + } + else + var_arg->vt = VT_UNKNOWN; + } + break; + + case VT_DISPATCH: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != VT_DISPATCH) + var_arg->vt = VT_EMPTY; + break; + + case VT_UI1|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pbVal = (unsigned char FAR*) &(pval_arg->value.lval); + break; + + case VT_I2|VT_BYREF: + convert_to_long(pval_arg); + var_arg->piVal = (short FAR*) &(pval_arg->value.lval); + break; + + case VT_I4|VT_BYREF: + convert_to_long(pval_arg); + var_arg->plVal = (long FAR*) &(pval_arg->value.lval); + break; + + case VT_R4|VT_BYREF: + convert_to_double(pval_arg); + var_arg->pfltVal = (float FAR*) &(pval_arg->value.lval); + break; + + case VT_R8|VT_BYREF: + convert_to_double(pval_arg); + var_arg->pdblVal = (double FAR*) &(pval_arg->value.lval); + break; + + case VT_BOOL|VT_BYREF: + convert_to_boolean(pval_arg); + var_arg->pboolVal = (short FAR*) &(pval_arg->value.lval); + break; + + case VT_ERROR|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pscode = (long FAR*) &(pval_arg->value.lval); + 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)); + + 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); + } + + case VT_BSTR|VT_BYREF: + convert_to_string(pval_arg); + var_arg->pbstrVal = (BSTR FAR*) emalloc(sizeof(BSTR FAR*)); + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + *(var_arg->pbstrVal) = SysAllocString(unicode_str); + efree(unicode_str); + break; + + case VT_UNKNOWN|VT_BYREF: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != VT_DISPATCH) + var_arg->vt = VT_EMPTY; + else + { + HRESULT hr; + + hr = var_arg->pdispVal->lpVtbl->QueryInterface(var_arg->pdispVal, &IID_IUnknown, &(var_arg->punkVal)); + + if(FAILED(hr)) + { + php_error(E_WARNING,"can't query IUnknown"); + var_arg->vt = VT_EMPTY; + } + else + var_arg->vt = VT_UNKNOWN|VT_BYREF; + } + break; + + case VT_DISPATCH|VT_BYREF: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != VT_DISPATCH) + var_arg->vt = VT_EMPTY; + else + var_arg->vt |= VT_BYREF; + break; + + case VT_VARIANT|VT_BYREF: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != (VT_VARIANT | VT_BYREF)) + var_arg->vt = VT_EMPTY; + break; + + case VT_I1: + convert_to_long_ex(&pval_arg); + var_arg->cVal = (char)pval_arg->value.lval; + break; + + case VT_UI2: + convert_to_long_ex(&pval_arg); + var_arg->uiVal = (unsigned short)pval_arg->value.lval; + break; + + case VT_UI4: + convert_to_long_ex(&pval_arg); + var_arg->ulVal = (unsigned long)pval_arg->value.lval; + break; + + case VT_INT: + convert_to_long_ex(&pval_arg); + var_arg->intVal = (int)pval_arg->value.lval; + break; + + case VT_UINT: + convert_to_long_ex(&pval_arg); + var_arg->uintVal = (unsigned int)pval_arg->value.lval; + break; + + case VT_I1|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pcVal = (char FAR*) &pval_arg->value.lval; + break; + + case VT_UI2|VT_BYREF: + convert_to_long(pval_arg); + var_arg->puiVal = (unsigned short FAR*) &pval_arg->value.lval; + break; + + case VT_UI4|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pulVal = (unsigned long FAR*) &pval_arg->value.lval; + break; + + case VT_INT|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pintVal = (int FAR*) &pval_arg->value.lval; + break; + + case VT_UINT|VT_BYREF: + convert_to_long(pval_arg); + var_arg->puintVal = (unsigned int FAR*) &pval_arg->value.lval; + break; + + default: + php_error(E_WARNING, "Type not supportet or not yet implemented."); + } } PHPAPI void php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, int codepage) { - switch(var_arg->vt & ~VT_BYREF) - { - case VT_EMPTY: - var_uninit(pval_arg); - break; - - case VT_UI1: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->pbVal); - else - pval_arg->value.lval = (long) var_arg->bVal; - - pval_arg->type = IS_LONG; - break; - - case VT_I2: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long )*(var_arg->piVal); - else - pval_arg->value.lval = (long) var_arg->iVal; - - pval_arg->type = IS_LONG; - break; - - case VT_I4: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = *(var_arg->plVal); - else - pval_arg->value.lval = var_arg->lVal; - - pval_arg->type = IS_LONG; - break; - - case VT_R4: - if(var_arg->vt & VT_BYREF) - pval_arg->value.dval = (double)*(var_arg->pfltVal); - else - pval_arg->value.dval = (double) var_arg->fltVal; - - pval_arg->type = IS_DOUBLE; - break; - - case VT_R8: - if(var_arg->vt & VT_BYREF) - pval_arg->value.dval = *(var_arg->pdblVal); - else - pval_arg->value.dval = var_arg->dblVal; - - pval_arg->type = IS_DOUBLE; - break; - - case VT_DECIMAL: - { - OLECHAR *unicode_str; - switch(VarBstrFromDec(&var_arg->decVal, LOCALE_SYSTEM_DEFAULT, 0, &unicode_str)) - { - case S_OK: - pval_arg->value.str.val = php_OLECHAR_to_char(unicode_str, &pval_arg->value.str.len, persistent, codepage); - pval_arg->type = IS_STRING; - break; - - default: - php_error(E_WARNING, "Error converting DECIMAL value to PHP floating point"); - break; - } - } - break; - - case VT_CY: - if(var_arg->vt & VT_BYREF) - VarR8FromCy(var_arg->cyVal, &(pval_arg->value.dval)); - else - VarR8FromCy(*(var_arg->pcyVal), &(pval_arg->value.dval)); - - pval_arg->type = IS_DOUBLE; - break; - - case VT_BOOL: - if (var_arg->vt & VT_BYREF) - if (*(var_arg->pboolVal) & 0xFFFF) - pval_arg->value.lval = 1; - else - pval_arg->value.lval = 0; - else - if (var_arg->boolVal & 0xFFFF) - pval_arg->value.lval = 1; - else - pval_arg->value.lval = 0; - - pval_arg->type = IS_BOOL; - break; - - case VT_NULL: - case VT_VOID: - pval_arg->type = IS_NULL; - break; - - case VT_VARIANT: - php_variant_to_pval(var_arg->pvarVal, pval_arg, persistent, codepage); - break; - - case VT_BSTR: - if (pval_arg->is_ref == 0 || (var_arg->vt & VT_BYREF) != VT_BYREF) { - pval_arg->value.str.val = php_OLECHAR_to_char(var_arg->bstrVal, &pval_arg->value.str.len, persistent, codepage); - SysFreeString(var_arg->bstrVal); - } else { - pval_arg->value.str.val = php_OLECHAR_to_char(*(var_arg->pbstrVal), &pval_arg->value.str.len, persistent, codepage); - SysFreeString(*(var_arg->pbstrVal)); - efree(var_arg->pbstrVal); - } - - pval_arg->type = IS_STRING; - break; - - case VT_DATE: { - SYSTEMTIME wintime; - struct tm phptime; - - VariantTimeToSystemTime(var_arg->date, &wintime); - - phptime.tm_year = wintime.wYear - 1900; - phptime.tm_mon = wintime.wMonth - 1; - phptime.tm_mday = wintime.wDay; - phptime.tm_hour = wintime.wHour; - phptime.tm_min = wintime.wMinute; - phptime.tm_sec = wintime.wSecond; - phptime.tm_isdst = -1; - - tzset(); - pval_arg->value.lval = mktime(&phptime); - pval_arg->type = IS_LONG; - } - break; - case VT_DISPATCH: { - pval *handle; - i_dispatch *obj; - - pval_arg->type=IS_OBJECT; - pval_arg->value.obj.ce = &com_class_entry; - pval_arg->value.obj.properties = (HashTable *) emalloc(sizeof(HashTable)); - pval_arg->is_ref=1; - pval_arg->refcount=1; - zend_hash_init(pval_arg->value.obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0); - - ALLOC_ZVAL(handle); - obj = emalloc(sizeof(i_dispatch)); - php_COM_set(obj, var_arg->pdispVal, TRUE); - - handle->type = IS_LONG; - handle->value.lval = zend_list_insert(obj, php_COM_get_le_idispatch()); - pval_copy_constructor(handle); - INIT_PZVAL(handle); - zend_hash_index_update(pval_arg->value.obj.properties, 0, &handle, sizeof(pval *), NULL); - } - break; - case VT_UNKNOWN: -//wtf ?? - var_arg->pdispVal->lpVtbl->Release(var_arg->pdispVal); - /* break missing intentionally */ - - case VT_I1: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->pcVal); - else - pval_arg->value.lval = (long) var_arg->cVal; - - pval_arg->type = IS_LONG; - break; - - case VT_UI2: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->puiVal); - else - pval_arg->value.lval = (long) var_arg->uiVal; - - pval_arg->type = IS_LONG; - break; - - case VT_UI4: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->pulVal); - else - pval_arg->value.lval = (long) var_arg->ulVal; - - pval_arg->type = IS_LONG; - break; - - case VT_INT: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->pintVal); - else - pval_arg->value.lval = (long) var_arg->intVal; - - pval_arg->type = IS_LONG; - break; - - case VT_UINT: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->puintVal); - else - pval_arg->value.lval = (long) var_arg->uintVal; - - pval_arg->type = IS_LONG; - break; - - default: - php_error(E_WARNING,"Unsupported variant type: %d (0x%X)", var_arg->vt, var_arg->vt); - var_reset(pval_arg); - break; - } + switch(var_arg->vt & ~VT_BYREF) + { + case VT_EMPTY: + var_uninit(pval_arg); + break; + + case VT_UI1: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->pbVal); + else + pval_arg->value.lval = (long) var_arg->bVal; + + pval_arg->type = IS_LONG; + break; + + case VT_I2: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long )*(var_arg->piVal); + else + pval_arg->value.lval = (long) var_arg->iVal; + + pval_arg->type = IS_LONG; + break; + + case VT_I4: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = *(var_arg->plVal); + else + pval_arg->value.lval = var_arg->lVal; + + pval_arg->type = IS_LONG; + break; + + case VT_R4: + if(var_arg->vt & VT_BYREF) + pval_arg->value.dval = (double)*(var_arg->pfltVal); + else + pval_arg->value.dval = (double) var_arg->fltVal; + + pval_arg->type = IS_DOUBLE; + break; + + case VT_R8: + if(var_arg->vt & VT_BYREF) + pval_arg->value.dval = *(var_arg->pdblVal); + else + pval_arg->value.dval = var_arg->dblVal; + + pval_arg->type = IS_DOUBLE; + break; + + case VT_DECIMAL: + { + OLECHAR *unicode_str; + switch(VarBstrFromDec(&var_arg->decVal, LOCALE_SYSTEM_DEFAULT, 0, &unicode_str)) + { + case S_OK: + pval_arg->value.str.val = php_OLECHAR_to_char(unicode_str, &pval_arg->value.str.len, persistent, codepage); + pval_arg->type = IS_STRING; + break; + + default: + php_error(E_WARNING, "Error converting DECIMAL value to PHP floating point"); + break; + } + } + break; + + case VT_CY: + if(var_arg->vt & VT_BYREF) + VarR8FromCy(var_arg->cyVal, &(pval_arg->value.dval)); + else + VarR8FromCy(*(var_arg->pcyVal), &(pval_arg->value.dval)); + + pval_arg->type = IS_DOUBLE; + break; + + case VT_BOOL: + if(var_arg->vt & VT_BYREF) + if(*(var_arg->pboolVal) & 0xFFFF) + pval_arg->value.lval = 1; + else + pval_arg->value.lval = 0; + else + if(var_arg->boolVal & 0xFFFF) + pval_arg->value.lval = 1; + else + pval_arg->value.lval = 0; + + pval_arg->type = IS_BOOL; + break; + + case VT_NULL: + case VT_VOID: + pval_arg->type = IS_NULL; + break; + + case VT_VARIANT: + php_variant_to_pval(var_arg->pvarVal, pval_arg, persistent, codepage); + break; + + case VT_BSTR: + if(pval_arg->is_ref == 0 || (var_arg->vt & VT_BYREF) != VT_BYREF) + { + pval_arg->value.str.val = php_OLECHAR_to_char(var_arg->bstrVal, &pval_arg->value.str.len, persistent, codepage); + SysFreeString(var_arg->bstrVal); + } + else + { + pval_arg->value.str.val = php_OLECHAR_to_char(*(var_arg->pbstrVal), &pval_arg->value.str.len, persistent, codepage); + SysFreeString(*(var_arg->pbstrVal)); + efree(var_arg->pbstrVal); + } + + pval_arg->type = IS_STRING; + break; + + case VT_DATE: { + SYSTEMTIME wintime; + struct tm phptime; + + VariantTimeToSystemTime(var_arg->date, &wintime); + + phptime.tm_year = wintime.wYear - 1900; + phptime.tm_mon = wintime.wMonth - 1; + phptime.tm_mday = wintime.wDay; + phptime.tm_hour = wintime.wHour; + phptime.tm_min = wintime.wMinute; + phptime.tm_sec = wintime.wSecond; + phptime.tm_isdst = -1; + + tzset(); + pval_arg->value.lval = mktime(&phptime); + pval_arg->type = IS_LONG; + } + break; + case VT_UNKNOWN: + + //IDispatch holen und dann weiterfiechen + //wtf ?? + var_arg->pdispVal->lpVtbl->Release(var_arg->pdispVal); + /* break missing intentionally */ + + case VT_DISPATCH: { + pval *handle; + i_dispatch *obj; + + if(var_arg->pdispVal == NULL) + { + pval_arg->type = IS_NULL; + } + else + { + pval_arg->type = IS_OBJECT; + pval_arg->value.obj.ce = &com_class_entry; + pval_arg->value.obj.properties = (HashTable *) emalloc(sizeof(HashTable)); + pval_arg->is_ref = 1; + pval_arg->refcount = 1; + zend_hash_init(pval_arg->value.obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + + ALLOC_ZVAL(handle); + obj = emalloc(sizeof(i_dispatch)); + php_COM_set(obj, var_arg->pdispVal, TRUE); + + handle->type = IS_LONG; + handle->value.lval = zend_list_insert(obj, php_COM_get_le_idispatch()); + pval_copy_constructor(handle); + INIT_PZVAL(handle); + zend_hash_index_update(pval_arg->value.obj.properties, 0, &handle, sizeof(pval *), NULL); + } + } + break; + case VT_I1: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->pcVal); + else + pval_arg->value.lval = (long) var_arg->cVal; + + pval_arg->type = IS_LONG; + break; + + case VT_UI2: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->puiVal); + else + pval_arg->value.lval = (long) var_arg->uiVal; + + pval_arg->type = IS_LONG; + break; + + case VT_UI4: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->pulVal); + else + pval_arg->value.lval = (long) var_arg->ulVal; + + pval_arg->type = IS_LONG; + break; + + case VT_INT: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->pintVal); + else + pval_arg->value.lval = (long) var_arg->intVal; + + pval_arg->type = IS_LONG; + break; + + case VT_UINT: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->puintVal); + else + pval_arg->value.lval = (long) var_arg->uintVal; + + pval_arg->type = IS_LONG; + break; + + default: + php_error(E_WARNING,"Unsupported variant type: %d (0x%X)", var_arg->vt, var_arg->vt); + var_reset(pval_arg); + break; + } } PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage) { - OLECHAR *unicode_str; - - //request needed buffersize - uint reqSize = MultiByteToWideChar(codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, C_str, -1, NULL, 0); - - if(reqSize) - { - unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR) * reqSize); - - //convert string - MultiByteToWideChar(codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, C_str, -1, unicode_str, reqSize); - } - else - { - unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR)); - *unicode_str = 0; - - switch(GetLastError()) - { - case ERROR_NO_UNICODE_TRANSLATION: - php_error(E_WARNING,"No unicode translation available for the specified string"); - break; - default: - php_error(E_WARNING,"Error in php_char_to_OLECHAR()"); - } - } - - return unicode_str; + OLECHAR *unicode_str; + + //request needed buffersize + uint reqSize = MultiByteToWideChar(codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, C_str, -1, NULL, 0); + + if(reqSize) + { + unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR) * reqSize); + + //convert string + MultiByteToWideChar(codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, C_str, -1, unicode_str, reqSize); + } + else + { + unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR)); + *unicode_str = 0; + + switch(GetLastError()) + { + case ERROR_NO_UNICODE_TRANSLATION: + php_error(E_WARNING,"No unicode translation available for the specified string"); + break; + default: + 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) { - char *C_str; - uint length = 0; + char *C_str; + uint length = 0; - //request needed buffersize - uint reqSize = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, unicode_str, -1, NULL, 0, NULL, NULL); + //request needed buffersize + uint reqSize = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, unicode_str, -1, NULL, 0, NULL, NULL); - if(reqSize) - { - C_str = (char *) pemalloc(sizeof(char) * reqSize, persistent); + if(reqSize) + { + C_str = (char *) pemalloc(sizeof(char) * reqSize, persistent); - //convert string - length = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, unicode_str, -1, C_str, reqSize, NULL, NULL) - 1; - } - else - { - C_str = (char *) pemalloc(sizeof(char), persistent); - *C_str = 0; + //convert string + length = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, unicode_str, -1, C_str, reqSize, NULL, NULL) - 1; + } + else + { + 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) - *out_length = length; + if(out_length) + *out_length = length; - return C_str; + return C_str; } #endif /* PHP_WIN32 */ \ No newline at end of file diff --git a/ext/rpc/com/com_wrapper.h b/ext/rpc/com/com_wrapper.h index c9ab0e4349..5492b983a3 100644 --- a/ext/rpc/com/com_wrapper.h +++ b/ext/rpc/com/com_wrapper.h @@ -7,15 +7,18 @@ typedef struct i_dispatch_ { int typelib; + int referenced; struct { IDispatch *dispatch; ITypeInfo *typeinfo; } i; } i_dispatch; -PHPAPI HRESULT php_COM_invoke(i_dispatch *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult); +PHPAPI HRESULT php_COM_invoke(i_dispatch *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult); PHPAPI HRESULT php_COM_get_ids_of_names(i_dispatch *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId); PHPAPI HRESULT php_COM_release(i_dispatch *obj); +PHPAPI HRESULT php_COM_addref(i_dispatch *obj); +PHPAPI int php_COM_check_ref(i_dispatch *obj); PHPAPI HRESULT php_COM_set(i_dispatch *obj, IDispatch FAR* pDisp, int cleanup); PHPAPI HRESULT php_COM_clone(i_dispatch *obj, i_dispatch *clone, int cleanup); diff --git a/ext/rpc/com/conversion.c b/ext/rpc/com/conversion.c index 14d5d13ce1..8da558fb90 100644 --- a/ext/rpc/com/conversion.c +++ b/ext/rpc/com/conversion.c @@ -34,614 +34,627 @@ PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int per PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage) { - OLECHAR *unicode_str; - - switch (pval_arg->type) - { - case IS_NULL: - var_arg->vt = VT_EMPTY; - break; - - case IS_BOOL: - var_arg->vt = VT_BOOL; - var_arg->boolVal = (short)pval_arg->value.lval; - break; - - case IS_OBJECT: - if(!strcmp(pval_arg->value.obj.ce->name, "VARIANT")) - { - int type; - pval **var_handle; - - /* fetch the VARIANT structure */ - zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &var_handle); - var_arg->pvarVal = (VARIANT FAR*) zend_list_find((*var_handle)->value.lval, &type); - var_arg->vt = VT_VARIANT|VT_BYREF; - } - else if(!strcmp(pval_arg->value.obj.ce->name, "COM")) - { - pval **idispatch_handle; - i_dispatch *obj; - int type; - - /* fetch the IDispatch interface */ - zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &idispatch_handle); - obj = (i_dispatch *)zend_list_find((*idispatch_handle)->value.lval, &type); - if (!obj || (type != php_COM_get_le_idispatch())) - var_arg->vt = VT_EMPTY; - else - { - var_arg->vt = VT_DISPATCH; - var_arg->pdispVal = obj->i.dispatch; - } - } - else - var_arg->vt = VT_EMPTY; - break; - - case IS_RESOURCE: - case IS_CONSTANT: - case IS_CONSTANT_ARRAY: - case IS_ARRAY: - var_arg->vt = VT_EMPTY; - break; - - case IS_LONG: - var_arg->vt = VT_I4; /* assuming 32-bit platform */ - var_arg->lVal = pval_arg->value.lval; - break; - - case IS_DOUBLE: - var_arg->vt = VT_R8; /* assuming 64-bit double precision */ - var_arg->dblVal = pval_arg->value.dval; - break; - - case IS_STRING: - var_arg->vt = VT_BSTR; - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - var_arg->bstrVal = SysAllocString(unicode_str); - efree(unicode_str); - } + OLECHAR *unicode_str; + + switch(pval_arg->type) + { + case IS_NULL: + var_arg->vt = VT_EMPTY; + break; + + case IS_BOOL: + var_arg->vt = VT_BOOL; + var_arg->boolVal = (short)pval_arg->value.lval; + break; + + case IS_OBJECT: + if(!strcmp(pval_arg->value.obj.ce->name, "VARIANT")) + { + int type; + pval **var_handle; + + /* fetch the VARIANT structure */ + zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &var_handle); + var_arg->pvarVal = (VARIANT FAR*) zend_list_find((*var_handle)->value.lval, &type); + var_arg->vt = VT_VARIANT|VT_BYREF; + } + else if(!strcmp(pval_arg->value.obj.ce->name, "COM")) + { + pval **idispatch_handle; + i_dispatch *obj; + int type; + + /* fetch the IDispatch interface */ + zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &idispatch_handle); + obj = (i_dispatch *)zend_list_find((*idispatch_handle)->value.lval, &type); + if(!obj || (type != php_COM_get_le_idispatch())) + var_arg->vt = VT_EMPTY; + else + { + php_COM_check_ref(obj); + var_arg->vt = VT_DISPATCH; + var_arg->pdispVal = obj->i.dispatch; + } + } + else + var_arg->vt = VT_EMPTY; + break; + + case IS_RESOURCE: + case IS_CONSTANT: + case IS_CONSTANT_ARRAY: + case IS_ARRAY: + var_arg->vt = VT_EMPTY; + break; + + case IS_LONG: + var_arg->vt = VT_I4; /* assuming 32-bit platform */ + var_arg->lVal = pval_arg->value.lval; + break; + + case IS_DOUBLE: + var_arg->vt = VT_R8; /* assuming 64-bit double precision */ + var_arg->dblVal = pval_arg->value.dval; + break; + + case IS_STRING: + var_arg->vt = VT_BSTR; + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + var_arg->bstrVal = SysAllocString(unicode_str); + efree(unicode_str); + } } PHPAPI void php_pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, pval *pval_type, int codepage) { - OLECHAR *unicode_str; - - var_arg->vt = (short) pval_type->value.lval; - - switch(var_arg->vt) - { - case VT_UI1: - convert_to_long_ex(&pval_arg); - var_arg->bVal = (unsigned char)pval_arg->value.lval; - break; - - case VT_I2: - convert_to_long_ex(&pval_arg); - var_arg->iVal = (short)pval_arg->value.lval; - break; - - case VT_I4: - convert_to_long_ex(&pval_arg); - var_arg->lVal = pval_arg->value.lval; - break; - - case VT_R4: - convert_to_double_ex(&pval_arg); - var_arg->fltVal = (float)pval_arg->value.dval; - break; - - case VT_R8: - convert_to_double_ex(&pval_arg); - var_arg->dblVal = pval_arg->value.dval; - break; - - case VT_BOOL: - convert_to_boolean_ex(&pval_arg); - var_arg->boolVal = (short)pval_arg->value.lval; - break; - - case VT_ERROR: - convert_to_long_ex(&pval_arg); - var_arg->scode = pval_arg->value.lval; - break; - - case VT_CY: - convert_to_double_ex(&pval_arg); - VarCyFromR8(pval_arg->value.dval, &(var_arg->cyVal)); - break; - - case VT_DATE: - { - SYSTEMTIME wintime; - struct tm *phptime; - - phptime = gmtime(&(pval_arg->value.lval)); - - 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->date)); - } - - case VT_BSTR: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - var_arg->bstrVal = SysAllocString(unicode_str); - efree(unicode_str); - break; - - case VT_DECIMAL: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &(var_arg->decVal)); - break; - - case VT_DECIMAL|VT_BYREF: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, var_arg->pdecVal); - break; - - case VT_UNKNOWN: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != VT_DISPATCH) - var_arg->vt = VT_EMPTY; - else - { - HRESULT hr; - - hr = var_arg->pdispVal->lpVtbl->QueryInterface(var_arg->pdispVal, &IID_IUnknown, &(var_arg->punkVal)); - - if (FAILED(hr)) - { - php_error(E_WARNING,"can't query IUnknown"); - var_arg->vt = VT_EMPTY; - } - else - var_arg->vt = VT_UNKNOWN; - } - break; - - case VT_DISPATCH: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != VT_DISPATCH) - var_arg->vt = VT_EMPTY; - break; - - case VT_UI1|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pbVal = (unsigned char FAR*) &(pval_arg->value.lval); - break; - - case VT_I2|VT_BYREF: - convert_to_long(pval_arg); - var_arg->piVal = (short FAR*) &(pval_arg->value.lval); - break; - - case VT_I4|VT_BYREF: - convert_to_long(pval_arg); - var_arg->plVal = (long FAR*) &(pval_arg->value.lval); - break; - - case VT_R4|VT_BYREF: - convert_to_double(pval_arg); - var_arg->pfltVal = (float FAR*) &(pval_arg->value.lval); - break; - - case VT_R8|VT_BYREF: - convert_to_double(pval_arg); - var_arg->pdblVal = (double FAR*) &(pval_arg->value.lval); - break; - - case VT_BOOL|VT_BYREF: - convert_to_boolean(pval_arg); - var_arg->pboolVal = (short FAR*) &(pval_arg->value.lval); - break; - - case VT_ERROR|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pscode = (long FAR*) &(pval_arg->value.lval); - 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)); - - 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); - } - - case VT_BSTR|VT_BYREF: - convert_to_string(pval_arg); - var_arg->pbstrVal = (BSTR FAR*) emalloc(sizeof(BSTR FAR*)); - unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); - *(var_arg->pbstrVal) = SysAllocString(unicode_str); - efree(unicode_str); - break; - - case VT_UNKNOWN|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != VT_DISPATCH) - var_arg->vt = VT_EMPTY; - else - { - HRESULT hr; - - hr = var_arg->pdispVal->lpVtbl->QueryInterface(var_arg->pdispVal, &IID_IUnknown, &(var_arg->punkVal)); - - if (FAILED(hr)) - { - php_error(E_WARNING,"can't query IUnknown"); - var_arg->vt = VT_EMPTY; - } - else - var_arg->vt = VT_UNKNOWN|VT_BYREF; - } - break; - - case VT_DISPATCH|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != VT_DISPATCH) - var_arg->vt = VT_EMPTY; - else - var_arg->vt |= VT_BYREF; - break; - - case VT_VARIANT|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(var_arg->vt != (VT_VARIANT | VT_BYREF)) - var_arg->vt = VT_EMPTY; - break; - - case VT_I1: - convert_to_long_ex(&pval_arg); - var_arg->cVal = (char)pval_arg->value.lval; - break; - - case VT_UI2: - convert_to_long_ex(&pval_arg); - var_arg->uiVal = (unsigned short)pval_arg->value.lval; - break; - - case VT_UI4: - convert_to_long_ex(&pval_arg); - var_arg->ulVal = (unsigned long)pval_arg->value.lval; - break; - - case VT_INT: - convert_to_long_ex(&pval_arg); - var_arg->intVal = (int)pval_arg->value.lval; - break; - - case VT_UINT: - convert_to_long_ex(&pval_arg); - var_arg->uintVal = (unsigned int)pval_arg->value.lval; - break; - - case VT_I1|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pcVal = (char FAR*) &pval_arg->value.lval; - break; - - case VT_UI2|VT_BYREF: - convert_to_long(pval_arg); - var_arg->puiVal = (unsigned short FAR*) &pval_arg->value.lval; - break; - - case VT_UI4|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pulVal = (unsigned long FAR*) &pval_arg->value.lval; - break; - - case VT_INT|VT_BYREF: - convert_to_long(pval_arg); - var_arg->pintVal = (int FAR*) &pval_arg->value.lval; - break; - - case VT_UINT|VT_BYREF: - convert_to_long(pval_arg); - var_arg->puintVal = (unsigned int FAR*) &pval_arg->value.lval; - break; - - default: - php_error(E_WARNING, "Type not supportet or not yet implemented."); - } + OLECHAR *unicode_str; + + var_arg->vt = (short) pval_type->value.lval; + + switch(var_arg->vt) + { + case VT_UI1: + convert_to_long_ex(&pval_arg); + var_arg->bVal = (unsigned char)pval_arg->value.lval; + break; + + case VT_I2: + convert_to_long_ex(&pval_arg); + var_arg->iVal = (short)pval_arg->value.lval; + break; + + case VT_I4: + convert_to_long_ex(&pval_arg); + var_arg->lVal = pval_arg->value.lval; + break; + + case VT_R4: + convert_to_double_ex(&pval_arg); + var_arg->fltVal = (float)pval_arg->value.dval; + break; + + case VT_R8: + convert_to_double_ex(&pval_arg); + var_arg->dblVal = pval_arg->value.dval; + break; + + case VT_BOOL: + convert_to_boolean_ex(&pval_arg); + var_arg->boolVal = (short)pval_arg->value.lval; + break; + + case VT_ERROR: + convert_to_long_ex(&pval_arg); + var_arg->scode = pval_arg->value.lval; + break; + + case VT_CY: + convert_to_double_ex(&pval_arg); + VarCyFromR8(pval_arg->value.dval, &(var_arg->cyVal)); + break; + + case VT_DATE: + { + SYSTEMTIME wintime; + struct tm *phptime; + + phptime = gmtime(&(pval_arg->value.lval)); + + 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->date)); + } + + case VT_BSTR: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + var_arg->bstrVal = SysAllocString(unicode_str); + efree(unicode_str); + break; + + case VT_DECIMAL: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &(var_arg->decVal)); + break; + + case VT_DECIMAL|VT_BYREF: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, var_arg->pdecVal); + break; + + case VT_UNKNOWN: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != VT_DISPATCH) + var_arg->vt = VT_EMPTY; + else + { + HRESULT hr; + + hr = var_arg->pdispVal->lpVtbl->QueryInterface(var_arg->pdispVal, &IID_IUnknown, &(var_arg->punkVal)); + + if(FAILED(hr)) + { + php_error(E_WARNING,"can't query IUnknown"); + var_arg->vt = VT_EMPTY; + } + else + var_arg->vt = VT_UNKNOWN; + } + break; + + case VT_DISPATCH: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != VT_DISPATCH) + var_arg->vt = VT_EMPTY; + break; + + case VT_UI1|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pbVal = (unsigned char FAR*) &(pval_arg->value.lval); + break; + + case VT_I2|VT_BYREF: + convert_to_long(pval_arg); + var_arg->piVal = (short FAR*) &(pval_arg->value.lval); + break; + + case VT_I4|VT_BYREF: + convert_to_long(pval_arg); + var_arg->plVal = (long FAR*) &(pval_arg->value.lval); + break; + + case VT_R4|VT_BYREF: + convert_to_double(pval_arg); + var_arg->pfltVal = (float FAR*) &(pval_arg->value.lval); + break; + + case VT_R8|VT_BYREF: + convert_to_double(pval_arg); + var_arg->pdblVal = (double FAR*) &(pval_arg->value.lval); + break; + + case VT_BOOL|VT_BYREF: + convert_to_boolean(pval_arg); + var_arg->pboolVal = (short FAR*) &(pval_arg->value.lval); + break; + + case VT_ERROR|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pscode = (long FAR*) &(pval_arg->value.lval); + 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)); + + 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); + } + + case VT_BSTR|VT_BYREF: + convert_to_string(pval_arg); + var_arg->pbstrVal = (BSTR FAR*) emalloc(sizeof(BSTR FAR*)); + unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len, codepage); + *(var_arg->pbstrVal) = SysAllocString(unicode_str); + efree(unicode_str); + break; + + case VT_UNKNOWN|VT_BYREF: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != VT_DISPATCH) + var_arg->vt = VT_EMPTY; + else + { + HRESULT hr; + + hr = var_arg->pdispVal->lpVtbl->QueryInterface(var_arg->pdispVal, &IID_IUnknown, &(var_arg->punkVal)); + + if(FAILED(hr)) + { + php_error(E_WARNING,"can't query IUnknown"); + var_arg->vt = VT_EMPTY; + } + else + var_arg->vt = VT_UNKNOWN|VT_BYREF; + } + break; + + case VT_DISPATCH|VT_BYREF: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != VT_DISPATCH) + var_arg->vt = VT_EMPTY; + else + var_arg->vt |= VT_BYREF; + break; + + case VT_VARIANT|VT_BYREF: + php_pval_to_variant(pval_arg, var_arg, codepage); + if(var_arg->vt != (VT_VARIANT | VT_BYREF)) + var_arg->vt = VT_EMPTY; + break; + + case VT_I1: + convert_to_long_ex(&pval_arg); + var_arg->cVal = (char)pval_arg->value.lval; + break; + + case VT_UI2: + convert_to_long_ex(&pval_arg); + var_arg->uiVal = (unsigned short)pval_arg->value.lval; + break; + + case VT_UI4: + convert_to_long_ex(&pval_arg); + var_arg->ulVal = (unsigned long)pval_arg->value.lval; + break; + + case VT_INT: + convert_to_long_ex(&pval_arg); + var_arg->intVal = (int)pval_arg->value.lval; + break; + + case VT_UINT: + convert_to_long_ex(&pval_arg); + var_arg->uintVal = (unsigned int)pval_arg->value.lval; + break; + + case VT_I1|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pcVal = (char FAR*) &pval_arg->value.lval; + break; + + case VT_UI2|VT_BYREF: + convert_to_long(pval_arg); + var_arg->puiVal = (unsigned short FAR*) &pval_arg->value.lval; + break; + + case VT_UI4|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pulVal = (unsigned long FAR*) &pval_arg->value.lval; + break; + + case VT_INT|VT_BYREF: + convert_to_long(pval_arg); + var_arg->pintVal = (int FAR*) &pval_arg->value.lval; + break; + + case VT_UINT|VT_BYREF: + convert_to_long(pval_arg); + var_arg->puintVal = (unsigned int FAR*) &pval_arg->value.lval; + break; + + default: + php_error(E_WARNING, "Type not supportet or not yet implemented."); + } } PHPAPI void php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, int codepage) { - switch(var_arg->vt & ~VT_BYREF) - { - case VT_EMPTY: - var_uninit(pval_arg); - break; - - case VT_UI1: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->pbVal); - else - pval_arg->value.lval = (long) var_arg->bVal; - - pval_arg->type = IS_LONG; - break; - - case VT_I2: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long )*(var_arg->piVal); - else - pval_arg->value.lval = (long) var_arg->iVal; - - pval_arg->type = IS_LONG; - break; - - case VT_I4: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = *(var_arg->plVal); - else - pval_arg->value.lval = var_arg->lVal; - - pval_arg->type = IS_LONG; - break; - - case VT_R4: - if(var_arg->vt & VT_BYREF) - pval_arg->value.dval = (double)*(var_arg->pfltVal); - else - pval_arg->value.dval = (double) var_arg->fltVal; - - pval_arg->type = IS_DOUBLE; - break; - - case VT_R8: - if(var_arg->vt & VT_BYREF) - pval_arg->value.dval = *(var_arg->pdblVal); - else - pval_arg->value.dval = var_arg->dblVal; - - pval_arg->type = IS_DOUBLE; - break; - - case VT_DECIMAL: - { - OLECHAR *unicode_str; - switch(VarBstrFromDec(&var_arg->decVal, LOCALE_SYSTEM_DEFAULT, 0, &unicode_str)) - { - case S_OK: - pval_arg->value.str.val = php_OLECHAR_to_char(unicode_str, &pval_arg->value.str.len, persistent, codepage); - pval_arg->type = IS_STRING; - break; - - default: - php_error(E_WARNING, "Error converting DECIMAL value to PHP floating point"); - break; - } - } - break; - - case VT_CY: - if(var_arg->vt & VT_BYREF) - VarR8FromCy(var_arg->cyVal, &(pval_arg->value.dval)); - else - VarR8FromCy(*(var_arg->pcyVal), &(pval_arg->value.dval)); - - pval_arg->type = IS_DOUBLE; - break; - - case VT_BOOL: - if (var_arg->vt & VT_BYREF) - if (*(var_arg->pboolVal) & 0xFFFF) - pval_arg->value.lval = 1; - else - pval_arg->value.lval = 0; - else - if (var_arg->boolVal & 0xFFFF) - pval_arg->value.lval = 1; - else - pval_arg->value.lval = 0; - - pval_arg->type = IS_BOOL; - break; - - case VT_NULL: - case VT_VOID: - pval_arg->type = IS_NULL; - break; - - case VT_VARIANT: - php_variant_to_pval(var_arg->pvarVal, pval_arg, persistent, codepage); - break; - - case VT_BSTR: - if (pval_arg->is_ref == 0 || (var_arg->vt & VT_BYREF) != VT_BYREF) { - pval_arg->value.str.val = php_OLECHAR_to_char(var_arg->bstrVal, &pval_arg->value.str.len, persistent, codepage); - SysFreeString(var_arg->bstrVal); - } else { - pval_arg->value.str.val = php_OLECHAR_to_char(*(var_arg->pbstrVal), &pval_arg->value.str.len, persistent, codepage); - SysFreeString(*(var_arg->pbstrVal)); - efree(var_arg->pbstrVal); - } - - pval_arg->type = IS_STRING; - break; - - case VT_DATE: { - SYSTEMTIME wintime; - struct tm phptime; - - VariantTimeToSystemTime(var_arg->date, &wintime); - - phptime.tm_year = wintime.wYear - 1900; - phptime.tm_mon = wintime.wMonth - 1; - phptime.tm_mday = wintime.wDay; - phptime.tm_hour = wintime.wHour; - phptime.tm_min = wintime.wMinute; - phptime.tm_sec = wintime.wSecond; - phptime.tm_isdst = -1; - - tzset(); - pval_arg->value.lval = mktime(&phptime); - pval_arg->type = IS_LONG; - } - break; - case VT_DISPATCH: { - pval *handle; - i_dispatch *obj; - - pval_arg->type=IS_OBJECT; - pval_arg->value.obj.ce = &com_class_entry; - pval_arg->value.obj.properties = (HashTable *) emalloc(sizeof(HashTable)); - pval_arg->is_ref=1; - pval_arg->refcount=1; - zend_hash_init(pval_arg->value.obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0); - - ALLOC_ZVAL(handle); - obj = emalloc(sizeof(i_dispatch)); - php_COM_set(obj, var_arg->pdispVal, TRUE); - - handle->type = IS_LONG; - handle->value.lval = zend_list_insert(obj, php_COM_get_le_idispatch()); - pval_copy_constructor(handle); - INIT_PZVAL(handle); - zend_hash_index_update(pval_arg->value.obj.properties, 0, &handle, sizeof(pval *), NULL); - } - break; - case VT_UNKNOWN: -//wtf ?? - var_arg->pdispVal->lpVtbl->Release(var_arg->pdispVal); - /* break missing intentionally */ - - case VT_I1: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->pcVal); - else - pval_arg->value.lval = (long) var_arg->cVal; - - pval_arg->type = IS_LONG; - break; - - case VT_UI2: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->puiVal); - else - pval_arg->value.lval = (long) var_arg->uiVal; - - pval_arg->type = IS_LONG; - break; - - case VT_UI4: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->pulVal); - else - pval_arg->value.lval = (long) var_arg->ulVal; - - pval_arg->type = IS_LONG; - break; - - case VT_INT: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->pintVal); - else - pval_arg->value.lval = (long) var_arg->intVal; - - pval_arg->type = IS_LONG; - break; - - case VT_UINT: - if(var_arg->vt & VT_BYREF) - pval_arg->value.lval = (long)*(var_arg->puintVal); - else - pval_arg->value.lval = (long) var_arg->uintVal; - - pval_arg->type = IS_LONG; - break; - - default: - php_error(E_WARNING,"Unsupported variant type: %d (0x%X)", var_arg->vt, var_arg->vt); - var_reset(pval_arg); - break; - } + switch(var_arg->vt & ~VT_BYREF) + { + case VT_EMPTY: + var_uninit(pval_arg); + break; + + case VT_UI1: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->pbVal); + else + pval_arg->value.lval = (long) var_arg->bVal; + + pval_arg->type = IS_LONG; + break; + + case VT_I2: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long )*(var_arg->piVal); + else + pval_arg->value.lval = (long) var_arg->iVal; + + pval_arg->type = IS_LONG; + break; + + case VT_I4: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = *(var_arg->plVal); + else + pval_arg->value.lval = var_arg->lVal; + + pval_arg->type = IS_LONG; + break; + + case VT_R4: + if(var_arg->vt & VT_BYREF) + pval_arg->value.dval = (double)*(var_arg->pfltVal); + else + pval_arg->value.dval = (double) var_arg->fltVal; + + pval_arg->type = IS_DOUBLE; + break; + + case VT_R8: + if(var_arg->vt & VT_BYREF) + pval_arg->value.dval = *(var_arg->pdblVal); + else + pval_arg->value.dval = var_arg->dblVal; + + pval_arg->type = IS_DOUBLE; + break; + + case VT_DECIMAL: + { + OLECHAR *unicode_str; + switch(VarBstrFromDec(&var_arg->decVal, LOCALE_SYSTEM_DEFAULT, 0, &unicode_str)) + { + case S_OK: + pval_arg->value.str.val = php_OLECHAR_to_char(unicode_str, &pval_arg->value.str.len, persistent, codepage); + pval_arg->type = IS_STRING; + break; + + default: + php_error(E_WARNING, "Error converting DECIMAL value to PHP floating point"); + break; + } + } + break; + + case VT_CY: + if(var_arg->vt & VT_BYREF) + VarR8FromCy(var_arg->cyVal, &(pval_arg->value.dval)); + else + VarR8FromCy(*(var_arg->pcyVal), &(pval_arg->value.dval)); + + pval_arg->type = IS_DOUBLE; + break; + + case VT_BOOL: + if(var_arg->vt & VT_BYREF) + if(*(var_arg->pboolVal) & 0xFFFF) + pval_arg->value.lval = 1; + else + pval_arg->value.lval = 0; + else + if(var_arg->boolVal & 0xFFFF) + pval_arg->value.lval = 1; + else + pval_arg->value.lval = 0; + + pval_arg->type = IS_BOOL; + break; + + case VT_NULL: + case VT_VOID: + pval_arg->type = IS_NULL; + break; + + case VT_VARIANT: + php_variant_to_pval(var_arg->pvarVal, pval_arg, persistent, codepage); + break; + + case VT_BSTR: + if(pval_arg->is_ref == 0 || (var_arg->vt & VT_BYREF) != VT_BYREF) + { + pval_arg->value.str.val = php_OLECHAR_to_char(var_arg->bstrVal, &pval_arg->value.str.len, persistent, codepage); + SysFreeString(var_arg->bstrVal); + } + else + { + pval_arg->value.str.val = php_OLECHAR_to_char(*(var_arg->pbstrVal), &pval_arg->value.str.len, persistent, codepage); + SysFreeString(*(var_arg->pbstrVal)); + efree(var_arg->pbstrVal); + } + + pval_arg->type = IS_STRING; + break; + + case VT_DATE: { + SYSTEMTIME wintime; + struct tm phptime; + + VariantTimeToSystemTime(var_arg->date, &wintime); + + phptime.tm_year = wintime.wYear - 1900; + phptime.tm_mon = wintime.wMonth - 1; + phptime.tm_mday = wintime.wDay; + phptime.tm_hour = wintime.wHour; + phptime.tm_min = wintime.wMinute; + phptime.tm_sec = wintime.wSecond; + phptime.tm_isdst = -1; + + tzset(); + pval_arg->value.lval = mktime(&phptime); + pval_arg->type = IS_LONG; + } + break; + case VT_UNKNOWN: + + //IDispatch holen und dann weiterfiechen + //wtf ?? + var_arg->pdispVal->lpVtbl->Release(var_arg->pdispVal); + /* break missing intentionally */ + + case VT_DISPATCH: { + pval *handle; + i_dispatch *obj; + + if(var_arg->pdispVal == NULL) + { + pval_arg->type = IS_NULL; + } + else + { + pval_arg->type = IS_OBJECT; + pval_arg->value.obj.ce = &com_class_entry; + pval_arg->value.obj.properties = (HashTable *) emalloc(sizeof(HashTable)); + pval_arg->is_ref = 1; + pval_arg->refcount = 1; + zend_hash_init(pval_arg->value.obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + + ALLOC_ZVAL(handle); + obj = emalloc(sizeof(i_dispatch)); + php_COM_set(obj, var_arg->pdispVal, TRUE); + + handle->type = IS_LONG; + handle->value.lval = zend_list_insert(obj, php_COM_get_le_idispatch()); + pval_copy_constructor(handle); + INIT_PZVAL(handle); + zend_hash_index_update(pval_arg->value.obj.properties, 0, &handle, sizeof(pval *), NULL); + } + } + break; + case VT_I1: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->pcVal); + else + pval_arg->value.lval = (long) var_arg->cVal; + + pval_arg->type = IS_LONG; + break; + + case VT_UI2: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->puiVal); + else + pval_arg->value.lval = (long) var_arg->uiVal; + + pval_arg->type = IS_LONG; + break; + + case VT_UI4: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->pulVal); + else + pval_arg->value.lval = (long) var_arg->ulVal; + + pval_arg->type = IS_LONG; + break; + + case VT_INT: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->pintVal); + else + pval_arg->value.lval = (long) var_arg->intVal; + + pval_arg->type = IS_LONG; + break; + + case VT_UINT: + if(var_arg->vt & VT_BYREF) + pval_arg->value.lval = (long)*(var_arg->puintVal); + else + pval_arg->value.lval = (long) var_arg->uintVal; + + pval_arg->type = IS_LONG; + break; + + default: + php_error(E_WARNING,"Unsupported variant type: %d (0x%X)", var_arg->vt, var_arg->vt); + var_reset(pval_arg); + break; + } } PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage) { - OLECHAR *unicode_str; - - //request needed buffersize - uint reqSize = MultiByteToWideChar(codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, C_str, -1, NULL, 0); - - if(reqSize) - { - unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR) * reqSize); - - //convert string - MultiByteToWideChar(codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, C_str, -1, unicode_str, reqSize); - } - else - { - unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR)); - *unicode_str = 0; - - switch(GetLastError()) - { - case ERROR_NO_UNICODE_TRANSLATION: - php_error(E_WARNING,"No unicode translation available for the specified string"); - break; - default: - php_error(E_WARNING,"Error in php_char_to_OLECHAR()"); - } - } - - return unicode_str; + OLECHAR *unicode_str; + + //request needed buffersize + uint reqSize = MultiByteToWideChar(codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, C_str, -1, NULL, 0); + + if(reqSize) + { + unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR) * reqSize); + + //convert string + MultiByteToWideChar(codepage, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, C_str, -1, unicode_str, reqSize); + } + else + { + unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR)); + *unicode_str = 0; + + switch(GetLastError()) + { + case ERROR_NO_UNICODE_TRANSLATION: + php_error(E_WARNING,"No unicode translation available for the specified string"); + break; + default: + 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) { - char *C_str; - uint length = 0; + char *C_str; + uint length = 0; - //request needed buffersize - uint reqSize = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, unicode_str, -1, NULL, 0, NULL, NULL); + //request needed buffersize + uint reqSize = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, unicode_str, -1, NULL, 0, NULL, NULL); - if(reqSize) - { - C_str = (char *) pemalloc(sizeof(char) * reqSize, persistent); + if(reqSize) + { + C_str = (char *) pemalloc(sizeof(char) * reqSize, persistent); - //convert string - length = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, unicode_str, -1, C_str, reqSize, NULL, NULL) - 1; - } - else - { - C_str = (char *) pemalloc(sizeof(char), persistent); - *C_str = 0; + //convert string + length = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, unicode_str, -1, C_str, reqSize, NULL, NULL) - 1; + } + else + { + 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) - *out_length = length; + if(out_length) + *out_length = length; - return C_str; + return C_str; } #endif /* PHP_WIN32 */ \ No newline at end of file diff --git a/ext/rpc/com/variant.c b/ext/rpc/com/variant.c index 4c4657b2a0..b2e9d4bee4 100644 --- a/ext/rpc/com/variant.c +++ b/ext/rpc/com/variant.c @@ -50,7 +50,6 @@ function_entry VARIANT_functions[] = { {NULL, NULL, NULL} }; - static PHP_MINFO_FUNCTION(VARIANT) { php_info_print_table_start(); @@ -58,12 +57,10 @@ static PHP_MINFO_FUNCTION(VARIANT) php_info_print_table_end(); } - zend_module_entry VARIANT_module_entry = { "variant", VARIANT_functions, PHP_MINIT(VARIANT), PHP_MSHUTDOWN(VARIANT), NULL, NULL, PHP_MINFO(VARIANT), STANDARD_MODULE_PROPERTIES }; - PHP_MINIT_FUNCTION(VARIANT) { le_variant = zend_register_list_destructors_ex(php_variant_destructor, NULL, "VARIANT", module_number); @@ -92,7 +89,7 @@ PHP_MINIT_FUNCTION(VARIANT) REGISTER_LONG_CONSTANT("VT_UINT", VT_UINT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("VT_ARRAY", VT_ARRAY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("VT_BYREF", VT_BYREF, CONST_CS | CONST_PERSISTENT); - + /* codepages */ REGISTER_LONG_CONSTANT("CP_ACP", CP_ACP, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CP_MACCP", CP_MACCP, CONST_CS | CONST_PERSISTENT); @@ -106,7 +103,6 @@ PHP_MINIT_FUNCTION(VARIANT) return SUCCESS; } - PHP_MSHUTDOWN_FUNCTION(VARIANT) { return SUCCESS; @@ -118,15 +114,15 @@ void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper zend_overloaded_element *function_name = (zend_overloaded_element *) property_reference->elements_list->tail->data; VARIANT *pVar; - if ((zend_llist_count(property_reference->elements_list)==1) && !strcmp(function_name->element.value.str.val, "variant")) + if((zend_llist_count(property_reference->elements_list)==1) && !strcmp(function_name->element.value.str.val, "variant")) { /* constructor */ pval *object_handle, *data, *type, *code_page; - + pVar = emalloc(sizeof(VARIANT)); VariantInit(pVar); - switch (ZEND_NUM_ARGS()) + switch(ZEND_NUM_ARGS()) { case 0: /* nothing to do */ @@ -155,7 +151,8 @@ void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper return_value->type = IS_LONG; return_value->value.lval = zend_list_insert(pVar, le_variant); - if (!zend_is_true(return_value)) { + if(!zend_is_true(return_value)) + { var_reset(object); return; } @@ -174,7 +171,7 @@ pval php_VARIANT_get_property_handler(zend_property_reference *property_referenc { zend_overloaded_element *overloaded_property; int type; - + pval result, **var_handle, *object = property_reference->object; VARIANT *var_arg; @@ -182,22 +179,31 @@ pval php_VARIANT_get_property_handler(zend_property_reference *property_referenc zend_hash_index_find(object->value.obj.properties, 0, (void **) &var_handle); var_arg = zend_list_find((*var_handle)->value.lval, &type); - if (!var_arg || (type != le_variant)) { + if(!var_arg || (type != le_variant)) + { var_reset(&result); - } else { + } + else + { overloaded_property = (zend_overloaded_element *) property_reference->elements_list->head->data; - switch (overloaded_property->type) { + switch(overloaded_property->type) + { case OE_IS_ARRAY: var_reset(&result); break; case OE_IS_OBJECT: - if(!strcmp(overloaded_property->element.value.str.val, "value")) { + if(!strcmp(overloaded_property->element.value.str.val, "value")) + { php_variant_to_pval(var_arg, &result, 0, codepage); - } else if(!strcmp(overloaded_property->element.value.str.val, "type")) { + } + else if(!strcmp(overloaded_property->element.value.str.val, "type")) + { result.value.lval = var_arg->vt; result.type = IS_LONG; - } else { + } + else + { var_reset(&result); php_error(E_WARNING, "Unknown member."); } @@ -206,11 +212,11 @@ pval php_VARIANT_get_property_handler(zend_property_reference *property_referenc var_reset(&result); php_error(E_WARNING, "Unknown method."); break; - - pval_destructor(&overloaded_property->element); + + pval_destructor(&overloaded_property->element); } } - + return result; } @@ -218,7 +224,7 @@ int php_VARIANT_set_property_handler(zend_property_reference *property_reference { zend_overloaded_element *overloaded_property; int type; - + pval **var_handle, *object = property_reference->object; VARIANT *var_arg; @@ -226,9 +232,9 @@ int php_VARIANT_set_property_handler(zend_property_reference *property_reference zend_hash_index_find(object->value.obj.properties, 0, (void **) &var_handle); var_arg = zend_list_find((*var_handle)->value.lval, &type); - if (!var_arg || (type != le_variant)) + if(!var_arg || (type != le_variant)) return FAILURE; - + overloaded_property = (zend_overloaded_element *) property_reference->elements_list->head->data; do_VARIANT_propset(var_arg, &overloaded_property->element, value); pval_destructor(&overloaded_property->element); @@ -240,7 +246,7 @@ static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value) pval type; type.type = IS_STRING; - + if(!strcmp(arg_property->value.str.val, "bVal")) { type.value.lval = VT_UI1; -- 2.50.1