urlmon: Separate NULL ptr check (Coverity 924).
[wine] / dlls / inetcomm / tests / mimeintl.c
1 /*
2  * MimeInternational tests
3  *
4  * Copyright 2008 Huw Davies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #define NONAMELESSUNION
23
24 #include "windows.h"
25 #include "ole2.h"
26 #include "ocidl.h"
27
28 #include "mimeole.h"
29
30 #include "initguid.h"
31 #include "mlang.h"
32
33 #include <stdio.h>
34 #include <assert.h>
35
36 #include "wine/test.h"
37
38 static void test_create(void)
39 {
40     IMimeInternational *internat, *internat2;
41     HRESULT hr;
42     ULONG ref;
43
44     hr = MimeOleGetInternat(&internat);
45     ok(hr == S_OK, "ret %08x\n", hr);
46     hr = MimeOleGetInternat(&internat2);
47     ok(hr == S_OK, "ret %08x\n", hr);
48
49     /* Under w2k8 it's no longer a singleton */
50     if(internat == internat2)
51     {
52         /* test to show that the object is a singleton with
53            a reference held by the dll. */
54         ref = IMimeInternational_Release(internat2);
55         ok(ref == 2 ||
56            ref == 1, /* win95 - object is a static singleton */
57            "got %d\n", ref);
58
59         ref = IMimeInternational_Release(internat);
60         ok(ref == 1, "got %d\n", ref);
61     }
62     else
63     {
64         ref = IMimeInternational_Release(internat2);
65         ok(ref == 0, "got %d\n", ref);
66
67         ref = IMimeInternational_Release(internat);
68         ok(ref == 0, "got %d\n", ref);
69     }
70
71 }
72
73 static inline HRESULT get_mlang(IMultiLanguage **ml)
74 {
75     return CoCreateInstance(&CLSID_CMultiLanguage, NULL,  CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
76                             &IID_IMultiLanguage, (void **)ml);
77 }
78
79 static HRESULT mlang_getcsetinfo(const char *charset, MIMECSETINFO *mlang_info)
80 {
81     DWORD len = MultiByteToWideChar(CP_ACP, 0, charset, -1, NULL, 0);
82     BSTR bstr = SysAllocStringLen(NULL, len - 1);
83     HRESULT hr;
84     IMultiLanguage *ml;
85
86     MultiByteToWideChar(CP_ACP, 0, charset, -1, bstr, len);
87
88     hr = get_mlang(&ml);
89
90     if(SUCCEEDED(hr))
91     {
92         hr = IMultiLanguage_GetCharsetInfo(ml, bstr, mlang_info);
93         IMultiLanguage_Release(ml);
94     }
95     SysFreeString(bstr);
96     if(FAILED(hr)) hr = MIME_E_NOT_FOUND;
97     return hr;
98 }
99
100 static HRESULT mlang_getcodepageinfo(UINT cp, MIMECPINFO *mlang_cp_info)
101 {
102     HRESULT hr;
103     IMultiLanguage *ml;
104
105     hr = get_mlang(&ml);
106
107     if(SUCCEEDED(hr))
108     {
109         hr = IMultiLanguage_GetCodePageInfo(ml, cp, mlang_cp_info);
110         IMultiLanguage_Release(ml);
111     }
112     return hr;
113 }
114
115 static HRESULT mlang_getcsetinfo_from_cp(UINT cp, CHARSETTYPE charset_type, MIMECSETINFO *mlang_info)
116 {
117     MIMECPINFO mlang_cp_info;
118     WCHAR *charset_name;
119     HRESULT hr;
120     IMultiLanguage *ml;
121
122     hr = mlang_getcodepageinfo(cp, &mlang_cp_info);
123     if(FAILED(hr)) return hr;
124
125     switch(charset_type)
126     {
127     case CHARSET_BODY:
128         charset_name = mlang_cp_info.wszBodyCharset;
129         break;
130     case CHARSET_HEADER:
131         charset_name = mlang_cp_info.wszHeaderCharset;
132         break;
133     case CHARSET_WEB:
134         charset_name = mlang_cp_info.wszWebCharset;
135         break;
136     }
137
138     hr = get_mlang(&ml);
139
140     if(SUCCEEDED(hr))
141     {
142         hr = IMultiLanguage_GetCharsetInfo(ml, charset_name, mlang_info);
143         IMultiLanguage_Release(ml);
144     }
145     return hr;
146 }
147
148 static void test_charset(void)
149 {
150     IMimeInternational *internat;
151     HRESULT hr;
152     HCHARSET hcs, hcs_windows_1252, hcs_windows_1251;
153     INETCSETINFO cs_info;
154     MIMECSETINFO mlang_cs_info;
155
156     hr = MimeOleGetInternat(&internat);
157     ok(hr == S_OK, "ret %08x\n", hr);
158
159     hr = IMimeInternational_FindCharset(internat, "non-existent", &hcs);
160     ok(hr == MIME_E_NOT_FOUND, "got %08x\n", hr);
161
162     hr = IMimeInternational_FindCharset(internat, "windows-1252", &hcs_windows_1252);
163     ok(hr == S_OK, "got %08x\n", hr);
164     hr = IMimeInternational_FindCharset(internat, "windows-1252", &hcs);
165     ok(hr == S_OK, "got %08x\n", hr);
166     ok(hcs_windows_1252 == hcs, "got different hcharsets for the same name\n");
167     hr = IMimeInternational_FindCharset(internat, "WiNdoWs-1252", &hcs);
168     ok(hr == S_OK, "got %08x\n", hr);
169     ok(hcs_windows_1252 == hcs, "got different hcharsets for the same name\n");
170
171     hr = IMimeInternational_FindCharset(internat, "windows-1251", &hcs_windows_1251);
172     ok(hr == S_OK, "got %08x\n", hr);
173     ok(hcs_windows_1252 != hcs_windows_1251, "got the same hcharset for the different names\n");
174
175     hr = IMimeInternational_GetCharsetInfo(internat, hcs_windows_1252, &cs_info);
176     ok(hr == S_OK, "got %08x\n", hr);
177
178     hr = mlang_getcsetinfo("windows-1252", &mlang_cs_info);
179     ok(hr == S_OK, "got %08x\n", hr);
180     ok(cs_info.cpiWindows == mlang_cs_info.uiCodePage, "cpiWindows %d while mlang uiCodePage %d\n",
181        cs_info.cpiWindows, mlang_cs_info.uiCodePage);
182     ok(cs_info.cpiInternet == mlang_cs_info.uiInternetEncoding, "cpiInternet %d while mlang uiInternetEncoding %d\n",
183        cs_info.cpiInternet, mlang_cs_info.uiInternetEncoding);
184     ok(cs_info.hCharset == hcs_windows_1252, "hCharset doesn't match requested\n");
185     ok(!strcmp(cs_info.szName, "windows-1252"), "szName doesn't match requested\n");
186
187     hr = IMimeInternational_GetCodePageCharset(internat, 1252, CHARSET_BODY, &hcs);
188     ok(hr == S_OK, "got %08x\n", hr);
189     hr = IMimeInternational_GetCharsetInfo(internat, hcs, &cs_info);
190     ok(hr == S_OK, "got %08x\n", hr);
191
192     hr = mlang_getcsetinfo_from_cp(1252, CHARSET_BODY, &mlang_cs_info);
193     ok(hr == S_OK, "got %08x\n", hr);
194     ok(cs_info.cpiWindows == mlang_cs_info.uiCodePage, "cpiWindows %d while mlang uiCodePage %d\n",
195        cs_info.cpiWindows, mlang_cs_info.uiCodePage);
196     ok(cs_info.cpiInternet == mlang_cs_info.uiInternetEncoding, "cpiInternet %d while mlang uiInternetEncoding %d\n",
197        cs_info.cpiInternet, mlang_cs_info.uiInternetEncoding);
198
199     IMimeInternational_Release(internat);
200 }
201
202 static void test_defaultcharset(void)
203 {
204     IMimeInternational *internat;
205     HRESULT hr;
206     HCHARSET hcs_default, hcs, hcs_windows_1251;
207
208     hr = MimeOleGetInternat(&internat);
209     ok(hr == S_OK, "ret %08x\n", hr);
210
211     hr = IMimeInternational_GetDefaultCharset(internat, &hcs_default);
212     ok(hr == S_OK, "ret %08x\n", hr);
213     hr = IMimeInternational_GetCodePageCharset(internat, GetACP(), CHARSET_BODY, &hcs);
214     ok(hr == S_OK, "ret %08x\n", hr);
215     ok(hcs_default == hcs, "Unexpected default charset\n");
216
217     hr = IMimeInternational_FindCharset(internat, "windows-1251", &hcs_windows_1251);
218     ok(hr == S_OK, "got %08x\n", hr);
219     hr = IMimeInternational_SetDefaultCharset(internat, hcs_windows_1251);
220     ok(hr == S_OK, "ret %08x\n", hr);
221     hr = IMimeInternational_GetDefaultCharset(internat, &hcs);
222     ok(hr == S_OK, "ret %08x\n", hr);
223     ok(hcs == hcs_windows_1251, "didn't retrieve recently set default\n");
224     /* Set the old default back again */
225     hr = IMimeInternational_SetDefaultCharset(internat, hcs_default);
226     ok(hr == S_OK, "ret %08x\n", hr);
227
228     IMimeInternational_Release(internat);
229 }
230
231 static void test_convert(void)
232 {
233     IMimeInternational *internat;
234     HRESULT hr;
235     BLOB src, dst;
236     ULONG read;
237     PROPVARIANT prop_in, prop_out;
238     static char test_string[] = "test string";
239     static WCHAR test_stringW[] = {'t','e','s','t',' ','s','t','r','i','n','g',0};
240
241     hr = MimeOleGetInternat(&internat);
242     ok(hr == S_OK, "ret %08x\n", hr);
243
244     src.pBlobData = (BYTE*)test_string;
245     src.cbSize = sizeof(test_string);
246     hr = IMimeInternational_ConvertBuffer(internat, 1252, 28591, &src, &dst, &read);
247     ok(hr == S_OK, "ret %08x\n", hr);
248     ok(read == sizeof(test_string), "got %d\n", read);
249     ok(dst.cbSize == sizeof(test_string), "got %d\n", dst.cbSize);
250     CoTaskMemFree(dst.pBlobData);
251
252     src.cbSize = 2;
253     hr = IMimeInternational_ConvertBuffer(internat, 1252, 28591, &src, &dst, &read);
254     ok(hr == S_OK, "ret %08x\n", hr);
255     ok(read == 2, "got %d\n", read);
256     ok(dst.cbSize == 2, "got %d\n", dst.cbSize);
257     CoTaskMemFree(dst.pBlobData);
258
259     prop_in.vt = VT_LPWSTR;
260     prop_in.u.pwszVal = test_stringW;
261     hr = IMimeInternational_ConvertString(internat, CP_UNICODE, 1252, &prop_in, &prop_out);
262     ok(hr == S_OK, "ret %08x\n", hr);
263     ok(prop_out.vt == VT_LPSTR, "got %d\n", prop_out.vt);
264     ok(!strcmp(prop_out.u.pszVal, test_string), "got %s\n", prop_out.u.pszVal);
265     PropVariantClear(&prop_out);
266
267     /* If in.vt is VT_LPWSTR, ignore cpiSrc */
268     prop_in.vt = VT_LPWSTR;
269     prop_in.u.pwszVal = test_stringW;
270     hr = IMimeInternational_ConvertString(internat, 28591, 1252, &prop_in, &prop_out);
271     ok(hr == S_OK, "ret %08x\n", hr);
272     ok(prop_out.vt == VT_LPSTR, "got %d\n", prop_out.vt);
273     ok(!strcmp(prop_out.u.pszVal, test_string), "got %s\n", prop_out.u.pszVal);
274     PropVariantClear(&prop_out);
275
276     prop_in.vt = VT_LPSTR;
277     prop_in.u.pszVal = test_string;
278     hr = IMimeInternational_ConvertString(internat, 28591, CP_UNICODE, &prop_in, &prop_out);
279     ok(hr == S_OK, "ret %08x\n", hr);
280     ok(prop_out.vt == VT_LPWSTR, "got %d\n", prop_out.vt);
281     ok(!lstrcmpW(prop_out.u.pwszVal, test_stringW), "mismatched strings\n");
282     PropVariantClear(&prop_out);
283
284     /* If in.vt is VT_LPSTR and cpiSrc is CP_UNICODE, use another multibyte codepage (probably GetACP()) */
285     prop_in.vt = VT_LPSTR;
286     prop_in.u.pszVal = test_string;
287     hr = IMimeInternational_ConvertString(internat, CP_UNICODE, CP_UNICODE, &prop_in, &prop_out);
288     ok(hr == S_OK, "ret %08x\n", hr);
289     ok(prop_out.vt == VT_LPWSTR, "got %d\n", prop_out.vt);
290     ok(!lstrcmpW(prop_out.u.pwszVal, test_stringW), "mismatched strings\n");
291     PropVariantClear(&prop_out);
292
293     IMimeInternational_Release(internat);
294 }
295
296 START_TEST(mimeintl)
297 {
298     OleInitialize(NULL);
299     test_create();
300     test_charset();
301     test_defaultcharset();
302     test_convert();
303     OleUninitialize();
304 }