コード例 #1
0
ファイル: com_olechar.c プロジェクト: Jeffy23/php-src
PHPAPI OLECHAR *php_com_string_to_olestring(char *string, uint string_len, int codepage TSRMLS_DC)
{
    OLECHAR *olestring = NULL;
    DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
    BOOL ok;

    if (string_len == -1) {
        /* determine required length for the buffer (includes NUL terminator) */
        string_len = MultiByteToWideChar(codepage, flags, string, -1, NULL, 0);
    } else {
        /* allow room for NUL terminator */
        string_len++;
    }

    if (string_len > 0) {
        olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0);
        ok = MultiByteToWideChar(codepage, flags, string, string_len, olestring, string_len);
    } else {
        ok = FALSE;
        olestring = (OLECHAR*)emalloc(sizeof(OLECHAR));
        *olestring = 0;
    }

    if (!ok) {
        char *msg = php_win32_error_to_msg(GetLastError());

        php_error_docref(NULL TSRMLS_CC, E_WARNING,
                         "Could not convert string to unicode: `%s'", msg);

        LocalFree(msg);
    }

    return olestring;
}
コード例 #2
0
ファイル: com_olechar.c プロジェクト: Jeffy23/php-src
PHPAPI char *php_com_olestring_to_string(OLECHAR *olestring, uint *string_len, int codepage TSRMLS_DC)
{
    char *string;
    uint length = 0;
    BOOL ok;

    length = WideCharToMultiByte(codepage, 0, olestring, -1, NULL, 0, NULL, NULL);

    if (length) {
        string = (char*)safe_emalloc(length, sizeof(char), 0);
        length = WideCharToMultiByte(codepage, 0, olestring, -1, string, length, NULL, NULL);
        ok = length > 0;
    } else {
        string = (char*)emalloc(sizeof(char));
        *string = '\0';
        ok = FALSE;
        length = 0;
    }

    if (!ok) {
        char *msg = php_win32_error_to_msg(GetLastError());

        php_error_docref(NULL TSRMLS_CC, E_WARNING,
                         "Could not convert string from unicode: `%s'", msg);

        LocalFree(msg);
    }

    if (string_len) {
        *string_len = length-1;
    }

    return string;
}
コード例 #3
0
ファイル: com_misc.c プロジェクト: Tyrael/php-src
void php_com_throw_exception(HRESULT code, char *message)
{
    int free_msg = 0;
    if (message == NULL) {
        message = php_win32_error_to_msg(code);
        free_msg = 1;
    }
#if SIZEOF_ZEND_LONG == 8
    zend_throw_exception(php_com_exception_class_entry, message, (zend_long)(uint32_t)code);
#else
    zend_throw_exception(php_com_exception_class_entry, message, (zend_long)code);
#endif
    if (free_msg) {
        LocalFree(message);
    }
}
コード例 #4
0
ファイル: com_com.c プロジェクト: AmesianX/php-src
int php_com_do_invoke(php_com_dotnet_object *obj, char *name, size_t namelen,
		WORD flags,	VARIANT *v, int nargs, zval *args, int allow_noarg)
{
	DISPID dispid;
	HRESULT hr;
	char *winerr = NULL;
	char *msg = NULL;

	hr = php_com_get_id_of_name(obj, name, namelen, &dispid);

	if (FAILED(hr)) {
		winerr = php_win32_error_to_msg(hr);
		spprintf(&msg, 0, "Unable to lookup `%s': %s", name, winerr);
		LocalFree(winerr);
		php_com_throw_exception(hr, msg);
		efree(msg);
		return FAILURE;
	}

	return php_com_do_invoke_by_id(obj, dispid, flags, v, nargs, args, 0, allow_noarg);
}
コード例 #5
0
ファイル: com_olechar.c プロジェクト: AmesianX/php-src
PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(char *string, size_t string_len, int codepage)
{
	OLECHAR *olestring = NULL;
	DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
	BOOL ok;

	if (string_len == -1) {
		/* determine required length for the buffer (includes NUL terminator) */
		string_len = MultiByteToWideChar(codepage, flags, string, -1, NULL, 0);
	} else {
		/* allow room for NUL terminator */
		string_len++;
	}

	if (string_len > 0) {
		olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0);
		/* XXX if that's a real multibyte string, olestring is obviously allocated excessively.
		This should be fixed by reallocating the olestring, but as emalloc is used, that doesn't
		matter much. */
		ok = MultiByteToWideChar(codepage, flags, string, (int)string_len, olestring, (int)string_len);
		if (ok > 0 && ok < string_len) {
			olestring[ok] = '\0';
		}
	} else {
		ok = FALSE;
		olestring = (OLECHAR*)emalloc(sizeof(OLECHAR));
		*olestring = 0;
	}

	if (!ok) {
		char *msg = php_win32_error_to_msg(GetLastError());

		php_error_docref(NULL, E_WARNING,
			"Could not convert string to unicode: `%s'", msg);

		LocalFree(msg);
	}

	return olestring;
}
コード例 #6
0
ファイル: com_com.c プロジェクト: do-aki/petipeti
/* Performs an Invoke on the given com object.
 * returns a failure code and creates an exception if there was an error */
