com_misc.c 4.2 KB

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