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,size_t * string_len,int codepage)70 PHP_COM_DOTNET_API char *php_com_olestring_to_string(OLECHAR *olestring, size_t *string_len, int codepage)
71 {
72 char *string;
73 uint32_t length = 0;
74 BOOL ok;
75
76 length = WideCharToMultiByte(codepage, 0, olestring, -1, NULL, 0, NULL, NULL);
77
78 if (length) {
79 string = (char*)safe_emalloc(length, sizeof(char), 0);
80 length = WideCharToMultiByte(codepage, 0, olestring, -1, string, length, NULL, NULL);
81 ok = length > 0;
82 } else {
83 string = (char*)emalloc(sizeof(char));
84 *string = '\0';
85 ok = FALSE;
86 length = 0;
87 }
88
89 if (!ok) {
90 char *msg = php_win32_error_to_msg(GetLastError());
91
92 php_error_docref(NULL, E_WARNING,
93 "Could not convert string from unicode: `%s'", msg);
94
95 php_win32_error_msg_free(msg);
96 }
97
98 if (string_len) {
99 *string_len = length-1;
100 }
101
102 return string;
103 }
104
php_com_string_to_bstr(zend_string * string,int codepage)105 BSTR php_com_string_to_bstr(zend_string *string, int codepage)
106 {
107 BSTR bstr = NULL;
108 DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
109 size_t mb_len = ZSTR_LEN(string);
110 int wc_len;
111
112 if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, NULL, 0)) <= 0) {
113 goto fail;
114 }
115 if ((bstr = SysAllocStringLen(NULL, (UINT)(wc_len - 1))) == NULL) {
116 goto fail;
117 }
118 if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, bstr, wc_len)) <= 0) {
119 goto fail;
120 }
121 return bstr;
122
123 fail:
124 char *msg = php_win32_error_to_msg(GetLastError());
125 php_error_docref(NULL, E_WARNING,
126 "Could not convert string to unicode: `%s'", msg);
127 LocalFree(msg);
128 SysFreeString(bstr);
129 return SysAllocString(L"");
130 }
131
php_com_bstr_to_string(BSTR bstr,int codepage)132 zend_string *php_com_bstr_to_string(BSTR bstr, int codepage)
133 {
134 zend_string *string = NULL;
135 UINT wc_len = SysStringLen(bstr);
136 int mb_len;
137
138 mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, NULL, 0, NULL, NULL);
139 if (mb_len > 0) {
140 string = zend_string_alloc(mb_len - 1, 0);
141 mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, ZSTR_VAL(string), mb_len, NULL, NULL);
142 }
143
144 if (mb_len <= 0) {
145 char *msg = php_win32_error_to_msg(GetLastError());
146
147 php_error_docref(NULL, E_WARNING,
148 "Could not convert string from unicode: `%s'", msg);
149 LocalFree(msg);
150
151 if (string != NULL) {
152 zend_string_release(string);
153 }
154 string = ZSTR_EMPTY_ALLOC();
155 }
156
157 return string;
158 }
159