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