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 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
35 static UINT (WINAPI *pMsiSourceListGetInfoA)
36 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
38 static void init_functionpointers(void)
40 HMODULE hmsi = GetModuleHandleA("msi.dll");
41 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
43 pMsiSourceListGetInfoA = (void*)GetProcAddress(hmsi, "MsiSourceListGetInfoA");
45 pConvertSidToStringSidA = (void*)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
48 /* copied from dlls/msi/registry.c */
49 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
54 if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
68 out[17+i*2] = in[n++];
69 out[16+i*2] = in[n++];
74 out[17+i*2] = in[n++];
75 out[16+i*2] = in[n++];
81 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
83 WCHAR guidW[MAX_PATH];
84 WCHAR squashedW[MAX_PATH];
89 hr = CoCreateGuid(&guid);
90 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
92 size = StringFromGUID2(&guid, (LPOLESTR)guidW, MAX_PATH);
93 ok(size == 39, "Expected 39, got %d\n", hr);
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);
100 static void get_user_sid(LPSTR *usersid)
107 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
109 GetTokenInformation(token, TokenUser, (void *)buf, size, &size);
110 user = (PTOKEN_USER)buf;
111 pConvertSidToStringSidA(user->User.Sid, usersid);
114 static void test_MsiSourceListGetInfo(void)
116 CHAR prodcode[MAX_PATH];
117 CHAR prod_squashed[MAX_PATH];
118 CHAR keypath[MAX_PATH*2];
119 CHAR value[MAX_PATH];
127 create_test_guid(prodcode, prod_squashed);
128 get_user_sid(&usersid);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
210 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
211 lstrcatA(keypath, prod_squashed);
213 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
214 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
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);
221 res = RegCreateKeyA(userkey, "SourceList", &hkey);
222 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
224 /* SourceList key exists */
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);
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);
235 /* PackageName value exists */
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);
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);
250 /* read the value, fix 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);
258 /* empty property now that product key exists */
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);
265 /* nonexistent property now that product key exists */
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);
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);
276 /* nonexistent property now that nonexistent value exists */
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);
283 /* invalid option now that product key exists */
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);
290 RegDeleteValueA(hkey, "nonexistent");
291 RegDeleteValueA(hkey, "PackageName");
292 RegDeleteKeyA(hkey, "");
293 RegDeleteKeyA(userkey, "");
295 RegCloseKey(userkey);
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);
304 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Patches\\");
305 lstrcatA(keypath, prod_squashed);
307 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
308 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
311 * NOTE: using prodcode guid, but it really doesn't matter
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);
319 res = RegCreateKeyA(userkey, "SourceList", &hkey);
320 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
322 /* SourceList key exists */
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);
329 RegDeleteKeyA(hkey, "");
330 RegDeleteKeyA(userkey, "");
332 RegCloseKey(userkey);
337 init_functionpointers();
339 test_MsiSourceListGetInfo();