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
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
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
28
php_com_string_to_olestring(const char * string,size_t string_len,int codepage)29 PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(const char *string, size_t string_len, int codepage)
30 {
31 OLECHAR *olestring = NULL;
32 DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
33 BOOL ok;
34
35 if (string_len == -1) {
36 /* determine required length for the buffer (includes NUL terminator) */
37 string_len = MultiByteToWideChar(codepage, flags, string, -1, NULL, 0);
38 } else {
39 /* allow room for NUL terminator */
40 string_len++;
41 }
42
43 if (string_len > 0) {
44 olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0);
45 /* XXX if that's a real multibyte string, olestring is obviously allocated excessively.
46 This should be fixed by reallocating the olestring, but as emalloc is used, that doesn't
47 matter much. */
48 ok = MultiByteToWideChar(codepage, flags, string, (int)string_len, olestring, (int)string_len);
49 if (ok > 0 && (size_t)ok < string_len) {
50 olestring[ok] = '\0';
51 }
52 } else {
53 ok = FALSE;
54 olestring = (OLECHAR*)emalloc(sizeof(OLECHAR));
55 *olestring = 0;
56 }
57
58 if (!ok) {
59 char *msg = php_win32_error_to_msg(GetLastError());
60
61 php_error_docref(NULL, E_WARNING,
62 "Could not convert string to unicode: `%s'", msg);
63
64 php_win32_error_msg_free(msg);
65 }
66
67 return olestring;
68 }
69
php_com_olestring_to_string(OLECHAR * olestring,int codepage)70 PHP_COM_DOTNET_API zend_string *php_com_olestring_to_string(OLECHAR *olestring, int codepage)
71 {
72 zend_string *string;
73 uint32_t length = 0;
74
75 length = WideCharToMultiByte(codepage, 0, olestring, -1, NULL, 0, NULL, NULL);
76
77 if (length) {
78 /* We remove 1 from the length as it takes into account the terminating null byte
79 * which zend_string alloc already takes into consideration */
80 /* TODO Should use safe alloc? */
81 string = zend_string_alloc(length - 1, /* persistent */ false);
82 length = WideCharToMultiByte(codepage, 0, olestring, -1, ZSTR_VAL(string), length, NULL, NULL);
83 } else {
84 string = ZSTR_EMPTY_ALLOC();
85 }
86
87 /* Failure to determine length of WideChar */
88 if (length == 0) {
89 char *msg = php_win32_error_to_msg(GetLastError());
90
91 php_error_docref(NULL, E_WARNING,
92 "Could not convert string from unicode: `%s'", msg);
93
94 php_win32_error_msg_free(msg);
95 }
96
97 return string;
98 }
99
php_com_string_to_bstr(zend_string * string,int codepage)100 BSTR php_com_string_to_bstr(zend_string *string, int codepage)
101 {
102 BSTR bstr = NULL;
103 DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
104 size_t mb_len = ZSTR_LEN(string);
105 int wc_len;
106
107 if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, NULL, 0)) <= 0) {
108 goto fail;
109 }
110 if ((bstr = SysAllocStringLen(NULL, (UINT)(wc_len - 1))) == NULL) {
111 goto fail;
112 }
113 if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, bstr, wc_len)) <= 0) {
114 goto fail;
115 }
116 return bstr;
117
118 fail:
119 char *msg = php_win32_error_to_msg(GetLastError());
120 php_error_docref(NULL, E_WARNING,
121 "Could not convert string to unicode: `%s'", msg);
122 LocalFree(msg);
123 SysFreeString(bstr);
124 return SysAllocString(L"");
125 }
126
php_com_bstr_to_string(BSTR bstr,int codepage)127 zend_string *php_com_bstr_to_string(BSTR bstr, int codepage)
128 {
129 zend_string *string = NULL;
130 UINT wc_len = SysStringLen(bstr);
131 int mb_len;
132
133 mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, NULL, 0, NULL, NULL);
134 if (mb_len > 0) {
135 string = zend_string_alloc(mb_len - 1, 0);
136 mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, ZSTR_VAL(string), mb_len, NULL, NULL);
137 }
138
139 if (mb_len <= 0) {
140 char *msg = php_win32_error_to_msg(GetLastError());
141
142 php_error_docref(NULL, E_WARNING,
143 "Could not convert string from unicode: `%s'", msg);
144 LocalFree(msg);
145
146 if (string != NULL) {
147 zend_string_release(string);
148 }
149 string = ZSTR_EMPTY_ALLOC();
150 }
151
152 return string;
153 }
154