com_misc.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 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. #ifdef HAVE_CONFIG_H
  19. #include "config.h"
  20. #endif
  21. #include "php.h"
  22. #include "php_ini.h"
  23. #include "ext/standard/info.h"
  24. #include "php_com_dotnet.h"
  25. #include "php_com_dotnet_internal.h"
  26. #include "Zend/zend_exceptions.h"
  27. void php_com_throw_exception(HRESULT code, char *message)
  28. {
  29. int free_msg = 0;
  30. if (message == NULL) {
  31. message = php_win32_error_to_msg(code);
  32. free_msg = 1;
  33. }
  34. #if SIZEOF_ZEND_LONG == 8
  35. zend_throw_exception(php_com_exception_class_entry, message, (zend_long)(uint32_t)code);
  36. #else
  37. zend_throw_exception(php_com_exception_class_entry, message, (zend_long)code);
  38. #endif
  39. if (free_msg) {
  40. LocalFree(message);
  41. }
  42. }
  43. PHP_COM_DOTNET_API void php_com_wrap_dispatch(zval *z, IDispatch *disp,
  44. int codepage)
  45. {
  46. php_com_dotnet_object *obj;
  47. obj = emalloc(sizeof(*obj));
  48. memset(obj, 0, sizeof(*obj));
  49. obj->code_page = codepage;
  50. obj->ce = php_com_variant_class_entry;
  51. obj->zo.ce = php_com_variant_class_entry;
  52. VariantInit(&obj->v);
  53. V_VT(&obj->v) = VT_DISPATCH;
  54. V_DISPATCH(&obj->v) = disp;
  55. IDispatch_AddRef(V_DISPATCH(&obj->v));
  56. IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
  57. zend_object_std_init(&obj->zo, php_com_variant_class_entry);
  58. obj->zo.handlers = &php_com_object_handlers;
  59. ZVAL_OBJ(z, &obj->zo);
  60. }
  61. PHP_COM_DOTNET_API void php_com_wrap_variant(zval *z, VARIANT *v,
  62. int codepage)
  63. {
  64. php_com_dotnet_object *obj;
  65. obj = emalloc(sizeof(*obj));
  66. memset(obj, 0, sizeof(*obj));
  67. obj->code_page = codepage;
  68. obj->ce = php_com_variant_class_entry;
  69. obj->zo.ce = php_com_variant_class_entry;
  70. VariantInit(&obj->v);
  71. VariantCopyInd(&obj->v, v);
  72. obj->modified = 0;
  73. if ((V_VT(&obj->v) == VT_DISPATCH) && (V_DISPATCH(&obj->v) != NULL)) {
  74. IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
  75. }
  76. zend_object_std_init(&obj->zo, php_com_variant_class_entry);
  77. obj->zo.handlers = &php_com_object_handlers;
  78. ZVAL_OBJ(z, &obj->zo);
  79. }
  80. /* this is a convenience function for fetching a particular
  81. * element from a (possibly multi-dimensional) safe array */
  82. PHP_COM_DOTNET_API int php_com_safearray_get_elem(VARIANT *array, VARIANT *dest, LONG dim1)
  83. {
  84. UINT dims;
  85. LONG lbound, ubound;
  86. LONG indices[1];
  87. VARTYPE vt;
  88. if (!V_ISARRAY(array)) {
  89. return 0;
  90. }
  91. dims = SafeArrayGetDim(V_ARRAY(array));
  92. if (dims != 1) {
  93. php_error_docref(NULL, E_WARNING,
  94. "Can only handle single dimension variant arrays (this array has %d)", dims);
  95. return 0;
  96. }
  97. if (FAILED(SafeArrayGetVartype(V_ARRAY(array), &vt)) || vt == VT_EMPTY) {
  98. vt = V_VT(array) & ~VT_ARRAY;
  99. }
  100. /* determine the bounds */
  101. SafeArrayGetLBound(V_ARRAY(array), 1, &lbound);
  102. SafeArrayGetUBound(V_ARRAY(array), 1, &ubound);
  103. /* check bounds */
  104. if (dim1 < lbound || dim1 > ubound) {
  105. php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds");
  106. return 0;
  107. }
  108. /* now fetch that element */
  109. VariantInit(dest);
  110. indices[0] = dim1;
  111. if (vt == VT_VARIANT) {
  112. SafeArrayGetElement(V_ARRAY(array), indices, dest);
  113. } else {
  114. V_VT(dest) = vt;
  115. /* store the value into "lVal" member of the variant.
  116. * This works because it is a union; since we know the variant
  117. * type, we end up with a working variant */
  118. SafeArrayGetElement(V_ARRAY(array), indices, &dest->lVal);
  119. }
  120. return 1;
  121. }