2 * Tests for MSI Source functions
4 * Copyright (C) 2006 James Hawkins
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.
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.
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
21 #define _WIN32_MSI 300
31 #include "wine/test.h"
33 /* copied from dlls/msi/registry.c */
34 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
39 if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
53 out[17+i*2] = in[n++];
54 out[16+i*2] = in[n++];
59 out[17+i*2] = in[n++];
60 out[16+i*2] = in[n++];
66 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
68 WCHAR guidW[MAX_PATH];
69 WCHAR squashedW[MAX_PATH];
74 hr = CoCreateGuid(&guid);
75 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
77 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
78 ok(size == 39, "Expected 39, got %d\n", hr);
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);
85 static void get_user_sid(LPSTR *usersid)
92 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
94 GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
95 user = (PTOKEN_USER)buf;
96 ConvertSidToStringSid(user->User.Sid, usersid);
99 static void test_MsiSourceListGetInfo(void)
101 CHAR prodcode[MAX_PATH];
102 CHAR prod_squashed[MAX_PATH];
103 CHAR keypath[MAX_PATH*2];
104 CHAR value[MAX_PATH];
112 create_test_guid(prodcode, prod_squashed);
113 get_user_sid(&usersid);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
195 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
196 lstrcatA(keypath, prod_squashed);
198 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
199 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
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);
206 res = RegCreateKeyA(userkey, "SourceList", &hkey);
207 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
209 /* SourceList key exists */
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);
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);
220 /* PackageName value exists */
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);
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);
235 /* read the value, fix 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);
243 /* empty property now that product key exists */
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);
250 /* nonexistent property now that product key exists */
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);
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);
261 /* nonexistent property now that nonexistent value exists */
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);
268 /* invalid option now that product key exists */
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);
275 RegDeleteValueA(hkey, "nonexistent");
276 RegDeleteValueA(hkey, "PackageName");
277 RegDeleteKeyA(hkey, "");
278 RegDeleteKeyA(userkey, "");
280 RegCloseKey(userkey);
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);
289 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Patches\\");
290 lstrcatA(keypath, prod_squashed);
292 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
293 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
296 * NOTE: using prodcode guid, but it really doesn't matter
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);
304 res = RegCreateKeyA(userkey, "SourceList", &hkey);
305 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
307 /* SourceList key exists */
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);
314 RegDeleteKeyA(hkey, "");
315 RegDeleteKeyA(userkey, "");
317 RegCloseKey(userkey);
322 test_MsiSourceListGetInfo();