com_misc.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Wez Furlong <wez@thebrainroom.com> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "php.h"
  23. #include "php_ini.h"
  24. #include "ext/standard/info.h"
  25. #include "php_com_dotnet.h"
  26. #include "php_com_dotnet_internal.h"
  27. #include "Zend/zend_exceptions.h"
  28. void php_com_throw_exception(HRESULT code, char *message TSRMLS_DC)
  29. {
  30. int free_msg = 0;
  31. if (message == NULL) {
  32. message = php_win32_error_to_msg(code);
  33. free_msg = 1;
  34. }
  35. zend_throw_exception(php_com_exception_class_entry, message, (long)code TSRMLS_CC);
  36. if (free_msg) {
  37. LocalFree(message);
  38. }
  39. }
  40. PHP_COM_DOTNET_API void php_com_wrap_dispatch(zval *z, IDispatch *disp,
  41. int codepage TSRMLS_DC)
  42. {
  43. php_com_dotnet_object *obj;
  44. obj = emalloc(sizeof(*obj));
  45. memset(obj, 0, sizeof(*obj));
  46. obj->code_page = codepage;
  47. obj->ce = php_com_variant_class_entry;
  48. obj->zo.ce = php_com_variant_class_entry;
  49. VariantInit(&obj->v);
  50. V_VT(&obj->v) = VT_DISPATCH;
  51. V_DISPATCH(&obj->v) = disp;
  52. IDispatch_AddRef(V_DISPATCH(&obj->v));
  53. IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
  54. Z_TYPE_P(z) = IS_OBJECT;
  55. z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
  56. z->value.obj.handlers = &php_com_object_handlers;
  57. }
  58. PHP_COM_DOTNET_API void php_com_wrap_variant(zval *z, VARIANT *v,
  59. int codepage TSRMLS_DC)
  60. {
  61. php_com_dotnet_object *obj;
  62. obj = emalloc(sizeof(*obj));
  63. memset(obj, 0, sizeof(*obj));
  64. obj->code_page = codepage;
  65. obj->ce = php_com_variant_class_entry;
  66. obj->zo.ce = php_com_variant_class_entry;
  67. VariantInit(&obj->v);
  68. VariantCopyInd(&obj->v, v);
  69. obj->modified = 0;
  70. if ((V_VT(&obj->v) == VT_DISPATCH) && (V_DISPATCH(&obj->v) != NULL)) {
  71. IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
  72. }
  73. Z_TYPE_P(z) = IS_OBJECT;
  74. z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
  75. z->value.obj.handlers = &php_com_object_handlers;
  76. }
  77. /* this is a convenience function for fetching a particular
  78. * element from a (possibly multi-dimensional) safe array */
  79. PHP_COM_DOTNET_API int php_com_safearray_get_elem(VARIANT *array, VARIANT *dest, LONG dim1 TSRMLS_DC)
  80. {
  81. UINT dims;
  82. LONG lbound, ubound;
  83. LONG indices[1];
  84. VARTYPE vt;
  85. if (!V_ISARRAY(array)) {
  86. return 0;
  87. }
  88. dims = SafeArrayGetDim(V_ARRAY(array));
  89. if (dims != 1) {
  90. php_error_docref(NULL TSRMLS_CC, E_WARNING,
  91. "Can only handle single dimension variant arrays (this array has %d)", dims);
  92. return 0;
  93. }
  94. if (FAILED(SafeArrayGetVartype(V_ARRAY(array), &vt)) || vt == VT_EMPTY) {
  95. vt = V_VT(array) & ~VT_ARRAY;
  96. }
  97. /* determine the bounds */
  98. SafeArrayGetLBound(V_ARRAY(array), 1, &lbound);
  99. SafeArrayGetUBound(V_ARRAY(array), 1, &ubound);
  100. /* check bounds */
  101. if (dim1 < lbound || dim1 > ubound) {
  102. php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds" TSRMLS_CC);
  103. return 0;
  104. }
  105. /* now fetch that element */
  106. VariantInit(dest);
  107. indices[0] = dim1;
  108. if (vt == VT_VARIANT) {
  109. SafeArrayGetElement(V_ARRAY(array), indices, dest);
  110. } else {
  111. V_VT(dest) = vt;
  112. /* store the value into "lVal" member of the variant.
  113. * This works because it is a union; since we know the variant
  114. * type, we end up with a working variant */
  115. SafeArrayGetElement(V_ARRAY(array), indices, &dest->lVal);
  116. }
  117. return 1;
  118. }