com_olechar.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. | Harald Radi <h.radi@nme.at> |
  15. +----------------------------------------------------------------------+
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #include "php.h"
  21. #include "php_ini.h"
  22. #include "ext/standard/info.h"
  23. #include "php_com_dotnet.h"
  24. #include "php_com_dotnet_internal.h"
  25. PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(const char *string, size_t string_len, int codepage)
  26. {
  27. OLECHAR *olestring = NULL;
  28. DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
  29. BOOL ok;
  30. if (string_len == -1) {
  31. /* determine required length for the buffer (includes NUL terminator) */
  32. string_len = MultiByteToWideChar(codepage, flags, string, -1, NULL, 0);
  33. } else {
  34. /* allow room for NUL terminator */
  35. string_len++;
  36. }
  37. if (string_len > 0) {
  38. olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0);
  39. /* XXX if that's a real multibyte string, olestring is obviously allocated excessively.
  40. This should be fixed by reallocating the olestring, but as emalloc is used, that doesn't
  41. matter much. */
  42. ok = MultiByteToWideChar(codepage, flags, string, (int)string_len, olestring, (int)string_len);
  43. if (ok > 0 && (size_t)ok < string_len) {
  44. olestring[ok] = '\0';
  45. }
  46. } else {
  47. ok = FALSE;
  48. olestring = (OLECHAR*)emalloc(sizeof(OLECHAR));
  49. *olestring = 0;
  50. }
  51. if (!ok) {
  52. char *msg = php_win32_error_to_msg(GetLastError());
  53. php_error_docref(NULL, E_WARNING,
  54. "Could not convert string to unicode: `%s'", msg);
  55. php_win32_error_msg_free(msg);
  56. }
  57. return olestring;
  58. }
  59. PHP_COM_DOTNET_API char *php_com_olestring_to_string(OLECHAR *olestring, size_t *string_len, int codepage)
  60. {
  61. char *string;
  62. uint32_t length = 0;
  63. BOOL ok;
  64. length = WideCharToMultiByte(codepage, 0, olestring, -1, NULL, 0, NULL, NULL);
  65. if (length) {
  66. string = (char*)safe_emalloc(length, sizeof(char), 0);
  67. length = WideCharToMultiByte(codepage, 0, olestring, -1, string, length, NULL, NULL);
  68. ok = length > 0;
  69. } else {
  70. string = (char*)emalloc(sizeof(char));
  71. *string = '\0';
  72. ok = FALSE;
  73. length = 0;
  74. }
  75. if (!ok) {
  76. char *msg = php_win32_error_to_msg(GetLastError());
  77. php_error_docref(NULL, E_WARNING,
  78. "Could not convert string from unicode: `%s'", msg);
  79. php_win32_error_msg_free(msg);
  80. }
  81. if (string_len) {
  82. *string_len = length-1;
  83. }
  84. return string;
  85. }
  86. BSTR php_com_string_to_bstr(zend_string *string, int codepage)
  87. {
  88. BSTR bstr = NULL;
  89. DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
  90. size_t mb_len = ZSTR_LEN(string);
  91. int wc_len;
  92. if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, NULL, 0)) <= 0) {
  93. goto fail;
  94. }
  95. if ((bstr = SysAllocStringLen(NULL, (UINT)(wc_len - 1))) == NULL) {
  96. goto fail;
  97. }
  98. if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, bstr, wc_len)) <= 0) {
  99. goto fail;
  100. }
  101. return bstr;
  102. fail:
  103. char *msg = php_win32_error_to_msg(GetLastError());
  104. php_error_docref(NULL, E_WARNING,
  105. "Could not convert string to unicode: `%s'", msg);
  106. LocalFree(msg);
  107. SysFreeString(bstr);
  108. return SysAllocString(L"");
  109. }
  110. zend_string *php_com_bstr_to_string(BSTR bstr, int codepage)
  111. {
  112. zend_string *string = NULL;
  113. UINT wc_len = SysStringLen(bstr);
  114. int mb_len;
  115. mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, NULL, 0, NULL, NULL);
  116. if (mb_len > 0) {
  117. string = zend_string_alloc(mb_len - 1, 0);
  118. mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, ZSTR_VAL(string), mb_len, NULL, NULL);
  119. }
  120. if (mb_len <= 0) {
  121. char *msg = php_win32_error_to_msg(GetLastError());
  122. php_error_docref(NULL, E_WARNING,
  123. "Could not convert string from unicode: `%s'", msg);
  124. LocalFree(msg);
  125. if (string != NULL) {
  126. zend_string_release(string);
  127. }
  128. string = ZSTR_EMPTY_ALLOC();
  129. }
  130. return string;
  131. }