crypt32: Introduce function to encode an array of items as a set.
[wine] / dlls / msi / tests / source.c
1 /*
2  * Tests for MSI Source functions
3  *
4  * Copyright (C) 2006 James Hawkins
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 _WIN32_MSI 300
22
23 #include <stdio.h>
24
25 #include <windows.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <msi.h>
29 #include <sddl.h>
30
31 #include "wine/test.h"
32
33 /* copied from dlls/msi/registry.c */
34 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
35 {
36     DWORD i,n=1;
37     GUID guid;
38
39     if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
40         return FALSE;
41
42     for(i=0; i<8; i++)
43         out[7-i] = in[n++];
44     n++;
45     for(i=0; i<4; i++)
46         out[11-i] = in[n++];
47     n++;
48     for(i=0; i<4; i++)
49         out[15-i] = in[n++];
50     n++;
51     for(i=0; i<2; i++)
52     {
53         out[17+i*2] = in[n++];
54         out[16+i*2] = in[n++];
55     }
56     n++;
57     for( ; i<8; i++)
58     {
59         out[17+i*2] = in[n++];
60         out[16+i*2] = in[n++];
61     }
62     out[32]=0;
63     return TRUE;
64 }
65
66 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
67 {
68     WCHAR guidW[MAX_PATH];
69     WCHAR squashedW[MAX_PATH];
70     GUID guid;
71     HRESULT hr;
72     int size;
73
74     hr = CoCreateGuid(&guid);
75     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
76
77     size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
78     ok(size == 39, "Expected 39, got %d\n", hr);
79
80     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
81     squash_guid(guidW, squashedW);
82     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
83 }
84
85 static void get_user_sid(LPSTR *usersid)
86 {
87     HANDLE token;
88     BYTE buf[1024];
89     DWORD size;
90     PTOKEN_USER user;
91
92     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
93     size = sizeof(buf);
94     GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
95     user = (PTOKEN_USER)buf;
96     ConvertSidToStringSid(user->User.Sid, usersid);
97 }
98
99 static void test_MsiSourceListGetInfo(void)
100 {
101     CHAR prodcode[MAX_PATH];
102     CHAR prod_squashed[MAX_PATH];
103     CHAR keypath[MAX_PATH*2];
104     CHAR value[MAX_PATH];
105     LPSTR usersid;
106     LPCSTR data;
107     LONG res;
108     UINT r;
109     HKEY userkey, hkey;
110     DWORD size;
111
112     create_test_guid(prodcode, prod_squashed);
113     get_user_sid(&usersid);
114
115     /* NULL szProductCodeOrPatchCode */
116     r = MsiSourceListGetInfoA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
117                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
118     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
119
120     /* empty szProductCodeOrPatchCode */
121     r = MsiSourceListGetInfoA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
122                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
123     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
124
125     /* garbage szProductCodeOrPatchCode */
126     r = MsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
127                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
128     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
129
130     /*  szProductCodeOrPatchCode */
131     r = MsiSourceListGetInfoA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
132                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
133     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
134
135     /* guid without brackets */
136     r = MsiSourceListGetInfoA("51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
137                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
138     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
139
140     /* guid with brackets */
141     r = MsiSourceListGetInfoA("{51CD2AD5-0482-4C46-8DDD-0ED1022AA1AA}", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
142                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
143     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
144
145     /* same length as guid, but random */
146     r = MsiSourceListGetInfoA("ADKD-2KSDFF2-DKK1KNFJASD9GLKWME-1I3KAD", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
147                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
148     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
149
150     /* invalid context */
151     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_NONE,
152                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
153     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
154
155     /* another invalid context */
156     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALLUSERMANAGED,
157                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
158     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
159
160     /* yet another invalid context */
161     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_ALL,
162                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
163     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
164
165     /* mix two valid contexts */
166     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED,
167                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
168     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
169
170     /* invalid option */
171     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
172                               4, INSTALLPROPERTY_PACKAGENAME, NULL, NULL);
173     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
174
175     /* NULL property */
176     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
177                               MSICODE_PRODUCT, NULL, NULL, NULL);
178     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
179
180     /* empty property */
181     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
182                               MSICODE_PRODUCT, "", NULL, NULL);
183     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
184
185     /* value is non-NULL while size is NULL */
186     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
187                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, NULL);
188     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
189
190     /* size is non-NULL while value is NULL */
191     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
192                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
193     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
194
195     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
196     lstrcatA(keypath, prod_squashed);
197
198     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
200
201     /* user product key exists */
202     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
203                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
204     ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
205
206     res = RegCreateKeyA(userkey, "SourceList", &hkey);
207     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
208
209     /* SourceList key exists */
210     size = 0xdeadbeef;
211     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
212                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
213     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
214     ok(size == 0, "Expected 0, got %d\n", size);
215
216     data = "msitest.msi";
217     res = RegSetValueExA(hkey, "PackageName", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
218     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
219
220     /* PackageName value exists */
221     size = 0xdeadbeef;
222     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
223                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
224     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
225     ok(size == 11, "Expected 11, got %d\n", size);
226
227     /* read the value, don't change size */
228     lstrcpyA(value, "aaa");
229     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
230                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
231     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
232     ok(!lstrcmpA(value, "aaa"), "Expected 'aaa', got %s\n", value);
233     ok(size == 11, "Expected 11, got %d\n", size);
234
235     /* read the value, fix size */
236     size++;
237     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
238                               MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAME, value, &size);
239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
240     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
241     ok(size == 11, "Expected 11, got %d\n", size);
242
243     /* empty property now that product key exists */
244     size = 0xdeadbeef;
245     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
246                               MSICODE_PRODUCT, "", NULL, &size);
247     ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
248     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
249
250     /* nonexistent property now that product key exists */
251     size = 0xdeadbeef;
252     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
253                               MSICODE_PRODUCT, "nonexistent", NULL, &size);
254     ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
255     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
256
257     data = "tester";
258     res = RegSetValueExA(hkey, "nonexistent", 0, REG_SZ, (const BYTE *)data, lstrlenA(data) + 1);
259     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
260
261     /* nonexistent property now that nonexistent value exists */
262     size = 0xdeadbeef;
263     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
264                               MSICODE_PRODUCT, "nonexistent", NULL, &size);
265     ok(r == ERROR_UNKNOWN_PROPERTY, "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
266     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
267
268     /* invalid option now that product key exists */
269     size = 0xdeadbeef;
270     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
271                               4, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
272     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
273     ok(size == 11, "Expected 11, got %d\n", size);
274
275     RegDeleteValueA(hkey, "nonexistent");
276     RegDeleteValueA(hkey, "PackageName");
277     RegDeleteKeyA(hkey, "");
278     RegDeleteKeyA(userkey, "");
279     RegCloseKey(hkey);
280     RegCloseKey(userkey);
281
282     /* try a patch */
283     size = 0xdeadbeef;
284     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
285                               MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
286     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
287     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
288
289     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Patches\\");
290     lstrcatA(keypath, prod_squashed);
291
292     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
294
295     /* patch key exists
296      * NOTE: using prodcode guid, but it really doesn't matter
297      */
298     size = 0xdeadbeef;
299     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
300                               MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
301     ok(r == ERROR_BAD_CONFIGURATION, "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
302     ok(size == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", size);
303
304     res = RegCreateKeyA(userkey, "SourceList", &hkey);
305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
306
307     /* SourceList key exists */
308     size = 0xdeadbeef;
309     r = MsiSourceListGetInfoA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
310                               MSICODE_PATCH, INSTALLPROPERTY_PACKAGENAME, NULL, &size);
311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
312     ok(size == 0, "Expected 0, got %d\n", size);
313
314     RegDeleteKeyA(hkey, "");
315     RegDeleteKeyA(userkey, "");
316     RegCloseKey(hkey);
317     RegCloseKey(userkey);
318 }
319
320 START_TEST(source)
321 {
322     test_MsiSourceListGetInfo();
323 }