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