You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
6.3 KiB

25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 4 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2002 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.02 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available at through the world-wide-web at |
  10. | http://www.php.net/license/2_02.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: Sam Ruby <rubys@us.ibm.com> |
  16. | Harald Radi <h.radi@nme.at> |
  17. +----------------------------------------------------------------------+
  18. */
  19. /*
  20. * This module implements support for Microsoft .Net components.
  21. */
  22. /*
  23. * 28.1.2001
  24. * use external unicode conversion functions
  25. *
  26. * harald radi <h.radi@nme.at>
  27. */
  28. #ifdef PHP_WIN32
  29. #include <iostream>
  30. #include <math.h>
  31. #include <comdef.h>
  32. extern "C"
  33. {
  34. #include "php.h"
  35. #include "ext/standard/info.h"
  36. }
  37. #include "ext/com/conversion.h"
  38. #include "ext/com/php_COM.h"
  39. #include "Mscoree.h"
  40. #include "mscorlib.h"
  41. using namespace mscorlib;
  42. static ICorRuntimeHost *pHost;
  43. static mscorlib::_AppDomain *pDomain;
  44. static zend_class_entry dotnet_class_entry;
  45. static int codepage;
  46. HRESULT dotnet_init() {
  47. HRESULT hr;
  48. hr = CoCreateInstance(CLSID_CorRuntimeHost, NULL, CLSCTX_ALL,
  49. IID_ICorRuntimeHost, (void **)&pHost);
  50. if (FAILED(hr)) return hr;
  51. hr = pHost->Start();
  52. if (FAILED(hr)) return hr;
  53. IUnknown *uDomain;
  54. hr = pHost->GetDefaultDomain(&uDomain);
  55. if (FAILED(hr)) return hr;
  56. hr = uDomain->QueryInterface(__uuidof(_AppDomain), (void**) &pDomain);
  57. if (FAILED(hr)) return -1;
  58. uDomain->Release();
  59. return ERROR_SUCCESS;
  60. }
  61. HRESULT dotnet_create(OLECHAR *assembly, OLECHAR *datatype, comval *obj TSRMLS_DC) {
  62. HRESULT hr;
  63. _ObjectHandle *pHandle;
  64. hr = pDomain->CreateInstance(_bstr_t(assembly), _bstr_t(datatype), &pHandle);
  65. if (FAILED(hr)) return hr;
  66. if (!pHandle) return hr;
  67. _variant_t unwrapped;
  68. hr = pHandle->Unwrap(&unwrapped);
  69. pHandle->Release();
  70. if (FAILED(hr)) return hr;
  71. php_COM_set(obj, &unwrapped.pdispVal, TRUE TSRMLS_CC);
  72. return ERROR_SUCCESS;
  73. }
  74. void dotnet_term() {
  75. if (pHost) pHost->Stop();
  76. if (pHost) pHost->Release();
  77. if (pDomain) pDomain->Release();
  78. pHost = 0;
  79. pDomain = 0;
  80. }
  81. /* {{{ proto int dotnet_load(string assembly_name [, string datatype_name, int codepage])
  82. Loads a DOTNET module */
  83. PHP_FUNCTION(dotnet_load)
  84. {
  85. HRESULT hr;
  86. pval *assembly_name, *datatype_name, *code_page;
  87. OLECHAR *assembly, *datatype;
  88. comval *obj;
  89. switch(ZEND_NUM_ARGS())
  90. {
  91. case 2:
  92. getParameters(ht, 2, &assembly_name, &datatype_name);
  93. codepage = CP_ACP;
  94. break;
  95. case 3:
  96. getParameters(ht, 3, &assembly_name, &datatype_name, &code_page);
  97. convert_to_long(code_page);
  98. codepage = Z_LVAL_P(code_page);
  99. break;
  100. default:
  101. WRONG_PARAM_COUNT;
  102. break;
  103. }
  104. convert_to_string(assembly_name);
  105. assembly = php_char_to_OLECHAR(Z_STRVAL_P(assembly_name), Z_STRLEN_P(assembly_name), codepage TSRMLS_CC);
  106. convert_to_string(datatype_name);
  107. datatype = php_char_to_OLECHAR(Z_STRVAL_P(datatype_name), Z_STRLEN_P(datatype_name), codepage TSRMLS_CC);
  108. ALLOC_COM(obj);
  109. /* obtain IDispatch */
  110. hr = dotnet_create(assembly, datatype, obj TSRMLS_CC);
  111. efree(assembly);
  112. efree(datatype);
  113. if (FAILED(hr)) {
  114. char *error_message;
  115. error_message = php_COM_error_message(hr TSRMLS_CC);
  116. php_error(E_WARNING, "Error obtaining .Net class for %s in assembly %s: %s", datatype_name->value.str.val, assembly_name->value.str.val, error_message);
  117. LocalFree(error_message);
  118. efree(obj);
  119. RETURN_FALSE;
  120. }
  121. if (C_DISPATCH(obj) == NULL) {
  122. php_error(E_WARNING, "Unable to locate %s in assembly %s", datatype_name->value.str.val, assembly_name->value.str.val);
  123. efree(obj);
  124. RETURN_FALSE;
  125. }
  126. RETURN_LONG(zend_list_insert(obj, IS_COM));
  127. }
  128. /* }}} */
  129. void php_DOTNET_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
  130. {
  131. pval *object = property_reference->object;
  132. zend_overloaded_element *function_name = (zend_overloaded_element *) property_reference->elements_list->tail->data;
  133. if (zend_llist_count(property_reference->elements_list)==1
  134. && !strcmp(Z_STRVAL(function_name->element), "dotnet")) { /* constructor */
  135. pval *object_handle;
  136. PHP_FN(dotnet_load)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  137. if (!Z_LVAL_P(return_value)) {
  138. ZVAL_FALSE(object);
  139. return;
  140. }
  141. ALLOC_ZVAL(object_handle);
  142. *object_handle = *return_value;
  143. pval_copy_constructor(object_handle);
  144. INIT_PZVAL(object_handle);
  145. zend_hash_index_update(Z_OBJPROP_P(object), 0, &object_handle, sizeof(pval *), NULL);
  146. pval_destructor(&function_name->element);
  147. } else {
  148. php_COM_call_function_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_reference);
  149. }
  150. }
  151. void php_register_DOTNET_class(TSRMLS_D)
  152. {
  153. INIT_OVERLOADED_CLASS_ENTRY(dotnet_class_entry, "DOTNET", NULL,
  154. php_DOTNET_call_function_handler,
  155. php_COM_get_property_handler,
  156. php_COM_set_property_handler);
  157. zend_register_internal_class(&dotnet_class_entry TSRMLS_CC);
  158. }
  159. function_entry DOTNET_functions[] = {
  160. {NULL, NULL, NULL}
  161. };
  162. static PHP_MINFO_FUNCTION(DOTNET)
  163. {
  164. php_info_print_table_start();
  165. php_info_print_table_row(2, ".NET support", "enabled");
  166. php_info_print_table_end();
  167. }
  168. PHP_MINIT_FUNCTION(DOTNET)
  169. {
  170. HRESULT hr;
  171. if (FAILED(hr = dotnet_init())) {
  172. return hr;
  173. }
  174. php_register_DOTNET_class(TSRMLS_C);
  175. return SUCCESS;
  176. }
  177. PHP_MSHUTDOWN_FUNCTION(DOTNET)
  178. {
  179. dotnet_term();
  180. return SUCCESS;
  181. }
  182. zend_module_entry dotnet_module_entry = {
  183. STANDARD_MODULE_HEADER,
  184. "dotnet", DOTNET_functions, PHP_MINIT(DOTNET), PHP_MSHUTDOWN(DOTNET), NULL, NULL, PHP_MINFO(DOTNET), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
  185. };
  186. BEGIN_EXTERN_C()
  187. ZEND_GET_MODULE(dotnet)
  188. END_EXTERN_C()
  189. #endif