msi/tests: Add test for empty MsiGetProductInfo parameters not referencing default...
[wine] / dlls / msi / tests / msi.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
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 #include <stdio.h>
22 #include <windows.h>
23 #include <msi.h>
24 #include <msiquery.h>
25
26 #include "wine/test.h"
27
28 typedef struct test_MSIFILEHASHINFO {
29     ULONG dwFileHashInfoSize;
30     ULONG dwData[4];
31 } test_MSIFILEHASHINFO, *test_PMSIFILEHASHINFO;
32
33 typedef INSTALLSTATE (WINAPI *fnMsiUseFeatureExA)(LPCSTR, LPCSTR ,DWORD, DWORD );
34 fnMsiUseFeatureExA pMsiUseFeatureExA;
35 typedef UINT (WINAPI *fnMsiOpenPackageExA)(LPCSTR, DWORD, MSIHANDLE*);
36 fnMsiOpenPackageExA pMsiOpenPackageExA;
37 typedef UINT (WINAPI *fnMsiOpenPackageExW)(LPCWSTR, DWORD, MSIHANDLE*);
38 fnMsiOpenPackageExW pMsiOpenPackageExW;
39 typedef INSTALLSTATE (WINAPI *fnMsiGetComponentPathA)(LPCSTR, LPCSTR, LPSTR, DWORD*);
40 fnMsiGetComponentPathA pMsiGetComponentPathA;
41 typedef UINT (WINAPI *fnMsiGetFileHashA)(LPCSTR, DWORD, test_PMSIFILEHASHINFO);
42 fnMsiGetFileHashA pMsiGetFileHashA;
43
44 static void test_usefeature(void)
45 {
46     UINT r;
47
48     if (!pMsiUseFeatureExA)
49         return;
50
51     r = MsiQueryFeatureState(NULL,NULL);
52     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
53
54     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
55     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
56
57     r = pMsiUseFeatureExA(NULL,NULL,0,0);
58     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
59
60     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
61     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
62
63     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
64                          NULL, -2, 0 );
65     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
66
67     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
68                          "WORDVIEWFiles", -2, 0 );
69     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
70
71     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
72                          "WORDVIEWFiles", -2, 0 );
73     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
74
75     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
76                          "WORDVIEWFiles", -2, 1 );
77     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
78 }
79
80 static void test_null(void)
81 {
82     MSIHANDLE hpkg;
83     UINT r;
84     HKEY hkey;
85     DWORD dwType, cbData;
86     LPBYTE lpData = NULL;
87
88     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
89     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
90
91     r = MsiQueryProductStateW(NULL);
92     ok( r == INSTALLSTATE_INVALIDARG, "wrong return\n");
93
94     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
95     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
96
97     r = MsiConfigureFeatureW(NULL, NULL, 0);
98     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
99
100     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
101     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
102
103     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
104     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
105
106     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
107     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
108
109     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
110      * necessary registry values */
111
112     /* empty product string */
113     r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
114     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
115
116     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
117     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
118     if ( r == ERROR_SUCCESS )
119     {
120         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
121         if (!lpData)
122             skip("Out of memory\n");
123         else
124         {
125             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
126             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
127         }
128     }
129
130     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
131     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
132
133     r = MsiGetProductInfoA("", "", NULL, NULL);
134     todo_wine ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
135
136     if (lpData)
137     {
138         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
139         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
140
141         HeapFree(GetProcessHeap(), 0, lpData);
142     }
143     else
144     {
145         r = RegDeleteValueA(hkey, NULL);
146         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
147     }
148
149     r = RegCloseKey(hkey);
150     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
151
152     /* empty attribute */
153     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
154     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
155
156     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
157     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
158
159     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
160     todo_wine ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
161
162     r = RegCloseKey(hkey);
163     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
164
165     r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
166     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
167 }
168
169 static void test_getcomponentpath(void)
170 {
171     INSTALLSTATE r;
172     char buffer[0x100];
173     DWORD sz;
174
175     if(!pMsiGetComponentPathA)
176         return;
177
178     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
179     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
180
181     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
182     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
183
184     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
185     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
186
187     sz = sizeof buffer;
188     buffer[0]=0;
189     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
190     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
191
192     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
193         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
194     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
195
196     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
197         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
198     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
199
200     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
201         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
202     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
203
204     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
205                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
206     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
207 }
208
209 static void test_filehash(void)
210 {
211     const char name[] = "msitest.bin";
212     const char data[] = {'a','b','c'};
213     HANDLE handle;
214     UINT r;
215     test_MSIFILEHASHINFO hash;
216     DWORD count = 0;
217
218     if (!pMsiGetFileHashA)
219         return;
220
221     DeleteFile(name);
222
223     memset(&hash, 0, sizeof hash);
224     r = pMsiGetFileHashA(name, 0, &hash);
225     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
226
227     r = pMsiGetFileHashA(name, 0, NULL);
228     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
229
230     memset(&hash, 0, sizeof hash);
231     hash.dwFileHashInfoSize = sizeof hash;
232     r = pMsiGetFileHashA(name, 0, &hash);
233     ok( r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
234
235     handle = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, 
236                 CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
237     ok(handle != INVALID_HANDLE_VALUE, "failed to create file\n");
238
239     WriteFile(handle, data, sizeof data, &count, NULL);
240     CloseHandle(handle);
241
242     memset(&hash, 0, sizeof hash);
243     r = pMsiGetFileHashA(name, 0, &hash);
244     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
245
246     memset(&hash, 0, sizeof hash);
247     hash.dwFileHashInfoSize = sizeof hash;
248     r = pMsiGetFileHashA(name, 1, &hash);
249     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
250
251     r = pMsiGetFileHashA(name, 0, &hash);
252     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
253
254     ok(hash.dwFileHashInfoSize == sizeof hash, "hash size changed\n");
255     ok(hash.dwData[0] == 0x98500190 &&
256        hash.dwData[1] == 0xb04fd23c &&
257        hash.dwData[2] == 0x7d3f96d6 &&
258        hash.dwData[3] == 0x727fe128, "hash of abc incorrect\n");
259
260     DeleteFile(name);
261 }
262
263 START_TEST(msi)
264 {
265     HMODULE hmod = GetModuleHandle("msi.dll");
266     pMsiUseFeatureExA = (fnMsiUseFeatureExA) 
267         GetProcAddress(hmod, "MsiUseFeatureExA");
268     pMsiOpenPackageExA = (fnMsiOpenPackageExA) 
269         GetProcAddress(hmod, "MsiOpenPackageExA");
270     pMsiOpenPackageExW = (fnMsiOpenPackageExW) 
271         GetProcAddress(hmod, "MsiOpenPackageExW");
272     pMsiGetComponentPathA = (fnMsiGetComponentPathA)
273         GetProcAddress(hmod, "MsiGetComponentPathA" );
274     pMsiGetFileHashA = (fnMsiGetFileHashA)
275         GetProcAddress(hmod, "MsiGetFileHashA" );
276
277     test_usefeature();
278     test_null();
279     test_getcomponentpath();
280     test_filehash();
281 }