HRESULT php_com_invoke_helper(php_com_dotnet_object *obj, DISPID id_member,
		WORD flags, DISPPARAMS *disp_params, VARIANT *v, int silent, int allow_noarg TSRMLS_DC)
{
	HRESULT hr;
	unsigned int arg_err;
	EXCEPINFO e = {0};

	hr = IDispatch_Invoke(V_DISPATCH(&obj->v), id_member,
		&IID_NULL, LOCALE_SYSTEM_DEFAULT, flags, disp_params, v, &e, &arg_err);

	if (silent == 0 && FAILED(hr)) {
		char *source = NULL, *desc = NULL, *msg = NULL;
		int source_len, desc_len;

		switch (hr) {
			case DISP_E_EXCEPTION:
				if (e.bstrSource) {
					source = php_com_olestring_to_string(e.bstrSource, &source_len, obj->code_page TSRMLS_CC);
					SysFreeString(e.bstrSource);
				}
				if (e.bstrDescription) {
					desc = php_com_olestring_to_string(e.bstrDescription, &desc_len, obj->code_page TSRMLS_CC);
					SysFreeString(e.bstrDescription);
				}
				if (PG(html_errors)) {
					spprintf(&msg, 0, "<b>Source:</b> %s<br/><b>Description:</b> %s",
						source ? source : "Unknown",
						desc ? desc : "Unknown");
				} else {
					spprintf(&msg, 0, "Source: %s\nDescription: %s",
						source ? source : "Unknown",
						desc ? desc : "Unknown");
				}
				if (desc) {
					efree(desc);
				}
				if (source) {
					efree(source);
				}
				if (e.bstrHelpFile) {
					SysFreeString(e.bstrHelpFile);
				}
				break;

			case DISP_E_PARAMNOTFOUND:
			case DISP_E_TYPEMISMATCH:
				desc = php_win32_error_to_msg(hr);
				spprintf(&msg, 0, "Parameter %d: %s", arg_err, desc);
				LocalFree(desc);
				break;

			case DISP_E_BADPARAMCOUNT:
				if ((disp_params->cArgs + disp_params->cNamedArgs == 0) && (allow_noarg == 1)) {
					/* if getting a property and they are missing all parameters,
					 * we want to create a proxy object for them; so lets not create an
					 * exception here */
					msg = NULL;
					break;
				}
				/* else fall through */
				
			default:
				desc = php_win32_error_to_msg(hr);
				spprintf(&msg, 0, "Error [0x%08x] %s", hr, desc);
				LocalFree(desc);
				break;
		}

		if (msg) {
			php_com_throw_exception(hr, msg TSRMLS_CC);
			efree(msg);
		}
	}

	return hr;
}
コード例 #7
0
ファイル: com_com.c プロジェクト: AmesianX/php-src
/* the core of COM */
int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *f,
		WORD flags,	VARIANT *v, int nargs, zval *args)
{
	DISPID dispid, altdispid;
	DISPPARAMS disp_params;
	HRESULT hr;
	VARIANT *vargs = NULL, *byref_vals = NULL;
	int i, byref_count = 0, j;

	/* assumption: that the active function (f) is the function we generated for the engine */
	if (!f) {
		return FAILURE;
	}
	
	hr = php_com_get_id_of_name(obj, f->function_name->val, f->function_name->len, &dispid);

	if (FAILED(hr)) {
		char *winerr = NULL;
		char *msg = NULL;
		winerr = php_win32_error_to_msg(hr);
		spprintf(&msg, 0, "Unable to lookup `%s': %s", f->function_name->val, winerr);
		LocalFree(winerr);
		php_com_throw_exception(hr, msg);
		efree(msg);
		return FAILURE;
	}


	if (nargs) {
		vargs = (VARIANT*)safe_emalloc(sizeof(VARIANT), nargs, 0);
	}

	if (f->arg_info) {
		for (i = 0; i < nargs; i++) {
			if (f->arg_info[nargs - i - 1].pass_by_reference) {
				byref_count++;
			}
		}
	}

	if (byref_count) {
		byref_vals = (VARIANT*)safe_emalloc(sizeof(VARIANT), byref_count, 0);
		for (j = 0, i = 0; i < nargs; i++) {
			if (f->arg_info[nargs - i - 1].pass_by_reference) {
				/* put the value into byref_vals instead */
				php_com_variant_from_zval(&byref_vals[j], &args[nargs - i - 1], obj->code_page);

				/* if it is already byref, "move" it into the vargs array, otherwise
				 * make vargs a reference to this value */
				if (V_VT(&byref_vals[j]) & VT_BYREF) {
					memcpy(&vargs[i], &byref_vals[j], sizeof(vargs[i]));
					VariantInit(&byref_vals[j]); /* leave the variant slot empty to simplify cleanup */
				} else {
					VariantInit(&vargs[i]);
					V_VT(&vargs[i]) = V_VT(&byref_vals[j]) | VT_BYREF;
					/* union magic ensures that this works out */
					vargs[i].byref = &V_UINT(&byref_vals[j]);
				}
				j++;
			} else {
				php_com_variant_from_zval(&vargs[i], &args[nargs - i - 1], obj->code_page);
			}
		}
		
	} else {
		/* Invoke'd args are in reverse order */
		for (i = 0; i < nargs; i++) {
			php_com_variant_from_zval(&vargs[i], &args[nargs - i - 1], obj->code_page);
		}
	}

	disp_params.cArgs = nargs;
	disp_params.cNamedArgs = 0;
	disp_params.rgvarg = vargs;
	disp_params.rgdispidNamedArgs = NULL;

	if (flags & DISPATCH_PROPERTYPUT) {
		altdispid = DISPID_PROPERTYPUT;
		disp_params.rgdispidNamedArgs = &altdispid;
		disp_params.cNamedArgs = 1;
	}

	/* this will create an exception if needed */
	hr = php_com_invoke_helper(obj, dispid, flags, &disp_params, v, 0, 0);	

	/* release variants */
	if (vargs) {
		if (f && f->arg_info) {
			for (i = 0, j = 0; i < nargs; i++) {
				/* if this was byref, update the zval */
				if (f->arg_info[nargs - i - 1].pass_by_reference) {
					SEPARATE_ZVAL_IF_NOT_REF(&args[nargs - i - 1]);

					/* if the variant is pointing at the byref_vals, we need to map
					 * the pointee value as a zval; otherwise, the value is pointing
					 * into an existing PHP variant record */
					if (V_VT(&vargs[i]) & VT_BYREF) {
						if (vargs[i].byref == &V_UINT(&byref_vals[j])) {
							/* copy that value */
							php_com_zval_from_variant(&args[nargs - i - 1], &byref_vals[j],
								obj->code_page);
						}
					} else {
						/* not sure if this can ever happen; the variant we marked as BYREF
						 * is no longer BYREF - copy its value */
						php_com_zval_from_variant(&args[nargs - i - 1], &vargs[i],
							obj->code_page);
					}
					VariantClear(&byref_vals[j]);
					j++;
				}
				VariantClear(&vargs[i]);
			}
		} else {
			for (i = 0, j = 0; i < nargs; i++) {
				VariantClear(&vargs[i]);
			}
		}
		efree(vargs);
	}

	return SUCCEEDED(hr) ? SUCCESS : FAILURE;
}