[MSI_WINETEST]
[reactos.git] / rostests / winetests / msi / 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 #define _WIN32_MSI 300
22
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <sddl.h>
29
30 #include "wine/test.h"
31
32 static BOOL is_wow64;
33 static const char msifile[] = "winetest.msi";
34 static char CURR_DIR[MAX_PATH];
35 static char PROG_FILES_DIR[MAX_PATH];
36 static char PROG_FILES_DIR_NATIVE[MAX_PATH];
37 static char COMMON_FILES_DIR[MAX_PATH];
38 static char WINDOWS_DIR[MAX_PATH];
39
40 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
41 static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
42 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
43 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
44
45 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
46 (LPCSTR, LPCSTR, LPSTR, DWORD*);
47 static UINT (WINAPI *pMsiGetFileHashA)
48 (LPCSTR, DWORD, PMSIFILEHASHINFO);
49 static UINT (WINAPI *pMsiGetProductInfoExA)
50 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
51 static UINT (WINAPI *pMsiOpenPackageExA)
52 (LPCSTR, DWORD, MSIHANDLE*);
53 static UINT (WINAPI *pMsiOpenPackageExW)
54 (LPCWSTR, DWORD, MSIHANDLE*);
55 static UINT (WINAPI *pMsiEnumPatchesExA)
56 (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
57 MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
58 static UINT (WINAPI *pMsiQueryComponentStateA)
59 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
60 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
61 (LPCSTR, LPCSTR ,DWORD, DWORD);
62 static UINT (WINAPI *pMsiGetPatchInfoExA)
63 (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
64 static UINT (WINAPI *pMsiEnumProductsExA)
65 (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
66 static UINT (WINAPI *pMsiEnumComponentsExA)
67 (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
68 static UINT (WINAPI *pMsiSetExternalUIRecord)
69 (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
70
71 static void init_functionpointers(void)
72 {
73 HMODULE hmsi = GetModuleHandleA("msi.dll");
74 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
75 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
76
77 #define GET_PROC(dll, func) \
78 p ## func = (void *)GetProcAddress(dll, #func); \
79 if(!p ## func) \
80 trace("GetProcAddress(%s) failed\n", #func);
81
82 GET_PROC(hmsi, MsiGetComponentPathA)
83 GET_PROC(hmsi, MsiGetFileHashA)
84 GET_PROC(hmsi, MsiGetProductInfoExA)
85 GET_PROC(hmsi, MsiOpenPackageExA)
86 GET_PROC(hmsi, MsiOpenPackageExW)
87 GET_PROC(hmsi, MsiEnumPatchesExA)
88 GET_PROC(hmsi, MsiQueryComponentStateA)
89 GET_PROC(hmsi, MsiSetExternalUIRecord)
90 GET_PROC(hmsi, MsiUseFeatureExA)
91 GET_PROC(hmsi, MsiGetPatchInfoExA)
92 GET_PROC(hmsi, MsiEnumProductsExA)
93 GET_PROC(hmsi, MsiEnumComponentsExA)
94
95 GET_PROC(hadvapi32, ConvertSidToStringSidA)
96 GET_PROC(hadvapi32, OpenProcessToken);
97 GET_PROC(hadvapi32, RegDeleteKeyExA)
98 GET_PROC(hkernel32, IsWow64Process)
99
100 #undef GET_PROC
101 }
102
103 static BOOL get_system_dirs(void)
104 {
105 HKEY hkey;
106 DWORD type, size;
107
108 if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
109 return FALSE;
110
111 size = MAX_PATH;
112 if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
113 RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
114 {
115 RegCloseKey(hkey);
116 return FALSE;
117 }
118 size = MAX_PATH;
119 if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
120 RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
121 {
122 RegCloseKey(hkey);
123 return FALSE;
124 }
125 size = MAX_PATH;
126 if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR_NATIVE, &size))
127 {
128 RegCloseKey(hkey);
129 return FALSE;
130 }
131 RegCloseKey(hkey);
132 if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH)) return FALSE;
133 return TRUE;
134 }
135
136 static BOOL file_exists(const char *file)
137 {
138 return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
139 }
140
141 static BOOL pf_exists(const char *file)
142 {
143 char path[MAX_PATH];
144
145 lstrcpyA(path, PROG_FILES_DIR);
146 lstrcatA(path, "\\");
147 lstrcatA(path, file);
148 return file_exists(path);
149 }
150
151 static BOOL delete_pf(const char *rel_path, BOOL is_file)
152 {
153 char path[MAX_PATH];
154
155 lstrcpyA(path, PROG_FILES_DIR);
156 lstrcatA(path, "\\");
157 lstrcatA(path, rel_path);
158
159 if (is_file)
160 return DeleteFileA(path);
161 else
162 return RemoveDirectoryA(path);
163 }
164
165 static BOOL is_process_limited(void)
166 {
167 HANDLE token;
168 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
169 DWORD size;
170 BOOL ret;
171
172 if (!pOpenProcessToken) return FALSE;
173 if (!pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) return FALSE;
174 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
175 CloseHandle(token);
176 return (ret && type == TokenElevationTypeLimited);
177 }
178
179 /* msi database data */
180
181 static const char directory_dat[] =
182 "Directory\tDirectory_Parent\tDefaultDir\n"
183 "s72\tS72\tl255\n"
184 "Directory\tDirectory\n"
185 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
186 "ProgramFilesFolder\tTARGETDIR\t.\n"
187 "TARGETDIR\t\tSourceDir";
188
189 static const char component_dat[] =
190 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
191 "s72\tS38\ts72\ti2\tS255\tS72\n"
192 "Component\tComponent\n"
193 "One\t{8F5BAEEF-DD92-40AC-9397-BE3CF9F97C81}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n";
194
195 static const char feature_dat[] =
196 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
197 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
198 "Feature\tFeature\n"
199 "One\t\tOne\tOne\t1\t3\tMSITESTDIR\t0\n"
200 "Two\t\t\t\t2\t1\tTARGETDIR\t0\n";
201
202 static const char feature_comp_dat[] =
203 "Feature_\tComponent_\n"
204 "s38\ts72\n"
205 "FeatureComponents\tFeature_\tComponent_\n"
206 "One\tOne\n";
207
208 static const char file_dat[] =
209 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
210 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
211 "File\tFile\n"
212 "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n";
213
214 static const char install_exec_seq_dat[] =
215 "Action\tCondition\tSequence\n"
216 "s72\tS255\tI2\n"
217 "InstallExecuteSequence\tAction\n"
218 "ValidateProductID\t\t700\n"
219 "CostInitialize\t\t800\n"
220 "FileCost\t\t900\n"
221 "CostFinalize\t\t1000\n"
222 "InstallValidate\t\t1400\n"
223 "InstallInitialize\t\t1500\n"
224 "ProcessComponents\t\t1600\n"
225 "UnpublishFeatures\t\t1800\n"
226 "RemoveFiles\t\t3500\n"
227 "InstallFiles\t\t4000\n"
228 "RegisterProduct\t\t6100\n"
229 "PublishFeatures\t\t6300\n"
230 "PublishProduct\t\t6400\n"
231 "InstallFinalize\t\t6600";
232
233 static const char media_dat[] =
234 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
235 "i2\ti4\tL64\tS255\tS32\tS72\n"
236 "Media\tDiskId\n"
237 "1\t1\t\t\tDISK1\t\n";
238
239 static const char property_dat[] =
240 "Property\tValue\n"
241 "s72\tl0\n"
242 "Property\tProperty\n"
243 "INSTALLLEVEL\t3\n"
244 "Manufacturer\tWine\n"
245 "ProductCode\t{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}\n"
246 "ProductName\tMSITEST\n"
247 "ProductVersion\t1.1.1\n"
248 "UpgradeCode\t{9574448F-9B86-4E07-B6F6-8D199DA12127}\n"
249 "MSIFASTINSTALL\t1\n";
250
251 static const char mcp_component_dat[] =
252 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
253 "s72\tS38\ts72\ti2\tS255\tS72\n"
254 "Component\tComponent\n"
255 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
256 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
257 "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
258
259 static const char mcp_feature_dat[] =
260 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
261 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
262 "Feature\tFeature\n"
263 "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
264 "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
265 "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
266
267 static const char mcp_feature_comp_dat[] =
268 "Feature_\tComponent_\n"
269 "s38\ts72\n"
270 "FeatureComponents\tFeature_\tComponent_\n"
271 "hydroxyl\thydrogen\n"
272 "heliox\thelium\n"
273 "lithia\tlithium";
274
275 static const CHAR mcp_file_dat[] =
276 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
277 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
278 "File\tFile\n"
279 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
280 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
281 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
282
283 typedef struct _msi_table
284 {
285 const CHAR *filename;
286 const CHAR *data;
287 int size;
288 } msi_table;
289
290 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
291
292 static const msi_table tables[] =
293 {
294 ADD_TABLE(directory),
295 ADD_TABLE(component),
296 ADD_TABLE(feature),
297 ADD_TABLE(feature_comp),
298 ADD_TABLE(file),
299 ADD_TABLE(install_exec_seq),
300 ADD_TABLE(media),
301 ADD_TABLE(property),
302 };
303
304 static const msi_table mcp_tables[] =
305 {
306 ADD_TABLE(directory),
307 ADD_TABLE(mcp_component),
308 ADD_TABLE(mcp_feature),
309 ADD_TABLE(mcp_feature_comp),
310 ADD_TABLE(mcp_file),
311 ADD_TABLE(install_exec_seq),
312 ADD_TABLE(media),
313 ADD_TABLE(property)
314 };
315
316 static void write_file(const CHAR *filename, const char *data, int data_size)
317 {
318 DWORD size;
319
320 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
321 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
322
323 WriteFile(hf, data, data_size, &size, NULL);
324 CloseHandle(hf);
325 }
326
327 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
328 {
329 MSIHANDLE summary;
330 UINT r;
331
332 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
334
335 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
336 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
337
338 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
339 "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
341
342 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
344
345 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
347
348 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
349 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
350
351 /* write the summary changes back to the stream */
352 r = MsiSummaryInfoPersist(summary);
353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
354
355 MsiCloseHandle(summary);
356 }
357
358 #define create_database(name, tables, num_tables) \
359 create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
360
361 #define create_database_template(name, tables, num_tables, version, template) \
362 create_database_wordcount(name, tables, num_tables, version, 0, template);
363
364 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
365 int num_tables, INT version, INT wordcount,
366 const char *template)
367 {
368 MSIHANDLE db;
369 UINT r;
370 int j;
371
372 r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
373 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
374
375 /* import the tables into the database */
376 for (j = 0; j < num_tables; j++)
377 {
378 const msi_table *table = &tables[j];
379
380 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
381
382 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
384
385 DeleteFileA(table->filename);
386 }
387
388 write_msi_summary_info(db, version, wordcount, template);
389
390 r = MsiDatabaseCommit(db);
391 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
392
393 MsiCloseHandle(db);
394 }
395
396 static UINT run_query(MSIHANDLE hdb, const char *query)
397 {
398 MSIHANDLE hview = 0;
399 UINT r;
400
401 r = MsiDatabaseOpenView(hdb, query, &hview);
402 if (r != ERROR_SUCCESS)
403 return r;
404
405 r = MsiViewExecute(hview, 0);
406 if (r == ERROR_SUCCESS)
407 r = MsiViewClose(hview);
408 MsiCloseHandle(hview);
409 return r;
410 }
411
412 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
413 {
414 UINT res;
415 MSIHANDLE suminfo;
416
417 /* build summary info */
418 res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
419 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
420
421 res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
422 "Installation Database");
423 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
424
425 res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
426 "Installation Database");
427 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
428
429 res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
430 "Wine Hackers");
431 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
432
433 res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
434 ";1033");
435 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
436
437 res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
438 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
439 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
440
441 res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
442 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
443
444 res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
445 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
446
447 res = MsiSummaryInfoPersist(suminfo);
448 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
449
450 res = MsiCloseHandle(suminfo);
451 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
452
453 return res;
454 }
455
456 static MSIHANDLE create_package_db(LPSTR prodcode)
457 {
458 MSIHANDLE hdb = 0;
459 CHAR query[MAX_PATH];
460 UINT res;
461
462 DeleteFile(msifile);
463
464 /* create an empty database */
465 res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
466 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
467 if (res != ERROR_SUCCESS)
468 return hdb;
469
470 res = MsiDatabaseCommit(hdb);
471 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
472
473 set_summary_info(hdb, prodcode);
474
475 res = run_query(hdb,
476 "CREATE TABLE `Directory` ( "
477 "`Directory` CHAR(255) NOT NULL, "
478 "`Directory_Parent` CHAR(255), "
479 "`DefaultDir` CHAR(255) NOT NULL "
480 "PRIMARY KEY `Directory`)");
481 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
482
483 res = run_query(hdb,
484 "CREATE TABLE `Property` ( "
485 "`Property` CHAR(72) NOT NULL, "
486 "`Value` CHAR(255) "
487 "PRIMARY KEY `Property`)");
488 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
489
490 sprintf(query, "INSERT INTO `Property` "
491 "(`Property`, `Value`) "
492 "VALUES( 'ProductCode', '%s' )", prodcode);
493 res = run_query(hdb, query);
494 ok(res == ERROR_SUCCESS , "Failed\n");
495
496 res = MsiDatabaseCommit(hdb);
497 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
498
499 return hdb;
500 }
501
502 static void test_usefeature(void)
503 {
504 INSTALLSTATE r;
505
506 if (!pMsiUseFeatureExA)
507 {
508 win_skip("MsiUseFeatureExA not implemented\n");
509 return;
510 }
511
512 r = MsiQueryFeatureState(NULL,NULL);
513 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
514
515 r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
516 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
517
518 r = pMsiUseFeatureExA(NULL,NULL,0,0);
519 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
520
521 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
522 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
523
524 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
525 NULL, -2, 0 );
526 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
527
528 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
529 "WORDVIEWFiles", -2, 0 );
530 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
531
532 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
533 "WORDVIEWFiles", -2, 0 );
534 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
535
536 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
537 "WORDVIEWFiles", -2, 1 );
538 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
539 }
540
541 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
542 {
543 if (pRegDeleteKeyExA)
544 return pRegDeleteKeyExA( key, subkey, access, 0 );
545 return RegDeleteKeyA( key, subkey );
546 }
547
548 static void test_null(void)
549 {
550 MSIHANDLE hpkg;
551 UINT r;
552 HKEY hkey;
553 DWORD dwType, cbData;
554 LPBYTE lpData = NULL;
555 INSTALLSTATE state;
556 REGSAM access = KEY_ALL_ACCESS;
557
558 if (is_wow64)
559 access |= KEY_WOW64_64KEY;
560
561 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
562 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
563
564 state = MsiQueryProductStateW(NULL);
565 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
566
567 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
568 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
569
570 r = MsiConfigureFeatureW(NULL, NULL, 0);
571 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
572
573 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
574 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
575
576 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
577 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
578
579 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
580 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
581
582 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
583 * necessary registry values */
584
585 /* empty product string */
586 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
587 if (r == ERROR_ACCESS_DENIED)
588 {
589 skip("Not enough rights to perform tests\n");
590 return;
591 }
592 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
593
594 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
595 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
596 if ( r == ERROR_SUCCESS )
597 {
598 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
599 if (!lpData)
600 skip("Out of memory\n");
601 else
602 {
603 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
604 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
605 }
606 }
607
608 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
609 if (r == ERROR_ACCESS_DENIED)
610 {
611 skip("Not enough rights to perform tests\n");
612 HeapFree(GetProcessHeap(), 0, lpData);
613 RegCloseKey(hkey);
614 return;
615 }
616 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
617
618 r = MsiGetProductInfoA("", "", NULL, NULL);
619 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
620
621 if (lpData)
622 {
623 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
624 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
625
626 HeapFree(GetProcessHeap(), 0, lpData);
627 }
628 else
629 {
630 r = RegDeleteValueA(hkey, NULL);
631 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
632 }
633
634 r = RegCloseKey(hkey);
635 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
636
637 /* empty attribute */
638 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
639 0, NULL, 0, access, NULL, &hkey, NULL);
640 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
641
642 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
643 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
644
645 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
646 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
647
648 r = RegCloseKey(hkey);
649 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
650
651 r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
652 access & KEY_WOW64_64KEY);
653 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
654 }
655
656 static void test_getcomponentpath(void)
657 {
658 INSTALLSTATE r;
659 char buffer[0x100];
660 DWORD sz;
661
662 if(!pMsiGetComponentPathA)
663 return;
664
665 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
666 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
667
668 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
669 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
670
671 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
672 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
673
674 sz = sizeof buffer;
675 buffer[0]=0;
676 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
677 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
678
679 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
680 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
681 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
682
683 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
684 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
685 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
686
687 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
688 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
689 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
690
691 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
692 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
693 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
694 }
695
696 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
697 {
698 HANDLE file;
699 DWORD written;
700
701 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
702 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
703 WriteFile(file, data, strlen(data), &written, NULL);
704
705 if (size)
706 {
707 SetFilePointer(file, size, NULL, FILE_BEGIN);
708 SetEndOfFile(file);
709 }
710
711 CloseHandle(file);
712 }
713
714 #define HASHSIZE sizeof(MSIFILEHASHINFO)
715
716 static const struct
717 {
718 LPCSTR data;
719 DWORD size;
720 MSIFILEHASHINFO hash;
721 } hash_data[] =
722 {
723 { "", 0,
724 { HASHSIZE,
725 { 0, 0, 0, 0 },
726 },
727 },
728
729 { "abc", 0,
730 { HASHSIZE,
731 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
732 },
733 },
734
735 { "C:\\Program Files\\msitest\\caesar\n", 0,
736 { HASHSIZE,
737 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
738 },
739 },
740
741 { "C:\\Program Files\\msitest\\caesar\n", 500,
742 { HASHSIZE,
743 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
744 },
745 },
746 };
747
748 static void test_MsiGetFileHash(void)
749 {
750 const char name[] = "msitest.bin";
751 UINT r;
752 MSIFILEHASHINFO hash;
753 DWORD i;
754
755 if (!pMsiGetFileHashA)
756 {
757 win_skip("MsiGetFileHash not implemented\n");
758 return;
759 }
760
761 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
762
763 /* szFilePath is NULL */
764 r = pMsiGetFileHashA(NULL, 0, &hash);
765 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
766
767 /* szFilePath is empty */
768 r = pMsiGetFileHashA("", 0, &hash);
769 ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
770 "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
771
772 /* szFilePath is nonexistent */
773 r = pMsiGetFileHashA(name, 0, &hash);
774 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
775
776 /* dwOptions is non-zero */
777 r = pMsiGetFileHashA(name, 1, &hash);
778 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
779
780 /* pHash.dwFileHashInfoSize is not correct */
781 hash.dwFileHashInfoSize = 0;
782 r = pMsiGetFileHashA(name, 0, &hash);
783 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
784
785 /* pHash is NULL */
786 r = pMsiGetFileHashA(name, 0, NULL);
787 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
788
789 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
790 {
791 int ret;
792
793 create_file(name, hash_data[i].data, hash_data[i].size);
794
795 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
796 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
797
798 r = pMsiGetFileHashA(name, 0, &hash);
799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
800
801 ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
802 ok(!ret, "Hash incorrect\n");
803
804 DeleteFile(name);
805 }
806 }
807
808 /* copied from dlls/msi/registry.c */
809 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
810 {
811 DWORD i,n=1;
812 GUID guid;
813
814 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
815 return FALSE;
816
817 for(i=0; i<8; i++)
818 out[7-i] = in[n++];
819 n++;
820 for(i=0; i<4; i++)
821 out[11-i] = in[n++];
822 n++;
823 for(i=0; i<4; i++)
824 out[15-i] = in[n++];
825 n++;
826 for(i=0; i<2; i++)
827 {
828 out[17+i*2] = in[n++];
829 out[16+i*2] = in[n++];
830 }
831 n++;
832 for( ; i<8; i++)
833 {
834 out[17+i*2] = in[n++];
835 out[16+i*2] = in[n++];
836 }
837 out[32]=0;
838 return TRUE;
839 }
840
841 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
842 {
843 WCHAR guidW[MAX_PATH];
844 WCHAR squashedW[MAX_PATH];
845 GUID guid;
846 HRESULT hr;
847 int size;
848
849 hr = CoCreateGuid(&guid);
850 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
851
852 size = StringFromGUID2(&guid, guidW, MAX_PATH);
853 ok(size == 39, "Expected 39, got %d\n", hr);
854
855 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
856 if (squashed)
857 {
858 squash_guid(guidW, squashedW);
859 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
860 }
861 }
862
863 static char *get_user_sid(void)
864 {
865 HANDLE token;
866 DWORD size = 0;
867 TOKEN_USER *user;
868 char *usersid = NULL;
869
870 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
871 GetTokenInformation(token, TokenUser, NULL, size, &size);
872
873 user = HeapAlloc(GetProcessHeap(), 0, size);
874 GetTokenInformation(token, TokenUser, user, size, &size);
875 pConvertSidToStringSidA(user->User.Sid, &usersid);
876 HeapFree(GetProcessHeap(), 0, user);
877
878 CloseHandle(token);
879 return usersid;
880 }
881
882 static void test_MsiQueryProductState(void)
883 {
884 CHAR prodcode[MAX_PATH];
885 CHAR prod_squashed[MAX_PATH];
886 CHAR keypath[MAX_PATH*2];
887 LPSTR usersid;
888 INSTALLSTATE state;
889 LONG res;
890 HKEY userkey, localkey, props;
891 HKEY prodkey;
892 DWORD data, error;
893 REGSAM access = KEY_ALL_ACCESS;
894
895 create_test_guid(prodcode, prod_squashed);
896 usersid = get_user_sid();
897
898 if (is_wow64)
899 access |= KEY_WOW64_64KEY;
900
901 /* NULL prodcode */
902 SetLastError(0xdeadbeef);
903 state = MsiQueryProductStateA(NULL);
904 error = GetLastError();
905 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
906 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
907
908 /* empty prodcode */
909 SetLastError(0xdeadbeef);
910 state = MsiQueryProductStateA("");
911 error = GetLastError();
912 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
913 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
914
915 /* garbage prodcode */
916 SetLastError(0xdeadbeef);
917 state = MsiQueryProductStateA("garbage");
918 error = GetLastError();
919 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
920 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
921
922 /* guid without brackets */
923 SetLastError(0xdeadbeef);
924 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
925 error = GetLastError();
926 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
927 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
928
929 /* guid with brackets */
930 SetLastError(0xdeadbeef);
931 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
932 error = GetLastError();
933 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
934 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
935 "expected ERROR_SUCCESS, got %u\n", error);
936
937 /* same length as guid, but random */
938 SetLastError(0xdeadbeef);
939 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
940 error = GetLastError();
941 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
942 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
943
944 /* MSIINSTALLCONTEXT_USERUNMANAGED */
945
946 SetLastError(0xdeadbeef);
947 state = MsiQueryProductStateA(prodcode);
948 error = GetLastError();
949 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
950 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
951 "expected ERROR_SUCCESS, got %u\n", error);
952
953 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
954 lstrcatA(keypath, prod_squashed);
955
956 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
958
959 /* user product key exists */
960 SetLastError(0xdeadbeef);
961 state = MsiQueryProductStateA(prodcode);
962 error = GetLastError();
963 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
964 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
965 "expected ERROR_SUCCESS, got %u\n", error);
966
967 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
968 lstrcatA(keypath, prodcode);
969
970 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
971 if (res == ERROR_ACCESS_DENIED)
972 {
973 skip("Not enough rights to perform tests\n");
974 RegDeleteKeyA(userkey, "");
975 LocalFree(usersid);
976 return;
977 }
978 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
979
980 /* local uninstall key exists */
981 SetLastError(0xdeadbeef);
982 state = MsiQueryProductStateA(prodcode);
983 error = GetLastError();
984 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
985 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
986 "expected ERROR_SUCCESS, got %u\n", error);
987
988 data = 1;
989 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
990 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
991
992 /* WindowsInstaller value exists */
993 SetLastError(0xdeadbeef);
994 state = MsiQueryProductStateA(prodcode);
995 error = GetLastError();
996 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
997 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
998 "expected ERROR_SUCCESS, got %u\n", error);
999
1000 RegDeleteValueA(localkey, "WindowsInstaller");
1001 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1002
1003 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1004 lstrcatA(keypath, usersid);
1005 lstrcatA(keypath, "\\Products\\");
1006 lstrcatA(keypath, prod_squashed);
1007
1008 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1009 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1010
1011 /* local product key exists */
1012 SetLastError(0xdeadbeef);
1013 state = MsiQueryProductStateA(prodcode);
1014 error = GetLastError();
1015 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1016 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1017 "expected ERROR_SUCCESS, got %u\n", error);
1018
1019 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1020 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1021
1022 /* install properties key exists */
1023 SetLastError(0xdeadbeef);
1024 state = MsiQueryProductStateA(prodcode);
1025 error = GetLastError();
1026 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1027 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1028 "expected ERROR_SUCCESS, got %u\n", error);
1029
1030 data = 1;
1031 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1032 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1033
1034 /* WindowsInstaller value exists */
1035 SetLastError(0xdeadbeef);
1036 state = MsiQueryProductStateA(prodcode);
1037 error = GetLastError();
1038 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1039 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1040 "expected ERROR_SUCCESS, got %u\n", error);
1041
1042 data = 2;
1043 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1044 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1045
1046 /* WindowsInstaller value is not 1 */
1047 SetLastError(0xdeadbeef);
1048 state = MsiQueryProductStateA(prodcode);
1049 error = GetLastError();
1050 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1051 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1052 "expected ERROR_SUCCESS, got %u\n", error);
1053
1054 RegDeleteKeyA(userkey, "");
1055
1056 /* user product key does not exist */
1057 SetLastError(0xdeadbeef);
1058 state = MsiQueryProductStateA(prodcode);
1059 error = GetLastError();
1060 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1061 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1062 "expected ERROR_SUCCESS, got %u\n", error);
1063
1064 RegDeleteValueA(props, "WindowsInstaller");
1065 delete_key(props, "", access & KEY_WOW64_64KEY);
1066 RegCloseKey(props);
1067 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1068 RegCloseKey(localkey);
1069 RegDeleteKeyA(userkey, "");
1070 RegCloseKey(userkey);
1071
1072 /* MSIINSTALLCONTEXT_USERMANAGED */
1073
1074 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1075 lstrcatA(keypath, usersid);
1076 lstrcatA(keypath, "\\Installer\\Products\\");
1077 lstrcatA(keypath, prod_squashed);
1078
1079 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1080 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1081
1082 state = MsiQueryProductStateA(prodcode);
1083 ok(state == INSTALLSTATE_ADVERTISED,
1084 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1085
1086 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1087 lstrcatA(keypath, usersid);
1088 lstrcatA(keypath, "\\Products\\");
1089 lstrcatA(keypath, prod_squashed);
1090
1091 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1092 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1093
1094 state = MsiQueryProductStateA(prodcode);
1095 ok(state == INSTALLSTATE_ADVERTISED,
1096 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1097
1098 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1099 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1100
1101 state = MsiQueryProductStateA(prodcode);
1102 ok(state == INSTALLSTATE_ADVERTISED,
1103 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1104
1105 data = 1;
1106 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1107 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1108
1109 /* WindowsInstaller value exists */
1110 state = MsiQueryProductStateA(prodcode);
1111 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1112
1113 RegDeleteValueA(props, "WindowsInstaller");
1114 delete_key(props, "", access & KEY_WOW64_64KEY);
1115 RegCloseKey(props);
1116 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1117 RegCloseKey(localkey);
1118 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1119 RegCloseKey(prodkey);
1120
1121 /* MSIINSTALLCONTEXT_MACHINE */
1122
1123 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1124 lstrcatA(keypath, prod_squashed);
1125
1126 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1127 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1128
1129 state = MsiQueryProductStateA(prodcode);
1130 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1131
1132 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1133 lstrcatA(keypath, "S-1-5-18\\Products\\");
1134 lstrcatA(keypath, prod_squashed);
1135
1136 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1137 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1138
1139 state = MsiQueryProductStateA(prodcode);
1140 ok(state == INSTALLSTATE_ADVERTISED,
1141 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1142
1143 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1144 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1145
1146 state = MsiQueryProductStateA(prodcode);
1147 ok(state == INSTALLSTATE_ADVERTISED,
1148 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1149
1150 data = 1;
1151 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1152 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1153
1154 /* WindowsInstaller value exists */
1155 state = MsiQueryProductStateA(prodcode);
1156 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1157
1158 RegDeleteValueA(props, "WindowsInstaller");
1159 delete_key(props, "", access & KEY_WOW64_64KEY);
1160 RegCloseKey(props);
1161 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1162 RegCloseKey(localkey);
1163 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1164 RegCloseKey(prodkey);
1165
1166 LocalFree(usersid);
1167 }
1168
1169 static const char table_enc85[] =
1170 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
1171 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
1172 "yz{}~";
1173
1174 /*
1175 * Encodes a base85 guid given a GUID pointer
1176 * Caller should provide a 21 character buffer for the encoded string.
1177 */
1178 static void encode_base85_guid( GUID *guid, LPWSTR str )
1179 {
1180 unsigned int x, *p, i;
1181
1182 p = (unsigned int*) guid;
1183 for( i=0; i<4; i++ )
1184 {
1185 x = p[i];
1186 *str++ = table_enc85[x%85];
1187 x = x/85;
1188 *str++ = table_enc85[x%85];
1189 x = x/85;
1190 *str++ = table_enc85[x%85];
1191 x = x/85;
1192 *str++ = table_enc85[x%85];
1193 x = x/85;
1194 *str++ = table_enc85[x%85];
1195 }
1196 *str = 0;
1197 }
1198
1199 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
1200 {
1201 WCHAR guidW[MAX_PATH];
1202 WCHAR base85W[MAX_PATH];
1203 WCHAR squashedW[MAX_PATH];
1204 GUID guid;
1205 HRESULT hr;
1206 int size;
1207
1208 hr = CoCreateGuid(&guid);
1209 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1210
1211 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1212 ok(size == 39, "Expected 39, got %d\n", hr);
1213
1214 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1215 encode_base85_guid(&guid, base85W);
1216 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1217 squash_guid(guidW, squashedW);
1218 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1219 }
1220
1221 static void test_MsiQueryFeatureState(void)
1222 {
1223 HKEY userkey, localkey, compkey, compkey2;
1224 CHAR prodcode[MAX_PATH];
1225 CHAR prod_squashed[MAX_PATH];
1226 CHAR component[MAX_PATH];
1227 CHAR comp_base85[MAX_PATH];
1228 CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
1229 CHAR keypath[MAX_PATH*2];
1230 INSTALLSTATE state;
1231 LPSTR usersid;
1232 LONG res;
1233 REGSAM access = KEY_ALL_ACCESS;
1234 DWORD error;
1235
1236 create_test_guid(prodcode, prod_squashed);
1237 compose_base85_guid(component, comp_base85, comp_squashed);
1238 compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
1239 usersid = get_user_sid();
1240
1241 if (is_wow64)
1242 access |= KEY_WOW64_64KEY;
1243
1244 /* NULL prodcode */
1245 SetLastError(0xdeadbeef);
1246 state = MsiQueryFeatureStateA(NULL, "feature");
1247 error = GetLastError();
1248 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1249 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1250
1251 /* empty prodcode */
1252 SetLastError(0xdeadbeef);
1253 state = MsiQueryFeatureStateA("", "feature");
1254 error = GetLastError();
1255 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1256 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1257
1258 /* garbage prodcode */
1259 SetLastError(0xdeadbeef);
1260 state = MsiQueryFeatureStateA("garbage", "feature");
1261 error = GetLastError();
1262 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1263 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1264
1265 /* guid without brackets */
1266 SetLastError(0xdeadbeef);
1267 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
1268 error = GetLastError();
1269 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1270 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1271
1272 /* guid with brackets */
1273 SetLastError(0xdeadbeef);
1274 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
1275 error = GetLastError();
1276 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1277 ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
1278 "expected ERROR_SUCCESS, got %u\n", error);
1279
1280 /* same length as guid, but random */
1281 SetLastError(0xdeadbeef);
1282 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
1283 error = GetLastError();
1284 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1285 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1286
1287 /* NULL szFeature */
1288 SetLastError(0xdeadbeef);
1289 state = MsiQueryFeatureStateA(prodcode, NULL);
1290 error = GetLastError();
1291 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1292 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1293
1294 /* empty szFeature */
1295 SetLastError(0xdeadbeef);
1296 state = MsiQueryFeatureStateA(prodcode, "");
1297 error = GetLastError();
1298 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1299 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1300 "expected ERROR_SUCCESS, got %u\n", error);
1301
1302 /* feature key does not exist yet */
1303 SetLastError(0xdeadbeef);
1304 state = MsiQueryFeatureStateA(prodcode, "feature");
1305 error = GetLastError();
1306 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1307 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1308 "expected ERROR_SUCCESS, got %u\n", error);
1309
1310 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1311
1312 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
1313 lstrcatA(keypath, prod_squashed);
1314
1315 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1316 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1317
1318 /* feature key exists */
1319 SetLastError(0xdeadbeef);
1320 state = MsiQueryFeatureStateA(prodcode, "feature");
1321 error = GetLastError();
1322 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1323 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1324 "expected ERROR_SUCCESS, got %u\n", error);
1325
1326 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1327 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1328
1329 /* feature value exists */
1330 SetLastError(0xdeadbeef);
1331 state = MsiQueryFeatureStateA(prodcode, "feature");
1332 error = GetLastError();
1333 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1334 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1335 "expected ERROR_SUCCESS, got %u\n", error);
1336
1337 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1338 lstrcatA(keypath, usersid);
1339 lstrcatA(keypath, "\\Products\\");
1340 lstrcatA(keypath, prod_squashed);
1341 lstrcatA(keypath, "\\Features");
1342
1343 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1344 if (res == ERROR_ACCESS_DENIED)
1345 {
1346 skip("Not enough rights to perform tests\n");
1347 RegDeleteKeyA(userkey, "");
1348 RegCloseKey(userkey);
1349 LocalFree(usersid);
1350 return;
1351 }
1352 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1353
1354 /* userdata features key exists */
1355 SetLastError(0xdeadbeef);
1356 state = MsiQueryFeatureStateA(prodcode, "feature");
1357 error = GetLastError();
1358 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1359 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1360 "expected ERROR_SUCCESS, got %u\n", error);
1361
1362 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1363 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1364
1365 SetLastError(0xdeadbeef);
1366 state = MsiQueryFeatureStateA(prodcode, "feature");
1367 error = GetLastError();
1368 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1369 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1370 "expected ERROR_SUCCESS, got %u\n", error);
1371
1372 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1373 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1374
1375 SetLastError(0xdeadbeef);
1376 state = MsiQueryFeatureStateA(prodcode, "feature");
1377 error = GetLastError();
1378 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1379 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1380 "expected ERROR_SUCCESS, got %u\n", error);
1381
1382 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1383 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1384
1385 SetLastError(0xdeadbeef);
1386 state = MsiQueryFeatureStateA(prodcode, "feature");
1387 error = GetLastError();
1388 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1389 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1390 "expected ERROR_SUCCESS, got %u\n", error);
1391
1392 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1393 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1394
1395 SetLastError(0xdeadbeef);
1396 state = MsiQueryFeatureStateA(prodcode, "feature");
1397 error = GetLastError();
1398 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1399 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1400 "expected ERROR_SUCCESS, got %u\n", error);
1401
1402 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1403 lstrcatA(keypath, usersid);
1404 lstrcatA(keypath, "\\Components\\");
1405 lstrcatA(keypath, comp_squashed);
1406
1407 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1408 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1409
1410 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1411 lstrcatA(keypath, usersid);
1412 lstrcatA(keypath, "\\Components\\");
1413 lstrcatA(keypath, comp_squashed2);
1414
1415 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1416 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1417
1418 SetLastError(0xdeadbeef);
1419 state = MsiQueryFeatureStateA(prodcode, "feature");
1420 error = GetLastError();
1421 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1422 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1423 "expected ERROR_SUCCESS, got %u\n", error);
1424
1425 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1426 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1427
1428 SetLastError(0xdeadbeef);
1429 state = MsiQueryFeatureStateA(prodcode, "feature");
1430 error = GetLastError();
1431 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1432 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1433 "expected ERROR_SUCCESS, got %u\n", error);
1434
1435 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1436 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1437
1438 SetLastError(0xdeadbeef);
1439 state = MsiQueryFeatureStateA(prodcode, "feature");
1440 error = GetLastError();
1441 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1442 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1443 "expected ERROR_SUCCESS, got %u\n", error);
1444
1445 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1446 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1447
1448 /* INSTALLSTATE_LOCAL */
1449 SetLastError(0xdeadbeef);
1450 state = MsiQueryFeatureStateA(prodcode, "feature");
1451 error = GetLastError();
1452 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1453 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1454 "expected ERROR_SUCCESS, got %u\n", error);
1455
1456 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1458
1459 /* INSTALLSTATE_SOURCE */
1460 SetLastError(0xdeadbeef);
1461 state = MsiQueryFeatureStateA(prodcode, "feature");
1462 error = GetLastError();
1463 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1464 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1465 "expected ERROR_SUCCESS, got %u\n", error);
1466
1467 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1469
1470 /* bad INSTALLSTATE_SOURCE */
1471 SetLastError(0xdeadbeef);
1472 state = MsiQueryFeatureStateA(prodcode, "feature");
1473 error = GetLastError();
1474 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1475 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1476 "expected ERROR_SUCCESS, got %u\n", error);
1477
1478 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1479 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1480
1481 /* INSTALLSTATE_SOURCE */
1482 SetLastError(0xdeadbeef);
1483 state = MsiQueryFeatureStateA(prodcode, "feature");
1484 error = GetLastError();
1485 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1486 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1487 "expected ERROR_SUCCESS, got %u\n", error);
1488
1489 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1490 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1491
1492 /* bad INSTALLSTATE_SOURCE */
1493 SetLastError(0xdeadbeef);
1494 state = MsiQueryFeatureStateA(prodcode, "feature");
1495 error = GetLastError();
1496 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1497 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1498 "expected ERROR_SUCCESS, got %u\n", error);
1499
1500 RegDeleteValueA(compkey, prod_squashed);
1501 RegDeleteValueA(compkey2, prod_squashed);
1502 delete_key(compkey, "", access & KEY_WOW64_64KEY);
1503 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1504 RegDeleteValueA(localkey, "feature");
1505 RegDeleteValueA(userkey, "feature");
1506 RegDeleteKeyA(userkey, "");
1507 RegCloseKey(compkey);
1508 RegCloseKey(compkey2);
1509 RegCloseKey(localkey);
1510 RegCloseKey(userkey);
1511
1512 /* MSIINSTALLCONTEXT_USERMANAGED */
1513
1514 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1515 lstrcatA(keypath, usersid);
1516 lstrcatA(keypath, "\\Installer\\Features\\");
1517 lstrcatA(keypath, prod_squashed);
1518
1519 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1520 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1521
1522 /* feature key exists */
1523 state = MsiQueryFeatureStateA(prodcode, "feature");
1524 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1525
1526 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1527 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1528
1529 /* feature value exists */
1530 state = MsiQueryFeatureStateA(prodcode, "feature");
1531 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1532
1533 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1534 lstrcatA(keypath, usersid);
1535 lstrcatA(keypath, "\\Products\\");
1536 lstrcatA(keypath, prod_squashed);
1537 lstrcatA(keypath, "\\Features");
1538
1539 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1540 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1541
1542 /* userdata features key exists */
1543 state = MsiQueryFeatureStateA(prodcode, "feature");
1544 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1545
1546 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1547 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1548
1549 state = MsiQueryFeatureStateA(prodcode, "feature");
1550 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1551
1552 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1553 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1554
1555 state = MsiQueryFeatureStateA(prodcode, "feature");
1556 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1557
1558 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1560
1561 state = MsiQueryFeatureStateA(prodcode, "feature");
1562 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1563
1564 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1565 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1566
1567 state = MsiQueryFeatureStateA(prodcode, "feature");
1568 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1569
1570 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1571 lstrcatA(keypath, usersid);
1572 lstrcatA(keypath, "\\Components\\");
1573 lstrcatA(keypath, comp_squashed);
1574
1575 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1576 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1577
1578 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1579 lstrcatA(keypath, usersid);
1580 lstrcatA(keypath, "\\Components\\");
1581 lstrcatA(keypath, comp_squashed2);
1582
1583 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1584 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1585
1586 state = MsiQueryFeatureStateA(prodcode, "feature");
1587 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1588
1589 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1590 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1591
1592 state = MsiQueryFeatureStateA(prodcode, "feature");
1593 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1594
1595 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1596 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1597
1598 state = MsiQueryFeatureStateA(prodcode, "feature");
1599 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1600
1601 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1602 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1603
1604 state = MsiQueryFeatureStateA(prodcode, "feature");
1605 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1606
1607 RegDeleteValueA(compkey, prod_squashed);
1608 RegDeleteValueA(compkey2, prod_squashed);
1609 delete_key(compkey, "", access & KEY_WOW64_64KEY);
1610 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1611 RegDeleteValueA(localkey, "feature");
1612 RegDeleteValueA(userkey, "feature");
1613 delete_key(userkey, "", access & KEY_WOW64_64KEY);
1614 RegCloseKey(compkey);
1615 RegCloseKey(compkey2);
1616 RegCloseKey(localkey);
1617 RegCloseKey(userkey);
1618
1619 /* MSIINSTALLCONTEXT_MACHINE */
1620
1621 lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1622 lstrcatA(keypath, prod_squashed);
1623
1624 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1625 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1626
1627 /* feature key exists */
1628 state = MsiQueryFeatureStateA(prodcode, "feature");
1629 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1630
1631 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1632 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1633
1634 /* feature value exists */
1635 state = MsiQueryFeatureStateA(prodcode, "feature");
1636 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1637
1638 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1639 lstrcatA(keypath, "S-1-5-18\\Products\\");
1640 lstrcatA(keypath, prod_squashed);
1641 lstrcatA(keypath, "\\Features");
1642
1643 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1644 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1645
1646 /* userdata features key exists */
1647 state = MsiQueryFeatureStateA(prodcode, "feature");
1648 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1649
1650 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1651 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1652
1653 state = MsiQueryFeatureStateA(prodcode, "feature");
1654 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1655
1656 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1657 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1658
1659 state = MsiQueryFeatureStateA(prodcode, "feature");
1660 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1661
1662 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1664
1665 state = MsiQueryFeatureStateA(prodcode, "feature");
1666 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1667
1668 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1669 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1670
1671 state = MsiQueryFeatureStateA(prodcode, "feature");
1672 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1673
1674 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1675 lstrcatA(keypath, "S-1-5-18\\Components\\");
1676 lstrcatA(keypath, comp_squashed);
1677
1678 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1679 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1680
1681 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1682 lstrcatA(keypath, "S-1-5-18\\Components\\");
1683 lstrcatA(keypath, comp_squashed2);
1684
1685 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1686 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1687
1688 state = MsiQueryFeatureStateA(prodcode, "feature");
1689 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1690
1691 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1692 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1693
1694 state = MsiQueryFeatureStateA(prodcode, "feature");
1695 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1696
1697 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1698 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1699
1700 state = MsiQueryFeatureStateA(prodcode, "feature");
1701 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1702
1703 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1704 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1705
1706 state = MsiQueryFeatureStateA(prodcode, "feature");
1707 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1708
1709 RegDeleteValueA(compkey, prod_squashed);
1710 RegDeleteValueA(compkey2, prod_squashed);
1711 delete_key(compkey, "", access & KEY_WOW64_64KEY);
1712 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1713 RegDeleteValueA(localkey, "feature");
1714 RegDeleteValueA(userkey, "feature");
1715 delete_key(userkey, "", access & KEY_WOW64_64KEY);
1716 RegCloseKey(compkey);
1717 RegCloseKey(compkey2);
1718 RegCloseKey(localkey);
1719 RegCloseKey(userkey);
1720 LocalFree(usersid);
1721 }
1722
1723 static void test_MsiQueryComponentState(void)
1724 {
1725 HKEY compkey, prodkey;
1726 CHAR prodcode[MAX_PATH];
1727 CHAR prod_squashed[MAX_PATH];
1728 CHAR component[MAX_PATH];
1729 CHAR comp_base85[MAX_PATH];
1730 CHAR comp_squashed[MAX_PATH];
1731 CHAR keypath[MAX_PATH];
1732 INSTALLSTATE state;
1733 LPSTR usersid;
1734 LONG res;
1735 UINT r;
1736 REGSAM access = KEY_ALL_ACCESS;
1737 DWORD error;
1738
1739 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1740
1741 if (!pMsiQueryComponentStateA)
1742 {
1743 win_skip("MsiQueryComponentStateA not implemented\n");
1744 return;
1745 }
1746
1747 create_test_guid(prodcode, prod_squashed);
1748 compose_base85_guid(component, comp_base85, comp_squashed);
1749 usersid = get_user_sid();
1750
1751 if (is_wow64)
1752 access |= KEY_WOW64_64KEY;
1753
1754 /* NULL szProductCode */
1755 state = MAGIC_ERROR;
1756 SetLastError(0xdeadbeef);
1757 r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1758 error = GetLastError();
1759 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1760 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1761 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1762
1763 /* empty szProductCode */
1764 state = MAGIC_ERROR;
1765 SetLastError(0xdeadbeef);
1766 r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1767 error = GetLastError();
1768 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1769 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1770 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1771
1772 /* random szProductCode */
1773 state = MAGIC_ERROR;
1774 SetLastError(0xdeadbeef);
1775 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1776 error = GetLastError();
1777 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1778 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1779 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1780
1781 /* GUID-length szProductCode */
1782 state = MAGIC_ERROR;
1783 SetLastError(0xdeadbeef);
1784 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1785 error = GetLastError();
1786 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1787 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1788 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1789
1790 /* GUID-length with brackets */
1791 state = MAGIC_ERROR;
1792 SetLastError(0xdeadbeef);
1793 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1794 error = GetLastError();
1795 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1796 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1797 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1798
1799 /* actual GUID */
1800 state = MAGIC_ERROR;
1801 SetLastError(0xdeadbeef);
1802 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1803 error = GetLastError();
1804 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1805 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1806 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1807
1808 state = MAGIC_ERROR;
1809 SetLastError(0xdeadbeef);
1810 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1811 error = GetLastError();
1812 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1813 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1814 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1815
1816 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1817 lstrcatA(keypath, prod_squashed);
1818
1819 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1820 if (res == ERROR_ACCESS_DENIED)
1821 {
1822 skip("Not enough rights to perform tests\n");
1823 LocalFree(usersid);
1824 return;
1825 }
1826 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1827
1828 state = MAGIC_ERROR;
1829 SetLastError(0xdeadbeef);
1830 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1831 error = GetLastError();
1832 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1833 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1834 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1835
1836 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1837 RegCloseKey(prodkey);
1838
1839 /* create local system product key */
1840 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1841 lstrcatA(keypath, prod_squashed);
1842 lstrcatA(keypath, "\\InstallProperties");
1843
1844 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1845 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1846
1847 /* local system product key exists */
1848 state = MAGIC_ERROR;
1849 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1850 error = GetLastError();
1851 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1852 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1853 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1854
1855 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1857
1858 /* LocalPackage value exists */
1859 state = MAGIC_ERROR;
1860 SetLastError(0xdeadbeef);
1861 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1862 error = GetLastError();
1863 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1864 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1865 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1866
1867 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1868 lstrcatA(keypath, comp_squashed);
1869
1870 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1871 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1872
1873 /* component key exists */
1874 state = MAGIC_ERROR;
1875 SetLastError(0xdeadbeef);
1876 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1877 error = GetLastError();
1878 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1879 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1880 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1881
1882 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1883 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1884
1885 /* component\product exists */
1886 state = MAGIC_ERROR;
1887 SetLastError(0xdeadbeef);
1888 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1890 error = GetLastError();
1891 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1892 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1893 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1894
1895 /* NULL component, product exists */
1896 state = MAGIC_ERROR;
1897 SetLastError(0xdeadbeef);
1898 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1899 error = GetLastError();
1900 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1901 ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1902 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1903
1904 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1905 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1906
1907 /* INSTALLSTATE_LOCAL */
1908 state = MAGIC_ERROR;
1909 SetLastError(0xdeadbeef);
1910 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1911 error = GetLastError();
1912 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1913 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1914 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1915
1916 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1917 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1918
1919 /* INSTALLSTATE_SOURCE */
1920 state = MAGIC_ERROR;
1921 SetLastError(0xdeadbeef);
1922 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1923 error = GetLastError();
1924 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1925 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1926 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1927
1928 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1929 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1930
1931 /* bad INSTALLSTATE_SOURCE */
1932 state = MAGIC_ERROR;
1933 SetLastError(0xdeadbeef);
1934 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1935 error = GetLastError();
1936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1937 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1938 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1939
1940 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1941 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1942
1943 /* INSTALLSTATE_SOURCE */
1944 state = MAGIC_ERROR;
1945 SetLastError(0xdeadbeef);
1946 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1947 error = GetLastError();
1948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1949 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1950 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1951
1952 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
1953 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1954
1955 /* registry component */
1956 state = MAGIC_ERROR;
1957 SetLastError(0xdeadbeef);
1958 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1959 error = GetLastError();
1960 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1961 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1962 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1963
1964 RegDeleteValueA(prodkey, "LocalPackage");
1965 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1966 RegDeleteValueA(compkey, prod_squashed);
1967 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1968 RegCloseKey(prodkey);
1969 RegCloseKey(compkey);
1970
1971 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1972
1973 state = MAGIC_ERROR;
1974 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1975 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1976 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1977
1978 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1979 lstrcatA(keypath, prod_squashed);
1980
1981 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1982 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1983
1984 state = MAGIC_ERROR;
1985 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1986 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1987 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1988
1989 RegDeleteKeyA(prodkey, "");
1990 RegCloseKey(prodkey);
1991
1992 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1993 lstrcatA(keypath, usersid);
1994 lstrcatA(keypath, "\\Products\\");
1995 lstrcatA(keypath, prod_squashed);
1996 lstrcatA(keypath, "\\InstallProperties");
1997
1998 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1999 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2000
2001 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2002 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2003
2004 RegCloseKey(prodkey);
2005
2006 state = MAGIC_ERROR;
2007 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2008 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2009 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2010
2011 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2012 lstrcatA(keypath, usersid);
2013 lstrcatA(keypath, "\\Components\\");
2014 lstrcatA(keypath, comp_squashed);
2015
2016 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2017 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2018
2019 /* component key exists */
2020 state = MAGIC_ERROR;
2021 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2022 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2023 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2024
2025 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2026 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2027
2028 /* component\product exists */
2029 state = MAGIC_ERROR;
2030 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2031 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2032 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2033 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2034
2035 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2036 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2037
2038 state = MAGIC_ERROR;
2039 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2041 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2042
2043 /* MSIINSTALLCONTEXT_USERMANAGED */
2044
2045 state = MAGIC_ERROR;
2046 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2047 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2048 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2049
2050 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2051 lstrcatA(keypath, prod_squashed);
2052
2053 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2055
2056 state = MAGIC_ERROR;
2057 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2058 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2059 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2060
2061 RegDeleteKeyA(prodkey, "");
2062 RegCloseKey(prodkey);
2063
2064 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2065 lstrcatA(keypath, usersid);
2066 lstrcatA(keypath, "\\Installer\\Products\\");
2067 lstrcatA(keypath, prod_squashed);
2068
2069 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2070 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2071
2072 state = MAGIC_ERROR;
2073 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2074 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2075 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2076
2077 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2078 RegCloseKey(prodkey);
2079
2080 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2081 lstrcatA(keypath, usersid);
2082 lstrcatA(keypath, "\\Products\\");
2083 lstrcatA(keypath, prod_squashed);
2084 lstrcatA(keypath, "\\InstallProperties");
2085
2086 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2087 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2088
2089 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2090 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2091
2092 state = MAGIC_ERROR;
2093 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2094 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2095 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2096
2097 RegDeleteValueA(prodkey, "LocalPackage");
2098 RegDeleteValueA(prodkey, "ManagedLocalPackage");
2099 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2100 RegDeleteValueA(compkey, prod_squashed);
2101 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2102 RegCloseKey(prodkey);
2103 RegCloseKey(compkey);
2104 LocalFree(usersid);
2105 }
2106
2107 static void test_MsiGetComponentPath(void)
2108 {
2109 HKEY compkey, prodkey, installprop;
2110 CHAR prodcode[MAX_PATH];
2111 CHAR prod_squashed[MAX_PATH];
2112 CHAR component[MAX_PATH];
2113 CHAR comp_base85[MAX_PATH];
2114 CHAR comp_squashed[MAX_PATH];
2115 CHAR keypath[MAX_PATH];
2116 CHAR path[MAX_PATH];
2117 INSTALLSTATE state;
2118 LPSTR usersid;
2119 DWORD size, val;
2120 REGSAM access = KEY_ALL_ACCESS;
2121 LONG res;
2122
2123 create_test_guid(prodcode, prod_squashed);
2124 compose_base85_guid(component, comp_base85, comp_squashed);
2125 usersid = get_user_sid();
2126
2127 if (is_wow64)
2128 access |= KEY_WOW64_64KEY;
2129
2130 /* NULL szProduct */
2131 size = MAX_PATH;
2132 state = MsiGetComponentPathA(NULL, component, path, &size);
2133 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2134 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2135
2136 /* NULL szComponent */
2137 size = MAX_PATH;
2138 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
2139 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2140 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2141
2142 size = MAX_PATH;
2143 state = MsiLocateComponentA(NULL, path, &size);
2144 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2145 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2146
2147 /* NULL lpPathBuf */
2148 size = MAX_PATH;
2149 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
2150 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2151 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2152
2153 size = MAX_PATH;
2154 state = MsiLocateComponentA(component, NULL, &size);
2155 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2156 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2157
2158 /* NULL pcchBuf */
2159 size = MAX_PATH;
2160 state = MsiGetComponentPathA(prodcode, component, path, NULL);
2161 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2162 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2163
2164 size = MAX_PATH;
2165 state = MsiLocateComponentA(component, path, NULL);
2166 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2167 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2168
2169 /* all params valid */
2170 size = MAX_PATH;
2171 state = MsiGetComponentPathA(prodcode, component, path, &size);
2172 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2173 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2174
2175 size = MAX_PATH;
2176 state = MsiLocateComponentA(component, path, &size);
2177 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2178 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2179
2180 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2181 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2182 lstrcatA(keypath, comp_squashed);
2183
2184 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2185 if (res == ERROR_ACCESS_DENIED)
2186 {
2187 skip("Not enough rights to perform tests\n");
2188 LocalFree(usersid);
2189 return;
2190 }
2191 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2192
2193 /* local system component key exists */
2194 size = MAX_PATH;
2195 state = MsiGetComponentPathA(prodcode, component, path, &size);
2196 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2197 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2198
2199 size = MAX_PATH;
2200 state = MsiLocateComponentA(component, path, &size);
2201 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2202 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2203
2204 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2205 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2206
2207 /* product value exists */
2208 path[0] = 0;
2209 size = MAX_PATH;
2210 state = MsiGetComponentPathA(prodcode, component, path, &size);
2211 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2212 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2213 ok(size == 10, "Expected 10, got %d\n", size);
2214
2215 path[0] = 0;
2216 size = MAX_PATH;
2217 state = MsiLocateComponentA(component, path, &size);
2218 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2219 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2220 ok(size == 10, "Expected 10, got %d\n", size);
2221
2222 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2223 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2224 lstrcatA(keypath, prod_squashed);
2225 lstrcatA(keypath, "\\InstallProperties");
2226
2227 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2228 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2229
2230 val = 1;
2231 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2232 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2233
2234 /* install properties key exists */
2235 path[0] = 0;
2236 size = MAX_PATH;
2237 state = MsiGetComponentPathA(prodcode, component, path, &size);
2238 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2239 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2240 ok(size == 10, "Expected 10, got %d\n", size);
2241
2242 path[0] = 0;
2243 size = MAX_PATH;
2244 state = MsiLocateComponentA(component, path, &size);
2245 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2246 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2247 ok(size == 10, "Expected 10, got %d\n", size);
2248
2249 create_file("C:\\imapath", "C:\\imapath", 11);
2250
2251 /* file exists */
2252 path[0] = 0;
2253 size = MAX_PATH;
2254 state = MsiGetComponentPathA(prodcode, component, path, &size);
2255 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2256 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2257 ok(size == 10, "Expected 10, got %d\n", size);
2258
2259 path[0] = 0;
2260 size = MAX_PATH;
2261 state = MsiLocateComponentA(component, path, &size);
2262 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2263 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2264 ok(size == 10, "Expected 10, got %d\n", size);
2265
2266 RegDeleteValueA(compkey, prod_squashed);
2267 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2268 RegDeleteValueA(installprop, "WindowsInstaller");
2269 delete_key(installprop, "", access & KEY_WOW64_64KEY);
2270 RegCloseKey(compkey);
2271 RegCloseKey(installprop);
2272 DeleteFileA("C:\\imapath");
2273
2274 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2275 lstrcatA(keypath, "Installer\\UserData\\");
2276 lstrcatA(keypath, usersid);
2277 lstrcatA(keypath, "\\Components\\");
2278 lstrcatA(keypath, comp_squashed);
2279
2280 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2281 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2282
2283 /* user managed component key exists */
2284 size = MAX_PATH;
2285 state = MsiGetComponentPathA(prodcode, component, path, &size);
2286 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2287 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2288
2289 size = MAX_PATH;
2290 state = MsiLocateComponentA(component, path, &size);
2291 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2292 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2293
2294 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2295 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2296
2297 /* product value exists */
2298 path[0] = 0;
2299 size = MAX_PATH;
2300 state = MsiGetComponentPathA(prodcode, component, path, &size);
2301 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2302 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2303 ok(size == 10, "Expected 10, got %d\n", size);
2304
2305 path[0] = 0;
2306 size = MAX_PATH;
2307 state = MsiLocateComponentA(component, path, &size);
2308 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2309 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2310 ok(size == 10, "Expected 10, got %d\n", size);
2311
2312 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2313 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2314 lstrcatA(keypath, prod_squashed);
2315 lstrcatA(keypath, "\\InstallProperties");
2316
2317 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2318 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2319
2320 val = 1;
2321 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2322 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2323
2324 /* install properties key exists */
2325 path[0] = 0;
2326 size = MAX_PATH;
2327 state = MsiGetComponentPathA(prodcode, component, path, &size);
2328 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2329 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2330 ok(size == 10, "Expected 10, got %d\n", size);
2331
2332 path[0] = 0;
2333 size = MAX_PATH;
2334 state = MsiLocateComponentA(component, path, &size);
2335 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2336 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2337 ok(size == 10, "Expected 10, got %d\n", size);
2338
2339 create_file("C:\\imapath", "C:\\imapath", 11);
2340
2341 /* file exists */
2342 path[0] = 0;
2343 size = MAX_PATH;
2344 state = MsiGetComponentPathA(prodcode, component, path, &size);
2345 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2346 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2347 ok(size == 10, "Expected 10, got %d\n", size);
2348
2349 path[0] = 0;
2350 size = MAX_PATH;
2351 state = MsiLocateComponentA(component, path, &size);
2352 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2353 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2354 ok(size == 10, "Expected 10, got %d\n", size);
2355
2356 RegDeleteValueA(compkey, prod_squashed);
2357 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2358 RegDeleteValueA(installprop, "WindowsInstaller");
2359 delete_key(installprop, "", access & KEY_WOW64_64KEY);
2360 RegCloseKey(compkey);
2361 RegCloseKey(installprop);
2362 DeleteFileA("C:\\imapath");
2363
2364 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2365 lstrcatA(keypath, "Installer\\Managed\\");
2366 lstrcatA(keypath, usersid);
2367 lstrcatA(keypath, "\\Installer\\Products\\");
2368 lstrcatA(keypath, prod_squashed);
2369
2370 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2372
2373 /* user managed product key exists */
2374 size = MAX_PATH;
2375 state = MsiGetComponentPathA(prodcode, component, path, &size);
2376 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2377 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2378
2379 size = MAX_PATH;
2380 state = MsiLocateComponentA(component, path, &size);
2381 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2382 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2383
2384 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2385 lstrcatA(keypath, "Installer\\UserData\\");
2386 lstrcatA(keypath, usersid);
2387 lstrcatA(keypath, "\\Components\\");
2388 lstrcatA(keypath, comp_squashed);
2389
2390 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2391 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2392
2393 /* user managed component key exists */
2394 size = MAX_PATH;
2395 state = MsiGetComponentPathA(prodcode, component, path, &size);
2396 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2397 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2398
2399 size = MAX_PATH;
2400 state = MsiLocateComponentA(component, path, &size);
2401 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2402 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2403
2404 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2405 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2406
2407 /* product value exists */
2408 path[0] = 0;
2409 size = MAX_PATH;
2410 state = MsiGetComponentPathA(prodcode, component, path, &size);
2411 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2412 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2413 ok(size == 10, "Expected 10, got %d\n", size);
2414
2415 path[0] = 0;
2416 size = MAX_PATH;
2417 state = MsiLocateComponentA(component, path, &size);
2418 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2419 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2420 ok(size == 10, "Expected 10, got %d\n", size);
2421
2422 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2423 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2424 lstrcatA(keypath, prod_squashed);
2425 lstrcatA(keypath, "\\InstallProperties");
2426
2427 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2428 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2429
2430 val = 1;
2431 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2432 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2433
2434 /* install properties key exists */
2435 path[0] = 0;
2436 size = MAX_PATH;
2437 state = MsiGetComponentPathA(prodcode, component, path, &size);
2438 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2439 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2440 ok(size == 10, "Expected 10, got %d\n", size);
2441
2442 path[0] = 0;
2443 size = MAX_PATH;
2444 state = MsiLocateComponentA(component, path, &size);
2445 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2446 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2447 ok(size == 10, "Expected 10, got %d\n", size);
2448
2449 create_file("C:\\imapath", "C:\\imapath", 11);
2450
2451 /* file exists */
2452 path[0] = 0;
2453 size = MAX_PATH;
2454 state = MsiGetComponentPathA(prodcode, component, path, &size);
2455 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2456 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2457 ok(size == 10, "Expected 10, got %d\n", size);
2458
2459 path[0] = 0;
2460 size = MAX_PATH;
2461 state = MsiLocateComponentA(component, path, &size);
2462 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2463 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2464 ok(size == 10, "Expected 10, got %d\n", size);
2465
2466 RegDeleteValueA(compkey, prod_squashed);
2467 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2468 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2469 RegDeleteValueA(installprop, "WindowsInstaller");
2470 delete_key(installprop, "", access & KEY_WOW64_64KEY);
2471 RegCloseKey(prodkey);
2472 RegCloseKey(compkey);
2473 RegCloseKey(installprop);
2474 DeleteFileA("C:\\imapath");
2475
2476 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2477 lstrcatA(keypath, prod_squashed);
2478
2479 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2481
2482 /* user unmanaged product key exists */
2483 size = MAX_PATH;
2484 state = MsiGetComponentPathA(prodcode, component, path, &size);
2485 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2486 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2487
2488 size = MAX_PATH;
2489 state = MsiLocateComponentA(component, path, &size);
2490 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2491 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2492
2493 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2494 lstrcatA(keypath, "Installer\\UserData\\");
2495 lstrcatA(keypath, usersid);
2496 lstrcatA(keypath, "\\Components\\");
2497 lstrcatA(keypath, comp_squashed);
2498
2499 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2500 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2501
2502 /* user unmanaged component key exists */
2503 size = MAX_PATH;
2504 state = MsiGetComponentPathA(prodcode, component, path, &size);
2505 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2506 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2507
2508 size = MAX_PATH;
2509 state = MsiLocateComponentA(component, path, &size);
2510 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2511 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2512
2513 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2514 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2515
2516 /* product value exists */
2517 path[0] = 0;
2518 size = MAX_PATH;
2519 state = MsiGetComponentPathA(prodcode, component, path, &size);
2520 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2521 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2522 ok(size == 10, "Expected 10, got %d\n", size);
2523
2524 path[0] = 0;
2525 size = MAX_PATH;
2526 state = MsiLocateComponentA(component, path, &size);
2527 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2528 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2529 ok(size == 10, "Expected 10, got %d\n", size);
2530
2531 create_file("C:\\imapath", "C:\\imapath", 11);
2532
2533 /* file exists */
2534 path[0] = 0;
2535 size = MAX_PATH;
2536 state = MsiGetComponentPathA(prodcode, component, path, &size);
2537 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2538 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2539 ok(size == 10, "Expected 10, got %d\n", size);
2540
2541 path[0] = 0;
2542 size = MAX_PATH;
2543 state = MsiLocateComponentA(component, path, &size);
2544 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2545 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2546 ok(size == 10, "Expected 10, got %d\n", size);
2547
2548 RegDeleteValueA(compkey, prod_squashed);
2549 RegDeleteKeyA(prodkey, "");
2550 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2551 RegCloseKey(prodkey);
2552 RegCloseKey(compkey);
2553 DeleteFileA("C:\\imapath");
2554
2555 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2556 lstrcatA(keypath, prod_squashed);
2557
2558 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2560
2561 /* local classes product key exists */
2562 size = MAX_PATH;
2563 state = MsiGetComponentPathA(prodcode, component, path, &size);
2564 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2565 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2566
2567 size = MAX_PATH;
2568 state = MsiLocateComponentA(component, path, &size);
2569 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2570 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2571
2572 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2573 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2574 lstrcatA(keypath, comp_squashed);
2575
2576 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2577 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2578
2579 /* local user component key exists */
2580 size = MAX_PATH;
2581 state = MsiGetComponentPathA(prodcode, component, path, &size);
2582 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2583 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2584
2585 size = MAX_PATH;
2586 state = MsiLocateComponentA(component, path, &size);
2587 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2588 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2589
2590 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2591 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2592
2593 /* product value exists */
2594 path[0] = 0;
2595 size = MAX_PATH;
2596 state = MsiGetComponentPathA(prodcode, component, path, &size);
2597 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2598 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2599 ok(size == 10, "Expected 10, got %d\n", size);
2600
2601 path[0] = 0;
2602 size = MAX_PATH;
2603 state = MsiLocateComponentA(component, path, &size);
2604 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2605 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2606 ok(size == 10, "Expected 10, got %d\n", size);
2607
2608 create_file("C:\\imapath", "C:\\imapath", 11);
2609
2610 /* file exists */
2611 path[0] = 0;
2612 size = MAX_PATH;
2613 state = MsiGetComponentPathA(prodcode, component, path, &size);
2614 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2615 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2616 ok(size == 10, "Expected 10, got %d\n", size);
2617
2618 path[0] = 0;
2619 size = MAX_PATH;
2620 state = MsiLocateComponentA(component, path, &size);
2621 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2622 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2623 ok(size == 10, "Expected 10, got %d\n", size);
2624
2625 RegDeleteValueA(compkey, prod_squashed);
2626 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2627 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2628 RegCloseKey(prodkey);
2629 RegCloseKey(compkey);
2630 DeleteFileA("C:\\imapath");
2631 LocalFree(usersid);
2632 }
2633
2634 static void test_MsiGetProductCode(void)
2635 {
2636 HKEY compkey, prodkey;
2637 CHAR prodcode[MAX_PATH];
2638 CHAR prod_squashed[MAX_PATH];
2639 CHAR prodcode2[MAX_PATH];
2640 CHAR prod2_squashed[MAX_PATH];
2641 CHAR component[MAX_PATH];
2642 CHAR comp_base85[MAX_PATH];
2643 CHAR comp_squashed[MAX_PATH];
2644 CHAR keypath[MAX_PATH];
2645 CHAR product[MAX_PATH];
2646 LPSTR usersid;
2647 LONG res;
2648 UINT r;
2649 REGSAM access = KEY_ALL_ACCESS;
2650
2651 create_test_guid(prodcode, prod_squashed);
2652 create_test_guid(prodcode2, prod2_squashed);
2653 compose_base85_guid(component, comp_base85, comp_squashed);
2654 usersid = get_user_sid();
2655
2656 if (is_wow64)
2657 access |= KEY_WOW64_64KEY;
2658
2659 /* szComponent is NULL */
2660 lstrcpyA(product, "prod");
2661 r = MsiGetProductCodeA(NULL, product);
2662 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2663 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2664
2665 /* szComponent is empty */
2666 lstrcpyA(product, "prod");
2667 r = MsiGetProductCodeA("", product);
2668 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2669 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2670
2671 /* garbage szComponent */
2672 lstrcpyA(product, "prod");
2673 r = MsiGetProductCodeA("garbage", product);
2674 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2675 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2676
2677 /* guid without brackets */
2678 lstrcpyA(product, "prod");
2679 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2680 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2681 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2682
2683 /* guid with brackets */
2684 lstrcpyA(product, "prod");
2685 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2686 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2687 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2688
2689 /* same length as guid, but random */
2690 lstrcpyA(product, "prod");
2691 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2692 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2693 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2694
2695 /* all params correct, szComponent not published */
2696 lstrcpyA(product, "prod");
2697 r = MsiGetProductCodeA(component, product);
2698 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2699 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2700
2701 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2702 lstrcatA(keypath, "Installer\\UserData\\");
2703 lstrcatA(keypath, usersid);
2704 lstrcatA(keypath, "\\Components\\");
2705 lstrcatA(keypath, comp_squashed);
2706
2707 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2708 if (res == ERROR_ACCESS_DENIED)
2709 {
2710 skip("Not enough rights to perform tests\n");
2711 LocalFree(usersid);
2712 return;
2713 }
2714 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2715
2716 /* user unmanaged component key exists */
2717 lstrcpyA(product, "prod");
2718 r = MsiGetProductCodeA(component, product);
2719 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2720 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2721
2722 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2723 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2724
2725 /* product value exists */
2726 lstrcpyA(product, "prod");
2727 r = MsiGetProductCodeA(component, product);
2728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2729 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2730
2731 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2732 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2733
2734 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2735 lstrcatA(keypath, "Installer\\Managed\\");
2736 lstrcatA(keypath, usersid);
2737 lstrcatA(keypath, "\\Installer\\Products\\");
2738 lstrcatA(keypath, prod_squashed);
2739
2740 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2741 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2742
2743 /* user managed product key of first product exists */
2744 lstrcpyA(product, "prod");
2745 r = MsiGetProductCodeA(component, product);
2746 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2747 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2748
2749 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2750 RegCloseKey(prodkey);
2751
2752 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2753 lstrcatA(keypath, prod_squashed);
2754
2755 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2756 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2757
2758 /* user unmanaged product key exists */
2759 lstrcpyA(product, "prod");
2760 r = MsiGetProductCodeA(component, product);
2761 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2762 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2763
2764 RegDeleteKeyA(prodkey, "");
2765 RegCloseKey(prodkey);
2766
2767 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2768 lstrcatA(keypath, prod_squashed);
2769
2770 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2771 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2772
2773 /* local classes product key exists */
2774 lstrcpyA(product, "prod");
2775 r = MsiGetProductCodeA(component, product);
2776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2777 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2778
2779 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2780 RegCloseKey(prodkey);
2781
2782 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2783 lstrcatA(keypath, "Installer\\Managed\\");
2784 lstrcatA(keypath, usersid);
2785 lstrcatA(keypath, "\\Installer\\Products\\");
2786 lstrcatA(keypath, prod2_squashed);
2787
2788 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2789 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2790
2791 /* user managed product key of second product exists */
2792 lstrcpyA(product, "prod");
2793 r = MsiGetProductCodeA(component, product);
2794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2795 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2796
2797 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2798 RegCloseKey(prodkey);
2799 RegDeleteValueA(compkey, prod_squashed);
2800 RegDeleteValueA(compkey, prod2_squashed);
2801 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2802 RegCloseKey(compkey);
2803
2804 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2805 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2806 lstrcatA(keypath, comp_squashed);
2807
2808 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2809 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2810
2811 /* local user component key exists */
2812 lstrcpyA(product, "prod");
2813 r = MsiGetProductCodeA(component, product);
2814 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2815 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2816
2817 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2818 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2819
2820 /* product value exists */
2821 lstrcpyA(product, "prod");
2822 r = MsiGetProductCodeA(component, product);
2823 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2824 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2825
2826 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2827 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2828
2829 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2830 lstrcatA(keypath, "Installer\\Managed\\");
2831 lstrcatA(keypath, usersid);
2832 lstrcatA(keypath, "\\Installer\\Products\\");
2833 lstrcatA(keypath, prod_squashed);
2834
2835 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2836 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2837
2838 /* user managed product key of first product exists */
2839 lstrcpyA(product, "prod");
2840 r = MsiGetProductCodeA(component, product);
2841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2842 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2843
2844 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2845 RegCloseKey(prodkey);
2846
2847 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2848 lstrcatA(keypath, prod_squashed);
2849
2850 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2851 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2852
2853 /* user unmanaged product key exists */
2854 lstrcpyA(product, "prod");
2855 r = MsiGetProductCodeA(component, product);
2856 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2857 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2858
2859 RegDeleteKeyA(prodkey, "");
2860 RegCloseKey(prodkey);
2861
2862 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2863 lstrcatA(keypath, prod_squashed);
2864
2865 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2866 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2867
2868 /* local classes product key exists */
2869 lstrcpyA(product, "prod");
2870 r = MsiGetProductCodeA(component, product);
2871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2872 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2873
2874 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2875 RegCloseKey(prodkey);
2876
2877 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2878 lstrcatA(keypath, "Installer\\Managed\\");
2879 lstrcatA(keypath, usersid);
2880 lstrcatA(keypath, "\\Installer\\Products\\");
2881 lstrcatA(keypath, prod2_squashed);
2882
2883 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2884 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2885
2886 /* user managed product key of second product exists */
2887 lstrcpyA(product, "prod");
2888 r = MsiGetProductCodeA(component, product);
2889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2890 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2891
2892 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2893 RegCloseKey(prodkey);
2894 RegDeleteValueA(compkey, prod_squashed);
2895 RegDeleteValueA(compkey, prod2_squashed);
2896 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2897 RegCloseKey(compkey);
2898 LocalFree(usersid);
2899 }
2900
2901 static void test_MsiEnumClients(void)
2902 {
2903 HKEY compkey;
2904 CHAR prodcode[MAX_PATH];
2905 CHAR prod_squashed[MAX_PATH];
2906 CHAR prodcode2[MAX_PATH];
2907 CHAR prod2_squashed[MAX_PATH];
2908 CHAR component[MAX_PATH];
2909 CHAR comp_base85[MAX_PATH];
2910 CHAR comp_squashed[MAX_PATH];
2911 CHAR product[MAX_PATH];
2912 CHAR keypath[MAX_PATH];
2913 LPSTR usersid;
2914 LONG res;
2915 UINT r;
2916 REGSAM access = KEY_ALL_ACCESS;
2917
2918 create_test_guid(prodcode, prod_squashed);
2919 create_test_guid(prodcode2, prod2_squashed);
2920 compose_base85_guid(component, comp_base85, comp_squashed);
2921 usersid = get_user_sid();
2922
2923 if (is_wow64)
2924 access |= KEY_WOW64_64KEY;
2925
2926 /* NULL szComponent */
2927 product[0] = '\0';
2928 r = MsiEnumClientsA(NULL, 0, product);
2929 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2930 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2931
2932 /* empty szComponent */
2933 product[0] = '\0';
2934 r = MsiEnumClientsA("", 0, product);
2935 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2936 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2937
2938 /* NULL lpProductBuf */
2939 r = MsiEnumClientsA(component, 0, NULL);
2940 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2941
2942 /* all params correct, component missing */
2943 product[0] = '\0';
2944 r = MsiEnumClientsA(component, 0, product);
2945 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2946 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2947
2948 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2949 lstrcatA(keypath, "Installer\\UserData\\");
2950 lstrcatA(keypath, usersid);
2951 lstrcatA(keypath, "\\Components\\");
2952 lstrcatA(keypath, comp_squashed);
2953
2954 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2955 if (res == ERROR_ACCESS_DENIED)
2956 {
2957 skip("Not enough rights to perform tests\n");
2958 LocalFree(usersid);
2959 return;
2960 }
2961 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2962
2963 /* user unmanaged component key exists */
2964 product[0] = '\0';
2965 r = MsiEnumClientsA(component, 0, product);
2966 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2967 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2968
2969 /* index > 0, no products exist */
2970 product[0] = '\0';
2971 r = MsiEnumClientsA(component, 1, product);
2972 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2973 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2974
2975 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2977
2978 /* product value exists */
2979 r = MsiEnumClientsA(component, 0, product);
2980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2981 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2982
2983 /* try index 0 again */
2984 product[0] = '\0';
2985 r = MsiEnumClientsA(component, 0, product);
2986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2987 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2988
2989 /* try index 1, second product value does not exist */
2990 product[0] = '\0';
2991 r = MsiEnumClientsA(component, 1, product);
2992 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2993 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2994
2995 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2996 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2997
2998 /* try index 1, second product value does exist */
2999 product[0] = '\0';
3000 r = MsiEnumClientsA(component, 1, product);
3001 todo_wine
3002 {
3003 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3004 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3005 }
3006
3007 /* start the enumeration over */
3008 product[0] = '\0';
3009 r = MsiEnumClientsA(component, 0, product);
3010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3011 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3012 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3013
3014 /* correctly query second product */
3015 product[0] = '\0';
3016 r = MsiEnumClientsA(component, 1, product);
3017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3018 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3019 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3020
3021 RegDeleteValueA(compkey, prod_squashed);
3022 RegDeleteValueA(compkey, prod2_squashed);
3023 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3024 RegCloseKey(compkey);
3025
3026 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3027 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3028 lstrcatA(keypath, comp_squashed);
3029
3030 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3031 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3032
3033 /* user local component key exists */
3034 product[0] = '\0';
3035 r = MsiEnumClientsA(component, 0, product);
3036 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3037 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3038
3039 /* index > 0, no products exist */
3040 product[0] = '\0';
3041 r = MsiEnumClientsA(component, 1, product);
3042 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3043 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3044
3045 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3046 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3047
3048 /* product value exists */
3049 product[0] = '\0';
3050 r = MsiEnumClientsA(component, 0, product);
3051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3052 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3053
3054 /* try index 0 again */
3055 product[0] = '\0';
3056 r = MsiEnumClientsA(component, 0, product);
3057 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3058
3059 /* try index 1, second product value does not exist */
3060 product[0] = '\0';
3061 r = MsiEnumClientsA(component, 1, product);
3062 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3063 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3064
3065 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3066 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3067
3068 /* try index 1, second product value does exist */
3069 product[0] = '\0';
3070 r = MsiEnumClientsA(component, 1, product);
3071 todo_wine
3072 {
3073 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3074 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3075 }
3076
3077 /* start the enumeration over */
3078 product[0] = '\0';
3079 r = MsiEnumClientsA(component, 0, product);
3080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3081 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3082 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3083
3084 /* correctly query second product */
3085 product[0] = '\0';
3086 r = MsiEnumClientsA(component, 1, product);
3087 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3088 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3089 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3090
3091 RegDeleteValueA(compkey, prod_squashed);
3092 RegDeleteValueA(compkey, prod2_squashed);
3093 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3094 RegCloseKey(compkey);
3095 LocalFree(usersid);
3096 }
3097
3098 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
3099 LPSTR *langcheck, LPDWORD langchecksz)
3100 {
3101 LPSTR version;
3102 VS_FIXEDFILEINFO *ffi;
3103 DWORD size = GetFileVersionInfoSizeA(path, NULL);
3104 USHORT *lang;
3105
3106 version = HeapAlloc(GetProcessHeap(), 0, size);
3107 GetFileVersionInfoA(path, 0, size, version);
3108
3109 VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
3110 *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3111 sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
3112 LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
3113 LOWORD(ffi->dwFileVersionLS));
3114 *verchecksz = lstrlenA(*vercheck);
3115
3116 VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
3117 *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3118 sprintf(*langcheck, "%d", *lang);
3119 *langchecksz = lstrlenA(*langcheck);
3120
3121 HeapFree(GetProcessHeap(), 0, version);
3122 }
3123
3124 static void test_MsiGetFileVersion(void)
3125 {
3126 UINT r;
3127 DWORD versz, langsz;
3128 char version[MAX_PATH];
3129 char lang[MAX_PATH];
3130 char path[MAX_PATH];
3131 LPSTR vercheck, langcheck;
3132 DWORD verchecksz, langchecksz;
3133
3134 /* NULL szFilePath */
3135 r = MsiGetFileVersionA(NULL, NULL, NULL, NULL, NULL);
3136 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3137
3138 versz = MAX_PATH;
3139 langsz = MAX_PATH;
3140 lstrcpyA(version, "version");
3141 lstrcpyA(lang, "lang");
3142 r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
3143 ok(r == ERROR_INVALID_PARAMETER,
3144 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3145 ok(!lstrcmpA(version, "version"),
3146 "Expected version to be unchanged, got %s\n", version);
3147 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3148 ok(!lstrcmpA(lang, "lang"),
3149 "Expected lang to be unchanged, got %s\n", lang);
3150 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3151
3152 /* empty szFilePath */
3153 r = MsiGetFileVersionA("", NULL, NULL, NULL, NULL);
3154 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3155
3156 versz = MAX_PATH;
3157 langsz = MAX_PATH;
3158 lstrcpyA(version, "version");
3159 lstrcpyA(lang, "lang");
3160 r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
3161 ok(r == ERROR_FILE_NOT_FOUND,
3162 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3163 ok(!lstrcmpA(version, "version"),
3164 "Expected version to be unchanged, got %s\n", version);
3165 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3166 ok(!lstrcmpA(lang, "lang"),
3167 "Expected lang to be unchanged, got %s\n", lang);
3168 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3169
3170 /* nonexistent szFilePath */
3171 versz = MAX_PATH;
3172 langsz = MAX_PATH;
3173 lstrcpyA(version, "version");
3174 lstrcpyA(lang, "lang");
3175 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3176 ok(r == ERROR_FILE_NOT_FOUND,
3177 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3178 ok(!lstrcmpA(version, "version"),
3179 "Expected version to be unchanged, got %s\n", version);
3180 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3181 ok(!lstrcmpA(lang, "lang"),
3182 "Expected lang to be unchanged, got %s\n", lang);
3183 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3184
3185 /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
3186 versz = MAX_PATH;
3187 langsz = MAX_PATH;
3188 lstrcpyA(version, "version");
3189 lstrcpyA(lang, "lang");
3190 r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
3191 ok(r == ERROR_INVALID_PARAMETER,
3192 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3193 ok(!lstrcmpA(version, "version"),
3194 "Expected version to be unchanged, got %s\n", version);
3195 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3196 ok(!lstrcmpA(lang, "lang"),
3197 "Expected lang to be unchanged, got %s\n", lang);
3198 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3199
3200 /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
3201 versz = MAX_PATH;
3202 langsz = MAX_PATH;
3203 lstrcpyA(version, "version");
3204 lstrcpyA(lang, "lang");
3205 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
3206 ok(r == ERROR_INVALID_PARAMETER,
3207 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3208 ok(!lstrcmpA(version, "version"),
3209 "Expected version to be unchanged, got %s\n", version);
3210 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3211 ok(!lstrcmpA(lang, "lang"),
3212 "Expected lang to be unchanged, got %s\n", lang);
3213 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3214
3215 /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
3216 versz = 0;
3217 langsz = MAX_PATH;
3218 lstrcpyA(version, "version");
3219 lstrcpyA(lang, "lang");
3220 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3221 ok(r == ERROR_FILE_NOT_FOUND,
3222 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3223 ok(!lstrcmpA(version, "version"),
3224 "Expected version to be unchanged, got %s\n", version);
3225 ok(versz == 0, "Expected 0, got %d\n", versz);
3226 ok(!lstrcmpA(lang, "lang"),
3227 "Expected lang to be unchanged, got %s\n", lang);
3228 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3229
3230 /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
3231 versz = MAX_PATH;
3232 langsz = 0;
3233 lstrcpyA(version, "version");
3234 lstrcpyA(lang, "lang");
3235 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3236 ok(r == ERROR_FILE_NOT_FOUND,
3237 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3238 ok(!lstrcmpA(version, "version"),
3239 "Expected version to be unchanged, got %s\n", version);
3240 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3241 ok(!lstrcmpA(lang, "lang"),
3242 "Expected lang to be unchanged, got %s\n", lang);
3243 ok(langsz == 0, "Expected 0, got %d\n", langsz);
3244
3245 /* nonexistent szFilePath, rest NULL */
3246 r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
3247 ok(r == ERROR_FILE_NOT_FOUND,
3248 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3249
3250 create_file("ver.txt", "ver.txt", 20);
3251
3252 /* file exists, no version information */
3253 r = MsiGetFileVersionA("ver.txt", NULL, NULL, NULL, NULL);
3254 ok(r == ERROR_FILE_INVALID, "Expected ERROR_FILE_INVALID, got %d\n", r);
3255
3256 versz = MAX_PATH;
3257 langsz = MAX_PATH;
3258 lstrcpyA(version, "version");
3259 lstrcpyA(lang, "lang");
3260 r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
3261 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3262 ok(!lstrcmpA(version, "version"),
3263 "Expected version to be unchanged, got %s\n", version);
3264 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3265 ok(!lstrcmpA(lang, "lang"),
3266 "Expected lang to be unchanged, got %s\n", lang);
3267 ok(r == ERROR_FILE_INVALID,
3268 "Expected ERROR_FILE_INVALID, got %d\n", r);
3269
3270 DeleteFileA("ver.txt");
3271
3272 /* relative path, has version information */
3273 versz = MAX_PATH;
3274 langsz = MAX_PATH;
3275 lstrcpyA(version, "version");
3276 lstrcpyA(lang, "lang");
3277 r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
3278 todo_wine
3279 {
3280 ok(r == ERROR_FILE_NOT_FOUND,
3281 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3282 ok(!lstrcmpA(version, "version"),
3283 "Expected version to be unchanged, got %s\n", version);
3284 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3285 ok(!lstrcmpA(lang, "lang"),
3286 "Expected lang to be unchanged, got %s\n", lang);
3287 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3288 }
3289
3290 GetSystemDirectoryA(path, MAX_PATH);
3291 lstrcatA(path, "\\kernel32.dll");
3292
3293 get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
3294
3295 /* absolute path, has version information */
3296 versz = MAX_PATH;
3297 langsz = MAX_PATH;
3298 lstrcpyA(version, "version");
3299 lstrcpyA(lang, "lang");
3300 r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
3301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3302 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3303 ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
3304 ok(!lstrcmpA(version, vercheck),
3305 "Expected %s, got %s\n", vercheck, version);
3306
3307 /* only check version */
3308 versz = MAX_PATH;
3309 lstrcpyA(version, "version");
3310 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
3311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3312 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3313 ok(!lstrcmpA(version, vercheck),
3314 "Expected %s, got %s\n", vercheck, version);
3315
3316 /* only check language */
3317 langsz = MAX_PATH;
3318 lstrcpyA(lang, "lang");
3319 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
3320 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3321 ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
3322
3323 /* check neither version nor language */
3324 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
3325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326
3327 /* get pcchVersionBuf */
3328 versz = MAX_PATH;
3329 r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
3330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3331 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3332
3333 /* get pcchLangBuf */
3334 langsz = MAX_PATH;
3335 r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
3336 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3337 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3338
3339 /* pcchVersionBuf not big enough */
3340 versz = 5;
3341 lstrcpyA(version, "version");
3342 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
3343 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3344 ok(!strncmp(version, vercheck, 4),
3345 "Expected first 4 characters of %s, got %s\n", vercheck, version);
3346 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3347
3348 /* pcchLangBuf not big enough */
3349 langsz = 3;
3350 lstrcpyA(lang, "lang");
3351 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
3352 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3353 ok(!strncmp(lang, langcheck, 2),
3354 "Expected first character of %s, got %s\n", langcheck, lang);
3355 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
3356
3357 /* pcchVersionBuf big enough, pcchLangBuf not big enough */
3358 versz = MAX_PATH;
3359 langsz = 0;
3360 lstrcpyA(version, "version");
3361 r = MsiGetFileVersionA(path, version, &versz, NULL, &langsz);
3362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3363 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3364 ok(!lstrcmpA(version, vercheck), "Expected %s, got %s\n", vercheck, version);
3365 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
3366
3367 /* pcchVersionBuf not big enough, pcchLangBuf big enough */
3368 versz = 5;
3369 langsz = MAX_PATH;
3370 lstrcpyA(lang, "lang");
3371 r = MsiGetFileVersionA(path, NULL, &versz, lang, &langsz);
3372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3373 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
3374 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
3375 ok(lstrcmpA(lang, "lang"), "lang buffer not modified\n");
3376
3377 /* NULL pcchVersionBuf and pcchLangBuf */
3378 r = MsiGetFileVersionA(path, version, NULL, lang, NULL);
3379 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3380
3381 /* All NULL except szFilePath */
3382 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
3383 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384
3385 HeapFree(GetProcessHeap(), 0, vercheck);
3386 HeapFree(GetProcessHeap(), 0, langcheck);
3387 }
3388
3389 static void test_MsiGetProductInfo(void)
3390 {
3391 UINT r;
3392 LONG res;
3393 HKEY propkey, source;
3394 HKEY prodkey, localkey;
3395 CHAR prodcode[MAX_PATH];
3396 CHAR prod_squashed[MAX_PATH];
3397 CHAR packcode[MAX_PATH];
3398 CHAR pack_squashed[MAX_PATH];
3399 CHAR buf[MAX_PATH];
3400 CHAR keypath[MAX_PATH];
3401 LPSTR usersid;
3402 DWORD sz, val = 42;
3403 REGSAM access = KEY_ALL_ACCESS;
3404
3405 create_test_guid(prodcode, prod_squashed);
3406 create_test_guid(packcode, pack_squashed);
3407 usersid = get_user_sid();
3408
3409 if (is_wow64)
3410 access |= KEY_WOW64_64KEY;
3411
3412 /* NULL szProduct */
3413 sz = MAX_PATH;
3414 lstrcpyA(buf, "apple");
3415 r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
3416 ok(r == ERROR_INVALID_PARAMETER,
3417 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3418 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3419 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3420
3421 /* empty szProduct */
3422 sz = MAX_PATH;
3423 lstrcpyA(buf, "apple");
3424 r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
3425 ok(r == ERROR_INVALID_PARAMETER,
3426 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3427 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3428 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3429
3430 /* garbage szProduct */
3431 sz = MAX_PATH;
3432 lstrcpyA(buf, "apple");
3433 r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
3434 ok(r == ERROR_INVALID_PARAMETER,
3435 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3436 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3437 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3438
3439 /* guid without brackets */
3440 sz = MAX_PATH;
3441 lstrcpyA(buf, "apple");
3442 r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
3443 INSTALLPROPERTY_HELPLINK, buf, &sz);
3444 ok(r == ERROR_INVALID_PARAMETER,
3445 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3446 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3447 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3448
3449 /* guid with brackets */
3450 sz = MAX_PATH;
3451 lstrcpyA(buf, "apple");
3452 r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
3453 INSTALLPROPERTY_HELPLINK, buf, &sz);
3454 ok(r == ERROR_UNKNOWN_PRODUCT,
3455 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3456 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3457 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3458
3459 /* same length as guid, but random */
3460 sz = MAX_PATH;
3461 lstrcpyA(buf, "apple");
3462 r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
3463 INSTALLPROPERTY_HELPLINK, buf, &sz);
3464 ok(r == ERROR_INVALID_PARAMETER,
3465 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3466 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3467 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3468
3469 /* not installed, NULL szAttribute */
3470 sz = MAX_PATH;
3471 lstrcpyA(buf, "apple");
3472 r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
3473 ok(r == ERROR_INVALID_PARAMETER,
3474 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3475 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3476 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3477
3478 /* not installed, NULL lpValueBuf */
3479 sz = MAX_PATH;
3480 lstrcpyA(buf, "apple");
3481 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3482 ok(r == ERROR_UNKNOWN_PRODUCT,
3483 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3484 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3485 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3486
3487 /* not installed, NULL pcchValueBuf */
3488 sz = MAX_PATH;
3489 lstrcpyA(buf, "apple");
3490 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
3491 ok(r == ERROR_INVALID_PARAMETER,
3492 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3493 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3494 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3495
3496 /* created guid cannot possibly be an installed product code */
3497 sz = MAX_PATH;
3498 lstrcpyA(buf, "apple");
3499 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3500 ok(r == ERROR_UNKNOWN_PRODUCT,
3501 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3502 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3503 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3504
3505 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3506 lstrcatA(keypath, usersid);
3507 lstrcatA(keypath, "\\Installer\\Products\\");
3508 lstrcatA(keypath, prod_squashed);
3509
3510 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3511 if (res == ERROR_ACCESS_DENIED)
3512 {
3513 skip("Not enough rights to perform tests\n");
3514 LocalFree(usersid);
3515 return;
3516 }
3517 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3518
3519 /* managed product code exists */
3520 sz = MAX_PATH;
3521 lstrcpyA(buf, "apple");
3522 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3523 ok(r == ERROR_UNKNOWN_PROPERTY,
3524 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3525 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3526 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3527
3528 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3529 RegCloseKey(prodkey);
3530
3531 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3532 lstrcatA(keypath, usersid);
3533 lstrcatA(keypath, "\\Products\\");
3534 lstrcatA(keypath, prod_squashed);
3535
3536 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3537 if (res == ERROR_ACCESS_DENIED)
3538 {
3539 skip("Not enough rights to perform tests\n");
3540 LocalFree(usersid);
3541 return;
3542 }
3543 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3544
3545 /* local user product code exists */
3546 sz = MAX_PATH;
3547 lstrcpyA(buf, "apple");
3548 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3549 ok(r == ERROR_UNKNOWN_PRODUCT,
3550 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3551 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3552 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3553
3554 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3555 lstrcatA(keypath, usersid);
3556 lstrcatA(keypath, "\\Installer\\Products\\");
3557 lstrcatA(keypath, prod_squashed);
3558
3559 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3560 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3561
3562 /* both local and managed product code exist */
3563 sz = MAX_PATH;
3564 lstrcpyA(buf, "apple");
3565 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3566 ok(r == ERROR_UNKNOWN_PROPERTY,
3567 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3568 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3569 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3570
3571 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3572 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3573
3574 /* InstallProperties key exists */
3575 sz = MAX_PATH;
3576 lstrcpyA(buf, "apple");
3577 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3578 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3579 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3580 ok(sz == 0, "Expected 0, got %d\n", sz);
3581
3582 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3583 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3584
3585 /* HelpLink value exists */
3586 sz = MAX_PATH;
3587 lstrcpyA(buf, "apple");
3588 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3589 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3590 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3591 ok(sz == 4, "Expected 4, got %d\n", sz);
3592
3593 /* pcchBuf is NULL */
3594 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
3595 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3596
3597 /* lpValueBuf is NULL */
3598 sz = MAX_PATH;
3599 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3601 ok(sz == 4, "Expected 4, got %d\n", sz);
3602
3603 /* lpValueBuf is NULL, pcchValueBuf is too small */
3604 sz = 2;
3605 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3606 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3607 ok(sz == 4, "Expected 4, got %d\n", sz);
3608
3609 /* lpValueBuf is non-NULL, pcchValueBuf is too small */
3610 sz = 2;
3611 lstrcpyA(buf, "apple");
3612 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3613 ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
3614 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3615 ok(sz == 4, "Expected 4, got %d\n", sz);
3616
3617 /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
3618 sz = 4;
3619 lstrcpyA(buf, "apple");
3620 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3621 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3622 ok(!lstrcmpA(buf, "apple"),
3623 "Expected buf to remain unchanged, got \"%s\"\n", buf);
3624 ok(sz == 4, "Expected 4, got %d\n", sz);
3625
3626 res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
3627 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3628
3629 /* random property not supported by MSI, value exists */
3630 sz = MAX_PATH;
3631 lstrcpyA(buf, "apple");
3632 r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
3633 ok(r == ERROR_UNKNOWN_PROPERTY,
3634 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3635 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3636 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3637
3638 RegDeleteValueA(propkey, "IMadeThis");
3639 RegDeleteValueA(propkey, "HelpLink");
3640 delete_key(propkey, "", access & KEY_WOW64_64KEY);
3641 delete_key(localkey, "", access & KEY_WOW64_64KEY);
3642 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3643 RegCloseKey(propkey);
3644 RegCloseKey(localkey);
3645 RegCloseKey(prodkey);
3646
3647 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3648 lstrcatA(keypath, prod_squashed);
3649
3650 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3651 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3652
3653 /* user product key exists */
3654 sz = MAX_PATH;
3655 lstrcpyA(buf, "apple");
3656 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3657 ok(r == ERROR_UNKNOWN_PROPERTY,
3658 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3659 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3660 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3661
3662 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3663 lstrcatA(keypath, usersid);
3664 lstrcatA(keypath, "\\Products\\");
3665 lstrcatA(keypath, prod_squashed);
3666
3667 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3668 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3669
3670 /* local user product key exists */
3671 sz = MAX_PATH;
3672 lstrcpyA(buf, "apple");
3673 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3674 ok(r == ERROR_UNKNOWN_PROPERTY,
3675 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3676 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3677 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3678
3679 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3680 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3681
3682 /* InstallProperties key exists */
3683 sz = MAX_PATH;
3684 lstrcpyA(buf, "apple");
3685 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3687 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3688 ok(sz == 0, "Expected 0, got %d\n", sz);
3689
3690 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3691 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3692
3693 /* HelpLink value exists */
3694 sz = MAX_PATH;
3695 lstrcpyA(buf, "apple");
3696 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3698 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3699 ok(sz == 4, "Expected 4, got %d\n", sz);
3700
3701 RegDeleteValueA(propkey, "HelpLink");
3702 delete_key(propkey, "", access & KEY_WOW64_64KEY);
3703 delete_key(localkey, "", access & KEY_WOW64_64KEY);
3704 RegDeleteKeyA(prodkey, "");
3705 RegCloseKey(propkey);
3706 RegCloseKey(localkey);
3707 RegCloseKey(prodkey);
3708
3709 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3710 lstrcatA(keypath, prod_squashed);
3711
3712 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3713 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3714
3715 /* classes product key exists */
3716 sz = MAX_PATH;
3717 lstrcpyA(buf, "apple");
3718 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3719 ok(r == ERROR_UNKNOWN_PROPERTY,
3720 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3721 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3722 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3723
3724 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3725 lstrcatA(keypath, usersid);
3726 lstrcatA(keypath, "\\Products\\");
3727 lstrcatA(keypath, prod_squashed);
3728
3729 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3730 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3731
3732 /* local user product key exists */
3733 sz = MAX_PATH;
3734 lstrcpyA(buf, "apple");
3735 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3736 ok(r == ERROR_UNKNOWN_PROPERTY,
3737 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3738 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3739 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3740
3741 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3742 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3743
3744 /* InstallProperties key exists */
3745 sz = MAX_PATH;
3746 lstrcpyA(buf, "apple");
3747 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3748 ok(r == ERROR_UNKNOWN_PROPERTY,
3749 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3750 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3751 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3752
3753 delete_key(propkey, "", access & KEY_WOW64_64KEY);
3754 delete_key(localkey, "", access & KEY_WOW64_64KEY);
3755 RegCloseKey(propkey);
3756 RegCloseKey(localkey);
3757
3758 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3759 lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3760 lstrcatA(keypath, prod_squashed);
3761
3762 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3763 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3764
3765 /* Local System product key exists */
3766 sz = MAX_PATH;
3767 lstrcpyA(buf, "apple");
3768 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3769 ok(r == ERROR_UNKNOWN_PROPERTY,
3770 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3771 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3772 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3773
3774 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3775 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3776
3777 /* InstallProperties key exists */
3778 sz = MAX_PATH;
3779 lstrcpyA(buf, "apple");
3780 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3782 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3783 ok(sz == 0, "Expected 0, got %d\n", sz);
3784
3785 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3787
3788 /* HelpLink value exists */
3789 sz = MAX_PATH;
3790 lstrcpyA(buf, "apple");
3791 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3792 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3793 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3794 ok(sz == 4, "Expected 4, got %d\n", sz);
3795
3796 res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3797 (const BYTE *)&val, sizeof(DWORD));
3798 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3799
3800 /* HelpLink type is REG_DWORD */
3801 sz = MAX_PATH;
3802 lstrcpyA(buf, "apple");
3803 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3804 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3805 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3806 ok(sz == 2, "Expected 2, got %d\n", sz);
3807
3808 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3809 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3810
3811 /* DisplayName value exists */
3812 sz = MAX_PATH;
3813 lstrcpyA(buf, "apple");
3814 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3816 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3817 ok(sz == 4, "Expected 4, got %d\n", sz);
3818
3819 res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3820 (const BYTE *)&val, sizeof(DWORD));
3821 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3822
3823 /* DisplayName type is REG_DWORD */
3824 sz = MAX_PATH;
3825 lstrcpyA(buf, "apple");
3826 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3828 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3829 ok(sz == 2, "Expected 2, got %d\n", sz);
3830
3831 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3832 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3833
3834 /* DisplayVersion value exists */
3835 sz = MAX_PATH;
3836 lstrcpyA(buf, "apple");
3837 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3838 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3839 ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3840 ok(sz == 5, "Expected 5, got %d\n", sz);
3841
3842 res = RegSetValueExA(propkey, "DisplayVersion", 0,
3843 REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3844 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3845
3846 /* DisplayVersion type is REG_DWORD */
3847 sz = MAX_PATH;
3848 lstrcpyA(buf, "apple");
3849 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3850 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3851 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3852 ok(sz == 2, "Expected 2, got %d\n", sz);
3853
3854 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3855 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3856
3857 /* HelpTelephone value exists */
3858 sz = MAX_PATH;
3859 lstrcpyA(buf, "apple");
3860 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3861 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3862 ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3863 ok(sz == 4, "Expected 4, got %d\n", sz);
3864
3865 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3866 (const BYTE *)&val, sizeof(DWORD));
3867 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3868
3869 /* HelpTelephone type is REG_DWORD */
3870 sz = MAX_PATH;
3871 lstrcpyA(buf, "apple");
3872 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3873 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3874 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3875 ok(sz == 2, "Expected 2, got %d\n", sz);
3876
3877 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3878 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3879
3880 /* InstallLocation value exists */
3881 sz = MAX_PATH;
3882 lstrcpyA(buf, "apple");
3883 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3884 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3885 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3886 ok(sz == 3, "Expected 3, got %d\n", sz);
3887
3888 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3889 (const BYTE *)&val, sizeof(DWORD));
3890 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3891
3892 /* InstallLocation type is REG_DWORD */
3893 sz = MAX_PATH;
3894 lstrcpyA(buf, "apple");
3895 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3897 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3898 ok(sz == 2, "Expected 2, got %d\n", sz);
3899
3900 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3901 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3902
3903 /* InstallSource value exists */
3904 sz = MAX_PATH;
3905 lstrcpyA(buf, "apple");
3906 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3907 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3908 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3909 ok(sz == 6, "Expected 6, got %d\n", sz);
3910
3911 res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3912 (const BYTE *)&val, sizeof(DWORD));
3913 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3914
3915 /* InstallSource type is REG_DWORD */
3916 sz = MAX_PATH;
3917 lstrcpyA(buf, "apple");
3918 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3919 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3920 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3921 ok(sz == 2, "Expected 2, got %d\n", sz);
3922
3923 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3924 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3925
3926 /* InstallDate value exists */
3927 sz = MAX_PATH;
3928 lstrcpyA(buf, "apple");
3929 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3930 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3931 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3932 ok(sz == 4, "Expected 4, got %d\n", sz);
3933
3934 res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3935 (const BYTE *)&val, sizeof(DWORD));
3936 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3937
3938 /* InstallDate type is REG_DWORD */
3939 sz = MAX_PATH;
3940 lstrcpyA(buf, "apple");
3941 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3943 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3944 ok(sz == 2, "Expected 2, got %d\n", sz);
3945
3946 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3948
3949 /* Publisher value exists */
3950 sz = MAX_PATH;
3951 lstrcpyA(buf, "apple");
3952 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3953 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3954 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3955 ok(sz == 3, "Expected 3, got %d\n", sz);
3956
3957 res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3958 (const BYTE *)&val, sizeof(DWORD));
3959 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3960
3961 /* Publisher type is REG_DWORD */
3962 sz = MAX_PATH;
3963 lstrcpyA(buf, "apple");
3964 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3966 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3967 ok(sz == 2, "Expected 2, got %d\n", sz);
3968
3969 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3970 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3971
3972 /* LocalPackage value exists */
3973 sz = MAX_PATH;
3974 lstrcpyA(buf, "apple");
3975 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3976 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3977 ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3978 ok(sz == 4, "Expected 4, got %d\n", sz);
3979
3980 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3981 (const BYTE *)&val, sizeof(DWORD));
3982 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3983
3984 /* LocalPackage type is REG_DWORD */
3985 sz = MAX_PATH;
3986 lstrcpyA(buf, "apple");
3987 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3989 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3990 ok(sz == 2, "Expected 2, got %d\n", sz);
3991
3992 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3993 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3994
3995 /* UrlInfoAbout value exists */
3996 sz = MAX_PATH;
3997 lstrcpyA(buf, "apple");
3998 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3999 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4000 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4001 ok(sz == 5, "Expected 5, got %d\n", sz);
4002
4003 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
4004 (const BYTE *)&val, sizeof(DWORD));
4005 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4006
4007 /* UrlInfoAbout type is REG_DWORD */
4008 sz = MAX_PATH;
4009 lstrcpyA(buf, "apple");
4010 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4012 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4013 ok(sz == 2, "Expected 2, got %d\n", sz);
4014
4015 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
4016 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4017
4018 /* UrlUpdateInfo value exists */
4019 sz = MAX_PATH;
4020 lstrcpyA(buf, "apple");
4021 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4023 ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
4024 ok(sz == 4, "Expected 4, got %d\n", sz);
4025
4026 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
4027 (const BYTE *)&val, sizeof(DWORD));
4028 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4029
4030 /* UrlUpdateInfo type is REG_DWORD */
4031 sz = MAX_PATH;
4032 lstrcpyA(buf, "apple");
4033 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4034 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4035 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4036 ok(sz == 2, "Expected 2, got %d\n", sz);
4037
4038 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
4039 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4040
4041 /* VersionMinor value exists */
4042 sz = MAX_PATH;
4043 lstrcpyA(buf, "apple");
4044 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4045 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4046 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4047 ok(sz == 1, "Expected 1, got %d\n", sz);
4048
4049 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
4050 (const BYTE *)&val, sizeof(DWORD));
4051 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4052
4053 /* VersionMinor type is REG_DWORD */
4054 sz = MAX_PATH;
4055 lstrcpyA(buf, "apple");
4056 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4057 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4058 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4059 ok(sz == 2, "Expected 2, got %d\n", sz);
4060
4061 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
4062 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4063
4064 /* VersionMajor value exists */
4065 sz = MAX_PATH;
4066 lstrcpyA(buf, "apple");
4067 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4069 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4070 ok(sz == 1, "Expected 1, got %d\n", sz);
4071
4072 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
4073 (const BYTE *)&val, sizeof(DWORD));
4074 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4075
4076 /* VersionMajor type is REG_DWORD */
4077 sz = MAX_PATH;
4078 lstrcpyA(buf, "apple");
4079 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4081 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4082 ok(sz == 2, "Expected 2, got %d\n", sz);
4083
4084 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4085 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4086
4087 /* ProductID value exists */
4088 sz = MAX_PATH;
4089 lstrcpyA(buf, "apple");
4090 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
4091 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4092 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4093 ok(sz == 2, "Expected 2, got %d\n", sz);
4094
4095 res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
4096 (const BYTE *)&val, sizeof(DWORD));
4097 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4098
4099 /* ProductID type is REG_DWORD */
4100 sz = MAX_PATH;
4101 lstrcpyA(buf, "apple");
4102 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
4103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4104 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4105 ok(sz == 2, "Expected 2, got %d\n", sz);
4106
4107 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4108 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4109
4110 /* RegCompany value exists */
4111 sz = MAX_PATH;
4112 lstrcpyA(buf, "apple");
4113 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4115 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4116 ok(sz == 4, "Expected 4, got %d\n", sz);
4117
4118 res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
4119 (const BYTE *)&val, sizeof(DWORD));
4120 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4121
4122 /* RegCompany type is REG_DWORD */
4123 sz = MAX_PATH;
4124 lstrcpyA(buf, "apple");
4125 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4126 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4127 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4128 ok(sz == 2, "Expected 2, got %d\n", sz);
4129
4130 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
4131 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4132
4133 /* RegOwner value exists */
4134 sz = MAX_PATH;
4135 lstrcpyA(buf, "apple");
4136 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
4137 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4138 ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
4139 ok(sz == 3, "Expected 3, got %d\n", sz);
4140
4141 res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
4142 (const BYTE *)&val, sizeof(DWORD));
4143 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4144
4145 /* RegOwner type is REG_DWORD */
4146 sz = MAX_PATH;
4147 lstrcpyA(buf, "apple");
4148 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
4149 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4150 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4151 ok(sz == 2, "Expected 2, got %d\n", sz);
4152
4153 res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
4154 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4155
4156 /* InstanceType value exists */
4157 sz = MAX_PATH;
4158 lstrcpyA(buf, "apple");
4159 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
4160 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4161 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4162 ok(sz == 0, "Expected 0, got %d\n", sz);
4163
4164 res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
4165 (const BYTE *)&val, sizeof(DWORD));
4166 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4167
4168 /* InstanceType type is REG_DWORD */
4169 sz = MAX_PATH;
4170 lstrcpyA(buf, "apple");
4171 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
4172 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4173 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4174 ok(sz == 0, "Expected 0, got %d\n", sz);
4175
4176 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
4177 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4178
4179 /* InstanceType value exists */
4180 sz = MAX_PATH;
4181 lstrcpyA(buf, "apple");
4182 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
4183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4184 ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
4185 ok(sz == 4, "Expected 4, got %d\n", sz);
4186
4187 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
4188 (const BYTE *)&val, sizeof(DWORD));
4189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4190
4191 /* InstanceType type is REG_DWORD */
4192 sz = MAX_PATH;
4193 lstrcpyA(buf, "apple");
4194 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
4195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4196 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4197 ok(sz == 2, "Expected 2, got %d\n", sz);
4198
4199 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
4200 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4201
4202 /* Transforms value exists */
4203 sz = MAX_PATH;
4204 lstrcpyA(buf, "apple");
4205 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4206 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4207 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4208 ok(sz == 0, "Expected 0, got %d\n", sz);
4209
4210 res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
4211 (const BYTE *)&val, sizeof(DWORD));
4212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4213
4214 /* Transforms type is REG_DWORD */
4215 sz = MAX_PATH;
4216 lstrcpyA(buf, "apple");
4217 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4218 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4219 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4220 ok(sz == 0, "Expected 0, got %d\n", sz);
4221
4222 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
4223 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4224
4225 /* Transforms value exists */
4226 sz = MAX_PATH;
4227 lstrcpyA(buf, "apple");
4228 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4229 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4230 ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
4231 ok(sz == 6, "Expected 6, got %d\n", sz);
4232
4233 res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
4234 (const BYTE *)&val, sizeof(DWORD));
4235 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4236
4237 /* Transforms type is REG_DWORD */
4238 sz = MAX_PATH;
4239 lstrcpyA(buf, "apple");
4240 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4241 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4242 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4243 ok(sz == 2, "Expected 2, got %d\n", sz);
4244
4245 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4246 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4247
4248 /* Language value exists */
4249 sz = MAX_PATH;
4250 lstrcpyA(buf, "apple");
4251 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
4252 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4253 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4254 ok(sz == 0, "Expected 0, got %d\n", sz);
4255
4256 res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
4257 (const BYTE *)&val, sizeof(DWORD));
4258 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4259
4260 /* Language type is REG_DWORD */
4261 sz = MAX_PATH;
4262 lstrcpyA(buf, "apple");
4263 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
4264 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4265 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4266 ok(sz == 0, "Expected 0, got %d\n", sz);
4267
4268 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4269 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4270
4271 /* Language value exists */
4272 sz = MAX_PATH;
4273 lstrcpyA(buf, "apple");
4274 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
4275 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4276 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4277 ok(sz == 4, "Expected 4, got %d\n", sz);
4278
4279 res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
4280 (const BYTE *)&val, sizeof(DWORD));
4281 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4282
4283 /* Language type is REG_DWORD */
4284 sz = MAX_PATH;
4285 lstrcpyA(buf, "apple");
4286 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
4287 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4288 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4289 ok(sz == 2, "Expected 2, got %d\n", sz);
4290
4291 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4292 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4293
4294 /* ProductName value exists */
4295 sz = MAX_PATH;
4296 lstrcpyA(buf, "apple");
4297 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4299 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4300 ok(sz == 0, "Expected 0, got %d\n", sz);
4301
4302 res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
4303 (const BYTE *)&val, sizeof(DWORD));
4304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4305
4306 /* ProductName type is REG_DWORD */
4307 sz = MAX_PATH;
4308 lstrcpyA(buf, "apple");
4309 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4311 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4312 ok(sz == 0, "Expected 0, got %d\n", sz);
4313
4314 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4315 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4316
4317 /* ProductName value exists */
4318 sz = MAX_PATH;
4319 lstrcpyA(buf, "apple");
4320 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4322 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4323 ok(sz == 4, "Expected 4, got %d\n", sz);
4324
4325 res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
4326 (const BYTE *)&val, sizeof(DWORD));
4327 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4328
4329 /* ProductName type is REG_DWORD */
4330 sz = MAX_PATH;
4331 lstrcpyA(buf, "apple");
4332 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4334 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4335 ok(sz == 2, "Expected 2, got %d\n", sz);
4336
4337 res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
4338 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4339
4340 /* Assignment value exists */
4341 sz = MAX_PATH;
4342 lstrcpyA(buf, "apple");
4343 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4344 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4345 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4346 ok(sz == 0, "Expected 0, got %d\n", sz);
4347
4348 res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
4349 (const BYTE *)&val, sizeof(DWORD));
4350 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4351
4352 /* Assignment type is REG_DWORD */
4353 sz = MAX_PATH;
4354 lstrcpyA(buf, "apple");
4355 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4357 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4358 ok(sz == 0, "Expected 0, got %d\n", sz);
4359
4360 res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
4361 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4362
4363 /* Assignment value exists */
4364 sz = MAX_PATH;
4365 lstrcpyA(buf, "apple");
4366 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4368 ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
4369 ok(sz == 2, "Expected 2, got %d\n", sz);
4370
4371 res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
4372 (const BYTE *)&val, sizeof(DWORD));
4373 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4374
4375 /* Assignment type is REG_DWORD */
4376 sz = MAX_PATH;
4377 lstrcpyA(buf, "apple");
4378 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4379 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4380 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4381 ok(sz == 2, "Expected 2, got %d\n", sz);
4382
4383 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4384 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4385
4386 /* PackageCode value exists */
4387 sz = MAX_PATH;
4388 lstrcpyA(buf, "apple");
4389 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4390 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4391 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4392 ok(sz == 0, "Expected 0, got %d\n", sz);
4393
4394 res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
4395 (const BYTE *)&val, sizeof(DWORD));
4396 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4397
4398 /* PackageCode type is REG_DWORD */
4399 sz = MAX_PATH;
4400 lstrcpyA(buf, "apple");
4401 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4403 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4404 ok(sz == 0, "Expected 0, got %d\n", sz);
4405
4406 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4407 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4408
4409 /* PackageCode value exists */
4410 sz = MAX_PATH;
4411 lstrcpyA(buf, "apple");
4412 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4413 ok(r == ERROR_BAD_CONFIGURATION,
4414 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4415 ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
4416 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4417
4418 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
4419 (const BYTE *)&val, sizeof(DWORD));
4420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4421
4422 /* PackageCode type is REG_DWORD */
4423 sz = MAX_PATH;
4424 lstrcpyA(buf, "apple");
4425 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4427 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4428 ok(sz == 2, "Expected 2, got %d\n", sz);
4429
4430 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
4431 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4432
4433 /* PackageCode value exists */
4434 sz = MAX_PATH;
4435 lstrcpyA(buf, "apple");
4436 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4438 ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
4439 ok(sz == 38, "Expected 38, got %d\n", sz);
4440
4441 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4442 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4443
4444 /* Version value exists */
4445 sz = MAX_PATH;
4446 lstrcpyA(buf, "apple");
4447 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4448 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4449 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4450 ok(sz == 0, "Expected 0, got %d\n", sz);
4451
4452 res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
4453 (const BYTE *)&val, sizeof(DWORD));
4454 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4455
4456 /* Version type is REG_DWORD */
4457 sz = MAX_PATH;
4458 lstrcpyA(buf, "apple");
4459 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4460 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4461 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4462 ok(sz == 0, "Expected 0, got %d\n", sz);
4463
4464 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4465 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4466
4467 /* Version value exists */
4468 sz = MAX_PATH;
4469 lstrcpyA(buf, "apple");
4470 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4471 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4472 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4473 ok(sz == 3, "Expected 3, got %d\n", sz);
4474
4475 res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
4476 (const BYTE *)&val, sizeof(DWORD));
4477 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4478
4479 /* Version type is REG_DWORD */
4480 sz = MAX_PATH;
4481 lstrcpyA(buf, "apple");
4482 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
4483 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4484 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4485 ok(sz == 2, "Expected 2, got %d\n", sz);
4486
4487 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4488 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4489
4490 /* ProductIcon value exists */
4491 sz = MAX_PATH;
4492 lstrcpyA(buf, "apple");
4493 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4494 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4495 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4496 ok(sz == 0, "Expected 0, got %d\n", sz);
4497
4498 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
4499 (const BYTE *)&val, sizeof(DWORD));
4500 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4501
4502 /* ProductIcon type is REG_DWORD */
4503 sz = MAX_PATH;
4504 lstrcpyA(buf, "apple");
4505 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4506 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4507 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4508 ok(sz == 0, "Expected 0, got %d\n", sz);
4509
4510 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
4511 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4512
4513 /* ProductIcon value exists */
4514 sz = MAX_PATH;
4515 lstrcpyA(buf, "apple");
4516 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4518 ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
4519 ok(sz == 3, "Expected 3, got %d\n", sz);
4520
4521 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
4522 (const BYTE *)&val, sizeof(DWORD));
4523 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4524
4525 /* ProductIcon type is REG_DWORD */
4526 sz = MAX_PATH;
4527 lstrcpyA(buf, "apple");
4528 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4529 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4530 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4531 ok(sz == 2, "Expected 2, got %d\n", sz);
4532
4533 /* SourceList key does not exist */
4534 sz = MAX_PATH;
4535 lstrcpyA(buf, "apple");
4536 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4537 ok(r == ERROR_UNKNOWN_PRODUCT,
4538 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4539 ok(!lstrcmpA(buf, "apple"),
4540 "Expected buf to be unchanged, got \"%s\"\n", buf);
4541 ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
4542
4543 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
4544 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4545
4546 /* SourceList key exists, but PackageName val does not exist */
4547 sz = MAX_PATH;
4548 lstrcpyA(buf, "apple");
4549 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4550 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4551 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4552 ok(sz == 0, "Expected 0, got %d\n", sz);
4553
4554 res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
4555 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4556
4557 /* PackageName val exists */
4558 sz = MAX_PATH;
4559 lstrcpyA(buf, "apple");
4560 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4562 ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
4563 ok(sz == 8, "Expected 8, got %d\n", sz);
4564
4565 res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
4566 (const BYTE *)&val, sizeof(DWORD));
4567 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4568
4569 /* PackageName type is REG_DWORD */
4570 sz = MAX_PATH;
4571 lstrcpyA(buf, "apple");
4572 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4573 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4574 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4575 ok(sz == 2, "Expected 2, got %d\n", sz);
4576
4577 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4578 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4579
4580 /* Authorized value exists */
4581 sz = MAX_PATH;
4582 lstrcpyA(buf, "apple");
4583 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4584 if (r != ERROR_UNKNOWN_PROPERTY)
4585 {
4586 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4587 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4588 ok(sz == 0, "Expected 0, got %d\n", sz);
4589 }
4590
4591 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
4592 (const BYTE *)&val, sizeof(DWORD));
4593 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4594
4595 /* AuthorizedLUAApp type is REG_DWORD */
4596 sz = MAX_PATH;
4597 lstrcpyA(buf, "apple");
4598 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4599 if (r != ERROR_UNKNOWN_PROPERTY)
4600 {
4601 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4602 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4603 ok(sz == 0, "Expected 0, got %d\n", sz);
4604 }
4605
4606 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4607 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4608
4609 /* Authorized value exists */
4610 sz = MAX_PATH;
4611 lstrcpyA(buf, "apple");
4612 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4613 if (r != ERROR_UNKNOWN_PROPERTY)
4614 {
4615 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4616 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4617 ok(sz == 4, "Expected 4, got %d\n", sz);
4618 }
4619
4620 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
4621 (const BYTE *)&val, sizeof(DWORD));
4622 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4623
4624 /* AuthorizedLUAApp type is REG_DWORD */
4625 sz = MAX_PATH;
4626 lstrcpyA(buf, "apple");
4627 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4628 if (r != ERROR_UNKNOWN_PROPERTY)
4629 {
4630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4631 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4632 ok(sz == 2, "Expected 2, got %d\n", sz);
4633 }
4634
4635 RegDeleteValueA(propkey, "HelpLink");
4636 RegDeleteValueA(propkey, "DisplayName");
4637 RegDeleteValueA(propkey, "DisplayVersion");
4638 RegDeleteValueA(propkey, "HelpTelephone");
4639 RegDeleteValueA(propkey, "InstallLocation");
4640 RegDeleteValueA(propkey, "InstallSource");
4641 RegDeleteValueA(propkey, "InstallDate");
4642 RegDeleteValueA(propkey, "Publisher");
4643 RegDeleteValueA(propkey, "LocalPackage");
4644 RegDeleteValueA(propkey, "UrlInfoAbout");
4645 RegDeleteValueA(propkey, "UrlUpdateInfo");
4646 RegDeleteValueA(propkey, "VersionMinor");
4647 RegDeleteValueA(propkey, "VersionMajor");
4648 RegDeleteValueA(propkey, "ProductID");
4649 RegDeleteValueA(propkey, "RegCompany");
4650 RegDeleteValueA(propkey, "RegOwner");
4651 RegDeleteValueA(propkey, "InstanceType");
4652 RegDeleteValueA(propkey, "Transforms");
4653 RegDeleteValueA(propkey, "Language");
4654 RegDeleteValueA(propkey, "ProductName");
4655 RegDeleteValueA(propkey, "Assignment");
4656 RegDeleteValueA(propkey, "PackageCode");
4657 RegDeleteValueA(propkey, "Version");
4658 RegDeleteValueA(propkey, "ProductIcon");
4659 RegDeleteValueA(propkey, "AuthorizedLUAApp");
4660 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4661 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4662 RegDeleteValueA(prodkey, "InstanceType");
4663 RegDeleteValueA(prodkey, "Transforms");
4664 RegDeleteValueA(prodkey, "Language");
4665 RegDeleteValueA(prodkey, "ProductName");
4666 RegDeleteValueA(prodkey, "Assignment");
4667 RegDeleteValueA(prodkey, "PackageCode");
4668 RegDeleteValueA(prodkey, "Version");
4669 RegDeleteValueA(prodkey, "ProductIcon");
4670 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4671 RegDeleteValueA(source, "PackageName");
4672 delete_key(source, "", access & KEY_WOW64_64KEY);
4673 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4674 RegCloseKey(propkey);
4675 RegCloseKey(localkey);
4676 RegCloseKey(source);
4677 RegCloseKey(prodkey);
4678 LocalFree(usersid);
4679 }
4680
4681 static void test_MsiGetProductInfoEx(void)
4682 {
4683 UINT r;
4684 LONG res;
4685 HKEY propkey, userkey;
4686 HKEY prodkey, localkey;
4687 CHAR prodcode[MAX_PATH];
4688 CHAR prod_squashed[MAX_PATH];
4689 CHAR packcode[MAX_PATH];
4690 CHAR pack_squashed[MAX_PATH];
4691 CHAR buf[MAX_PATH];
4692 CHAR keypath[MAX_PATH];
4693 LPSTR usersid;
4694 DWORD sz;
4695 REGSAM access = KEY_ALL_ACCESS;
4696
4697 if (!pMsiGetProductInfoExA)
4698 {
4699 win_skip("MsiGetProductInfoExA is not available\n");
4700 return;
4701 }
4702
4703 create_test_guid(prodcode, prod_squashed);
4704 create_test_guid(packcode, pack_squashed);
4705 usersid = get_user_sid();
4706
4707 if (is_wow64)
4708 access |= KEY_WOW64_64KEY;
4709
4710 /* NULL szProductCode */
4711 sz = MAX_PATH;
4712 lstrcpyA(buf, "apple");
4713 r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4714 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4715 ok(r == ERROR_INVALID_PARAMETER,
4716 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4717 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4718 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4719
4720 /* empty szProductCode */
4721 sz = MAX_PATH;
4722 lstrcpyA(buf, "apple");
4723 r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4724 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4725 ok(r == ERROR_INVALID_PARAMETER,
4726 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4727 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4728 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4729
4730 /* garbage szProductCode */
4731 sz = MAX_PATH;
4732 lstrcpyA(buf, "apple");
4733 r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4734 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4735 ok(r == ERROR_INVALID_PARAMETER,
4736 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4737 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4738 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4739
4740 /* guid without brackets */
4741 sz = MAX_PATH;
4742 lstrcpyA(buf, "apple");
4743 r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4744 MSIINSTALLCONTEXT_USERUNMANAGED,
4745 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4746 ok(r == ERROR_INVALID_PARAMETER,
4747 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4748 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4749 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4750
4751 /* guid with brackets */
4752 sz = MAX_PATH;
4753 lstrcpyA(buf, "apple");
4754 r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4755 MSIINSTALLCONTEXT_USERUNMANAGED,
4756 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4757 ok(r == ERROR_UNKNOWN_PRODUCT,
4758 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4759 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4760 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4761
4762 /* szValue is non-NULL while pcchValue is NULL */
4763 lstrcpyA(buf, "apple");
4764 r = pMsiGetProductInfoExA(prodcode, usersid,
4765 MSIINSTALLCONTEXT_USERUNMANAGED,
4766 INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4767 ok(r == ERROR_INVALID_PARAMETER,
4768 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4769 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4770
4771 /* dwContext is out of range */
4772 sz = MAX_PATH;
4773 lstrcpyA(buf, "apple");
4774 r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4775 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4776 ok(r == ERROR_INVALID_PARAMETER,
4777 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4778 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4779 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4780
4781 /* szProperty is NULL */
4782 sz = MAX_PATH;
4783 lstrcpyA(buf, "apple");
4784 r = pMsiGetProductInfoExA(prodcode, usersid,
4785 MSIINSTALLCONTEXT_USERUNMANAGED,
4786 NULL, buf, &sz);
4787 ok(r == ERROR_INVALID_PARAMETER,
4788 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4789 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4790 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4791
4792 /* szProperty is empty */
4793 sz = MAX_PATH;
4794 lstrcpyA(buf, "apple");
4795 r = pMsiGetProductInfoExA(prodcode, usersid,
4796 MSIINSTALLCONTEXT_USERUNMANAGED,
4797 "", buf, &sz);
4798 ok(r == ERROR_INVALID_PARAMETER,
4799 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4800 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4801 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4802
4803 /* szProperty is not a valid property */
4804 sz = MAX_PATH;
4805 lstrcpyA(buf, "apple");
4806 r = pMsiGetProductInfoExA(prodcode, usersid,
4807 MSIINSTALLCONTEXT_USERUNMANAGED,
4808 "notvalid", buf, &sz);
4809 ok(r == ERROR_UNKNOWN_PRODUCT,
4810 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4811 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4812 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4813
4814 /* same length as guid, but random */
4815 sz = MAX_PATH;
4816 lstrcpyA(buf, "apple");
4817 r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4818 MSIINSTALLCONTEXT_USERUNMANAGED,
4819 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4820 ok(r == ERROR_INVALID_PARAMETER,
4821 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4822 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4823 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4824
4825 /* MSIINSTALLCONTEXT_USERUNMANAGED */
4826
4827 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4828 lstrcatA(keypath, usersid);
4829 lstrcatA(keypath, "\\Products\\");
4830 lstrcatA(keypath, prod_squashed);
4831
4832 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4833 if (res == ERROR_ACCESS_DENIED)
4834 {
4835 skip("Not enough rights to perform tests\n");
4836 LocalFree(usersid);
4837 return;
4838 }
4839 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4840
4841 /* local user product key exists */
4842 sz = MAX_PATH;
4843 lstrcpyA(buf, "apple");
4844 r = pMsiGetProductInfoExA(prodcode, usersid,
4845 MSIINSTALLCONTEXT_USERUNMANAGED,
4846 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4847 ok(r == ERROR_UNKNOWN_PRODUCT,
4848 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4849 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4850 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4851
4852 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4853 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4854
4855 /* InstallProperties key exists */
4856 sz = MAX_PATH;
4857 lstrcpyA(buf, "apple");
4858 r = pMsiGetProductInfoExA(prodcode, usersid,
4859 MSIINSTALLCONTEXT_USERUNMANAGED,
4860 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4861 ok(r == ERROR_UNKNOWN_PRODUCT,
4862 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4863 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4864 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4865
4866 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4867 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4868
4869 /* LocalPackage value exists */
4870 sz = MAX_PATH;
4871 lstrcpyA(buf, "apple");
4872 r = pMsiGetProductInfoExA(prodcode, usersid,
4873 MSIINSTALLCONTEXT_USERUNMANAGED,
4874 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4875 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4876 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4877 ok(sz == 1, "Expected 1, got %d\n", sz);
4878
4879 RegDeleteValueA(propkey, "LocalPackage");
4880
4881 /* LocalPackage value must exist */
4882 sz = MAX_PATH;
4883 lstrcpyA(buf, "apple");
4884 r = pMsiGetProductInfoExA(prodcode, usersid,
4885 MSIINSTALLCONTEXT_USERUNMANAGED,
4886 INSTALLPROPERTY_HELPLINK, buf, &sz);
4887 ok(r == ERROR_UNKNOWN_PRODUCT,
4888 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4889 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4890 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4891
4892 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4893 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4894
4895 /* LocalPackage exists, but HelpLink does not exist */
4896 sz = MAX_PATH;
4897 lstrcpyA(buf, "apple");
4898 r = pMsiGetProductInfoExA(prodcode, usersid,
4899 MSIINSTALLCONTEXT_USERUNMANAGED,
4900 INSTALLPROPERTY_HELPLINK, buf, &sz);
4901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4902 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4903 ok(sz == 0, "Expected 0, got %d\n", sz);
4904
4905 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4906 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4907
4908 /* HelpLink value exists */
4909 sz = MAX_PATH;
4910 lstrcpyA(buf, "apple");
4911 r = pMsiGetProductInfoExA(prodcode, usersid,
4912 MSIINSTALLCONTEXT_USERUNMANAGED,
4913 INSTALLPROPERTY_HELPLINK, buf, &sz);
4914 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4915 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4916 ok(sz == 4, "Expected 4, got %d\n", sz);
4917
4918 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4919 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4920
4921 /* HelpTelephone value exists */
4922 sz = MAX_PATH;
4923 lstrcpyA(buf, "apple");
4924 r = pMsiGetProductInfoExA(prodcode, usersid,
4925 MSIINSTALLCONTEXT_USERUNMANAGED,
4926 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4927 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4928 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4929 ok(sz == 5, "Expected 5, got %d\n", sz);
4930
4931 /* szValue and pcchValue are NULL */
4932 r = pMsiGetProductInfoExA(prodcode, usersid,
4933 MSIINSTALLCONTEXT_USERUNMANAGED,
4934 INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4935 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4936
4937 /* pcchValue is exactly 5 */
4938 sz = 5;
4939 lstrcpyA(buf, "apple");
4940 r = pMsiGetProductInfoExA(prodcode, usersid,
4941 MSIINSTALLCONTEXT_USERUNMANAGED,
4942 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4943 ok(r == ERROR_MORE_DATA,
4944 "Expected ERROR_MORE_DATA, got %d\n", r);
4945 ok(sz == 10, "Expected 10, got %d\n", sz);
4946
4947 /* szValue is NULL, pcchValue is exactly 5 */
4948 sz = 5;
4949 r = pMsiGetProductInfoExA(prodcode, usersid,
4950 MSIINSTALLCONTEXT_USERUNMANAGED,
4951 INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4953 ok(sz == 10, "Expected 10, got %d\n", sz);
4954
4955 /* szValue is NULL, pcchValue is MAX_PATH */
4956 sz = MAX_PATH;
4957 r = pMsiGetProductInfoExA(prodcode, usersid,
4958 MSIINSTALLCONTEXT_USERUNMANAGED,
4959 INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4960 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4961 ok(sz == 10, "Expected 10, got %d\n", sz);
4962
4963 /* pcchValue is exactly 0 */
4964 sz = 0;
4965 lstrcpyA(buf, "apple");
4966 r = pMsiGetProductInfoExA(prodcode, usersid,
4967 MSIINSTALLCONTEXT_USERUNMANAGED,
4968 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4969 ok(r == ERROR_MORE_DATA,
4970 "Expected ERROR_MORE_DATA, got %d\n", r);
4971 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4972 ok(sz == 10, "Expected 10, got %d\n", sz);
4973
4974 res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4975 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4976
4977 /* szProperty is not a valid property */
4978 sz = MAX_PATH;
4979 lstrcpyA(buf, "apple");
4980 r = pMsiGetProductInfoExA(prodcode, usersid,
4981 MSIINSTALLCONTEXT_USERUNMANAGED,
4982 "notvalid", buf, &sz);
4983 ok(r == ERROR_UNKNOWN_PROPERTY,
4984 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4985 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4986 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4987
4988 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4989 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4990
4991 /* InstallDate value exists */
4992 sz = MAX_PATH;
4993 lstrcpyA(buf, "apple");
4994 r = pMsiGetProductInfoExA(prodcode, usersid,
4995 MSIINSTALLCONTEXT_USERUNMANAGED,
4996 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4997 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4998 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4999 ok(sz == 4, "Expected 4, got %d\n", sz);
5000
5001 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5002 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5003
5004 /* DisplayName value exists */
5005 sz = MAX_PATH;
5006 lstrcpyA(buf, "apple");
5007 r = pMsiGetProductInfoExA(prodcode, usersid,
5008 MSIINSTALLCONTEXT_USERUNMANAGED,
5009 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5011 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5012 ok(sz == 4, "Expected 4, got %d\n", sz);
5013
5014 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5015 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5016
5017 /* InstallLocation value exists */
5018 sz = MAX_PATH;
5019 lstrcpyA(buf, "apple");
5020 r = pMsiGetProductInfoExA(prodcode, usersid,
5021 MSIINSTALLCONTEXT_USERUNMANAGED,
5022 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5023 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5024 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5025 ok(sz == 3, "Expected 3, got %d\n", sz);
5026
5027 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5028 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5029
5030 /* InstallSource value exists */
5031 sz = MAX_PATH;
5032 lstrcpyA(buf, "apple");
5033 r = pMsiGetProductInfoExA(prodcode, usersid,
5034 MSIINSTALLCONTEXT_USERUNMANAGED,
5035 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5036 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5037 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5038 ok(sz == 6, "Expected 6, got %d\n", sz);
5039
5040 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5041 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5042
5043 /* LocalPackage value exists */
5044 sz = MAX_PATH;
5045 lstrcpyA(buf, "apple");
5046 r = pMsiGetProductInfoExA(prodcode, usersid,
5047 MSIINSTALLCONTEXT_USERUNMANAGED,
5048 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5050 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5051 ok(sz == 5, "Expected 5, got %d\n", sz);
5052
5053 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5055
5056 /* Publisher value exists */
5057 sz = MAX_PATH;
5058 lstrcpyA(buf, "apple");
5059 r = pMsiGetProductInfoExA(prodcode, usersid,
5060 MSIINSTALLCONTEXT_USERUNMANAGED,
5061 INSTALLPROPERTY_PUBLISHER, buf, &sz);
5062 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5063 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5064 ok(sz == 3, "Expected 3, got %d\n", sz);
5065
5066 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5067 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5068
5069 /* URLInfoAbout value exists */
5070 sz = MAX_PATH;
5071 lstrcpyA(buf, "apple");
5072 r = pMsiGetProductInfoExA(prodcode, usersid,
5073 MSIINSTALLCONTEXT_USERUNMANAGED,
5074 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5075 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5076 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5077 ok(sz == 5, "Expected 5, got %d\n", sz);
5078
5079 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5080 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5081
5082 /* URLUpdateInfo value exists */
5083 sz = MAX_PATH;
5084 lstrcpyA(buf, "apple");
5085 r = pMsiGetProductInfoExA(prodcode, usersid,
5086 MSIINSTALLCONTEXT_USERUNMANAGED,
5087 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5089 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5090 ok(sz == 6, "Expected 6, got %d\n", sz);
5091
5092 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5093 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5094
5095 /* VersionMinor value exists */
5096 sz = MAX_PATH;
5097 lstrcpyA(buf, "apple");
5098 r = pMsiGetProductInfoExA(prodcode, usersid,
5099 MSIINSTALLCONTEXT_USERUNMANAGED,
5100 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5102 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5103 ok(sz == 1, "Expected 1, got %d\n", sz);
5104
5105 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5106 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5107
5108 /* VersionMajor value exists */
5109 sz = MAX_PATH;
5110 lstrcpyA(buf, "apple");
5111 r = pMsiGetProductInfoExA(prodcode, usersid,
5112 MSIINSTALLCONTEXT_USERUNMANAGED,
5113 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5115 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5116 ok(sz == 1, "Expected 1, got %d\n", sz);
5117
5118 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5120
5121 /* DisplayVersion value exists */
5122 sz = MAX_PATH;
5123 lstrcpyA(buf, "apple");
5124 r = pMsiGetProductInfoExA(prodcode, usersid,
5125 MSIINSTALLCONTEXT_USERUNMANAGED,
5126 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5127 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5128 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5129 ok(sz == 5, "Expected 5, got %d\n", sz);
5130
5131 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5132 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5133
5134 /* ProductID value exists */
5135 sz = MAX_PATH;
5136 lstrcpyA(buf, "apple");
5137 r = pMsiGetProductInfoExA(prodcode, usersid,
5138 MSIINSTALLCONTEXT_USERUNMANAGED,
5139 INSTALLPROPERTY_PRODUCTID, buf, &sz);
5140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5141 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5142 ok(sz == 2, "Expected 2, got %d\n", sz);
5143
5144 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5145 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5146
5147 /* RegCompany value exists */
5148 sz = MAX_PATH;
5149 lstrcpyA(buf, "apple");
5150 r = pMsiGetProductInfoExA(prodcode, usersid,
5151 MSIINSTALLCONTEXT_USERUNMANAGED,
5152 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5154 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5155 ok(sz == 4, "Expected 4, got %d\n", sz);
5156
5157 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5158 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5159
5160 /* RegOwner value exists */
5161 sz = MAX_PATH;
5162 lstrcpyA(buf, "apple");
5163 r = pMsiGetProductInfoExA(prodcode, usersid,
5164 MSIINSTALLCONTEXT_USERUNMANAGED,
5165 INSTALLPROPERTY_REGOWNER, buf, &sz);
5166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5167 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5168 ok(sz == 5, "Expected 5, got %d\n", sz);
5169
5170 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5171 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5172
5173 /* Transforms value exists */
5174 sz = MAX_PATH;
5175 lstrcpyA(buf, "apple");
5176 r = pMsiGetProductInfoExA(prodcode, usersid,
5177 MSIINSTALLCONTEXT_USERUNMANAGED,
5178 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5179 ok(r == ERROR_UNKNOWN_PRODUCT,
5180 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5181 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5182 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5183
5184 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5185 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5186
5187 /* Language value exists */
5188 sz = MAX_PATH;
5189 lstrcpyA(buf, "apple");
5190 r = pMsiGetProductInfoExA(prodcode, usersid,
5191 MSIINSTALLCONTEXT_USERUNMANAGED,
5192 INSTALLPROPERTY_LANGUAGE, buf, &sz);
5193 ok(r == ERROR_UNKNOWN_PRODUCT,
5194 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5195 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5196 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5197
5198 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5199 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5200
5201 /* ProductName value exists */
5202 sz = MAX_PATH;
5203 lstrcpyA(buf, "apple");
5204 r = pMsiGetProductInfoExA(prodcode, usersid,
5205 MSIINSTALLCONTEXT_USERUNMANAGED,
5206 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5207 ok(r == ERROR_UNKNOWN_PRODUCT,
5208 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5209 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5210 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5211
5212 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5213 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5214
5215 /* FIXME */
5216
5217 /* AssignmentType value exists */
5218 sz = MAX_PATH;
5219 lstrcpyA(buf, "apple");
5220 r = pMsiGetProductInfoExA(prodcode, usersid,
5221 MSIINSTALLCONTEXT_USERUNMANAGED,
5222 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5223 ok(r == ERROR_UNKNOWN_PRODUCT,
5224 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5225 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5226 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5227
5228 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5229 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5230
5231 /* PackageCode value exists */
5232 sz = MAX_PATH;
5233 lstrcpyA(buf, "apple");
5234 r = pMsiGetProductInfoExA(prodcode, usersid,
5235 MSIINSTALLCONTEXT_USERUNMANAGED,
5236 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5237 ok(r == ERROR_UNKNOWN_PRODUCT,
5238 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5239 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5240 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5241
5242 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5243 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5244
5245 /* Version value exists */
5246 sz = MAX_PATH;
5247 lstrcpyA(buf, "apple");
5248 r = pMsiGetProductInfoExA(prodcode, usersid,
5249 MSIINSTALLCONTEXT_USERUNMANAGED,
5250 INSTALLPROPERTY_VERSION, buf, &sz);
5251 ok(r == ERROR_UNKNOWN_PRODUCT,
5252 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5253 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5254 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5255
5256 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5258
5259 /* ProductIcon value exists */
5260 sz = MAX_PATH;
5261 lstrcpyA(buf, "apple");
5262 r = pMsiGetProductInfoExA(prodcode, usersid,
5263 MSIINSTALLCONTEXT_USERUNMANAGED,
5264 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5265 ok(r == ERROR_UNKNOWN_PRODUCT,
5266 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5267 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5268 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5269
5270 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5272
5273 /* PackageName value exists */
5274 sz = MAX_PATH;
5275 lstrcpyA(buf, "apple");
5276 r = pMsiGetProductInfoExA(prodcode, usersid,
5277 MSIINSTALLCONTEXT_USERUNMANAGED,
5278 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5279 ok(r == ERROR_UNKNOWN_PRODUCT,
5280 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5281 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5282 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5283
5284 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5285 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5286
5287 /* AuthorizedLUAApp value exists */
5288 sz = MAX_PATH;
5289 lstrcpyA(buf, "apple");
5290 r = pMsiGetProductInfoExA(prodcode, usersid,
5291 MSIINSTALLCONTEXT_USERUNMANAGED,
5292 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5293 ok(r == ERROR_UNKNOWN_PRODUCT,
5294 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5295 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5296 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5297
5298 RegDeleteValueA(propkey, "AuthorizedLUAApp");
5299 RegDeleteValueA(propkey, "PackageName");
5300 RegDeleteValueA(propkey, "ProductIcon");
5301 RegDeleteValueA(propkey, "Version");
5302 RegDeleteValueA(propkey, "PackageCode");
5303 RegDeleteValueA(propkey, "AssignmentType");
5304 RegDeleteValueA(propkey, "ProductName");
5305 RegDeleteValueA(propkey, "Language");
5306 RegDeleteValueA(propkey, "Transforms");
5307 RegDeleteValueA(propkey, "RegOwner");
5308 RegDeleteValueA(propkey, "RegCompany");
5309 RegDeleteValueA(propkey, "ProductID");
5310 RegDeleteValueA(propkey, "DisplayVersion");
5311 RegDeleteValueA(propkey, "VersionMajor");
5312 RegDeleteValueA(propkey, "VersionMinor");
5313 RegDeleteValueA(propkey, "URLUpdateInfo");
5314 RegDeleteValueA(propkey, "URLInfoAbout");
5315 RegDeleteValueA(propkey, "Publisher");
5316 RegDeleteValueA(propkey, "LocalPackage");
5317 RegDeleteValueA(propkey, "InstallSource");
5318 RegDeleteValueA(propkey, "InstallLocation");
5319 RegDeleteValueA(propkey, "DisplayName");
5320 RegDeleteValueA(propkey, "InstallDate");
5321 RegDeleteValueA(propkey, "HelpTelephone");
5322 RegDeleteValueA(propkey, "HelpLink");
5323 RegDeleteValueA(propkey, "LocalPackage");
5324 RegDeleteKeyA(propkey, "");
5325 RegCloseKey(propkey);
5326 RegDeleteKeyA(localkey, "");
5327 RegCloseKey(localkey);
5328
5329 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5330 lstrcatA(keypath, usersid);
5331 lstrcatA(keypath, "\\Installer\\Products\\");
5332 lstrcatA(keypath, prod_squashed);
5333
5334 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5335 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5336
5337 /* user product key exists */
5338 sz = MAX_PATH;
5339 lstrcpyA(buf, "apple");
5340 r = pMsiGetProductInfoExA(prodcode, usersid,
5341 MSIINSTALLCONTEXT_USERUNMANAGED,
5342 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5343 ok(r == ERROR_UNKNOWN_PRODUCT,
5344 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5345 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5346 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5347
5348 RegDeleteKeyA(userkey, "");
5349 RegCloseKey(userkey);
5350
5351 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5352 lstrcatA(keypath, prod_squashed);
5353
5354 res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
5355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5356
5357 sz = MAX_PATH;
5358 lstrcpyA(buf, "apple");
5359 r = pMsiGetProductInfoExA(prodcode, usersid,
5360 MSIINSTALLCONTEXT_USERUNMANAGED,
5361 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5362 ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
5363 if (r == ERROR_UNKNOWN_PRODUCT)
5364 {
5365 win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
5366 delete_key(prodkey, "", access);
5367 RegCloseKey(prodkey);
5368 return;
5369 }
5370 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5371 ok(sz == 1, "Expected 1, got %d\n", sz);
5372
5373 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5375
5376 /* HelpLink value exists */
5377 sz = MAX_PATH;
5378 lstrcpyA(buf, "apple");
5379 r = pMsiGetProductInfoExA(prodcode, usersid,
5380 MSIINSTALLCONTEXT_USERUNMANAGED,
5381 INSTALLPROPERTY_HELPLINK, buf, &sz);
5382 ok(r == ERROR_UNKNOWN_PROPERTY,
5383 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5384 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5385 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5386
5387 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5388 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5389
5390 /* HelpTelephone value exists */
5391 sz = MAX_PATH;
5392 lstrcpyA(buf, "apple");
5393 r = pMsiGetProductInfoExA(prodcode, usersid,
5394 MSIINSTALLCONTEXT_USERUNMANAGED,
5395 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5396 ok(r == ERROR_UNKNOWN_PROPERTY,
5397 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5398 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5399 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5400
5401 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5402 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5403
5404 /* InstallDate value exists */
5405 sz = MAX_PATH;
5406 lstrcpyA(buf, "apple");
5407 r = pMsiGetProductInfoExA(prodcode, usersid,
5408 MSIINSTALLCONTEXT_USERUNMANAGED,
5409 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5410 ok(r == ERROR_UNKNOWN_PROPERTY,
5411 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5412 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5413 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5414
5415 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5416 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5417
5418 /* DisplayName value exists */
5419 sz = MAX_PATH;
5420 lstrcpyA(buf, "apple");
5421 r = pMsiGetProductInfoExA(prodcode, usersid,
5422 MSIINSTALLCONTEXT_USERUNMANAGED,
5423 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5424 ok(r == ERROR_UNKNOWN_PROPERTY,
5425 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5426 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5427 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5428
5429 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5430 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5431
5432 /* InstallLocation value exists */
5433 sz = MAX_PATH;
5434 lstrcpyA(buf, "apple");
5435 r = pMsiGetProductInfoExA(prodcode, usersid,
5436 MSIINSTALLCONTEXT_USERUNMANAGED,
5437 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5438 ok(r == ERROR_UNKNOWN_PROPERTY,
5439 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5440 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5441 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5442
5443 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5444 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5445
5446 /* InstallSource value exists */
5447 sz = MAX_PATH;
5448 lstrcpyA(buf, "apple");
5449 r = pMsiGetProductInfoExA(prodcode, usersid,
5450 MSIINSTALLCONTEXT_USERUNMANAGED,
5451 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5452 ok(r == ERROR_UNKNOWN_PROPERTY,
5453 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5454 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5455 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5456
5457 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5458 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5459
5460 /* LocalPackage value exists */
5461 sz = MAX_PATH;
5462 lstrcpyA(buf, "apple");
5463 r = pMsiGetProductInfoExA(prodcode, usersid,
5464 MSIINSTALLCONTEXT_USERUNMANAGED,
5465 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5466 ok(r == ERROR_UNKNOWN_PROPERTY,
5467 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5468 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5469 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5470
5471 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5472 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5473
5474 /* Publisher value exists */
5475 sz = MAX_PATH;
5476 lstrcpyA(buf, "apple");
5477 r = pMsiGetProductInfoExA(prodcode, usersid,
5478 MSIINSTALLCONTEXT_USERUNMANAGED,
5479 INSTALLPROPERTY_PUBLISHER, buf, &sz);
5480 ok(r == ERROR_UNKNOWN_PROPERTY,
5481 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5482 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5483 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5484
5485 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5486 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5487
5488 /* URLInfoAbout value exists */
5489 sz = MAX_PATH;
5490 lstrcpyA(buf, "apple");
5491 r = pMsiGetProductInfoExA(prodcode, usersid,
5492 MSIINSTALLCONTEXT_USERUNMANAGED,
5493 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5494 ok(r == ERROR_UNKNOWN_PROPERTY,
5495 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5496 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5497 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5498
5499 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5500 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5501
5502 /* URLUpdateInfo value exists */
5503 sz = MAX_PATH;
5504 lstrcpyA(buf, "apple");
5505 r = pMsiGetProductInfoExA(prodcode, usersid,
5506 MSIINSTALLCONTEXT_USERUNMANAGED,
5507 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5508 ok(r == ERROR_UNKNOWN_PROPERTY,
5509 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5510 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5511 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5512
5513 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5514 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5515
5516 /* VersionMinor value exists */
5517 sz = MAX_PATH;
5518 lstrcpyA(buf, "apple");
5519 r = pMsiGetProductInfoExA(prodcode, usersid,
5520 MSIINSTALLCONTEXT_USERUNMANAGED,
5521 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5522 ok(r == ERROR_UNKNOWN_PROPERTY,
5523 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5524 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5525 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5526
5527 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5528 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5529
5530 /* VersionMajor value exists */
5531 sz = MAX_PATH;
5532 lstrcpyA(buf, "apple");
5533 r = pMsiGetProductInfoExA(prodcode, usersid,
5534 MSIINSTALLCONTEXT_USERUNMANAGED,
5535 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5536 ok(r == ERROR_UNKNOWN_PROPERTY,
5537 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5538 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5539 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5540
5541 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5542 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5543
5544 /* DisplayVersion value exists */
5545 sz = MAX_PATH;
5546 lstrcpyA(buf, "apple");
5547 r = pMsiGetProductInfoExA(prodcode, usersid,
5548 MSIINSTALLCONTEXT_USERUNMANAGED,
5549 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5550 ok(r == ERROR_UNKNOWN_PROPERTY,
5551 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5552 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5553 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5554
5555 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5556 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5557
5558 /* ProductID value exists */
5559 sz = MAX_PATH;
5560 lstrcpyA(buf, "apple");
5561 r = pMsiGetProductInfoExA(prodcode, usersid,
5562 MSIINSTALLCONTEXT_USERUNMANAGED,
5563 INSTALLPROPERTY_PRODUCTID, buf, &sz);
5564 ok(r == ERROR_UNKNOWN_PROPERTY,
5565 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5566 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5567 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5568
5569 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5570 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5571
5572 /* RegCompany value exists */
5573 sz = MAX_PATH;
5574 lstrcpyA(buf, "apple");
5575 r = pMsiGetProductInfoExA(prodcode, usersid,
5576 MSIINSTALLCONTEXT_USERUNMANAGED,
5577 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5578 ok(r == ERROR_UNKNOWN_PROPERTY,
5579 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5580 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5581 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5582
5583 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5584 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5585
5586 /* RegOwner value exists */
5587 sz = MAX_PATH;
5588 lstrcpyA(buf, "apple");
5589 r = pMsiGetProductInfoExA(prodcode, usersid,
5590 MSIINSTALLCONTEXT_USERUNMANAGED,
5591 INSTALLPROPERTY_REGOWNER, buf, &sz);
5592 ok(r == ERROR_UNKNOWN_PROPERTY,
5593 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5594 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5595 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5596
5597 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5598 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5599
5600 /* Transforms value exists */
5601 sz = MAX_PATH;
5602 lstrcpyA(buf, "apple");
5603 r = pMsiGetProductInfoExA(prodcode, usersid,
5604 MSIINSTALLCONTEXT_USERUNMANAGED,
5605 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5606 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5607 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5608 ok(sz == 5, "Expected 5, got %d\n", sz);
5609
5610 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5611 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5612
5613 /* Language value exists */
5614 sz = MAX_PATH;
5615 lstrcpyA(buf, "apple");
5616 r = pMsiGetProductInfoExA(prodcode, usersid,
5617 MSIINSTALLCONTEXT_USERUNMANAGED,
5618 INSTALLPROPERTY_LANGUAGE, buf, &sz);
5619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5620 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5621 ok(sz == 4, "Expected 4, got %d\n", sz);
5622
5623 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5624 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5625
5626 /* ProductName value exists */
5627 sz = MAX_PATH;
5628 lstrcpyA(buf, "apple");
5629 r = pMsiGetProductInfoExA(prodcode, usersid,
5630 MSIINSTALLCONTEXT_USERUNMANAGED,
5631 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5633 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5634 ok(sz == 4, "Expected 4, got %d\n", sz);
5635
5636 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5637 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5638
5639 /* FIXME */
5640
5641 /* AssignmentType value exists */
5642 sz = MAX_PATH;
5643 lstrcpyA(buf, "apple");
5644 r = pMsiGetProductInfoExA(prodcode, usersid,
5645 MSIINSTALLCONTEXT_USERUNMANAGED,
5646 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5647 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5648 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5649 ok(sz == 0, "Expected 0, got %d\n", sz);
5650
5651 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5653
5654 /* FIXME */
5655
5656 /* PackageCode value exists */
5657 sz = MAX_PATH;
5658 lstrcpyA(buf, "apple");
5659 r = pMsiGetProductInfoExA(prodcode, usersid,
5660 MSIINSTALLCONTEXT_USERUNMANAGED,
5661 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5662 todo_wine
5663 {
5664 ok(r == ERROR_BAD_CONFIGURATION,
5665 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5666 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5667 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5668 }
5669
5670 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5671 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5672
5673 /* Version value exists */
5674 sz = MAX_PATH;
5675 lstrcpyA(buf, "apple");
5676 r = pMsiGetProductInfoExA(prodcode, usersid,
5677 MSIINSTALLCONTEXT_USERUNMANAGED,
5678 INSTALLPROPERTY_VERSION, buf, &sz);
5679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5680 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5681 ok(sz == 3, "Expected 3, got %d\n", sz);
5682
5683 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5685
5686 /* ProductIcon value exists */
5687 sz = MAX_PATH;
5688 lstrcpyA(buf, "apple");
5689 r = pMsiGetProductInfoExA(prodcode, usersid,
5690 MSIINSTALLCONTEXT_USERUNMANAGED,
5691 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5693 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5694 ok(sz == 4, "Expected 4, got %d\n", sz);
5695
5696 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5698
5699 /* PackageName value exists */
5700 sz = MAX_PATH;
5701 lstrcpyA(buf, "apple");
5702 r = pMsiGetProductInfoExA(prodcode, usersid,
5703 MSIINSTALLCONTEXT_USERUNMANAGED,
5704 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5705 todo_wine
5706 {
5707 ok(r == ERROR_UNKNOWN_PRODUCT,
5708 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5709 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5710 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5711 }
5712
5713 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5714 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5715
5716 /* AuthorizedLUAApp value exists */
5717 sz = MAX_PATH;
5718 lstrcpyA(buf, "apple");
5719 r = pMsiGetProductInfoExA(prodcode, usersid,
5720 MSIINSTALLCONTEXT_USERUNMANAGED,
5721 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5723 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5724 ok(sz == 4, "Expected 4, got %d\n", sz);
5725
5726 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5727 RegDeleteValueA(prodkey, "PackageName");
5728 RegDeleteValueA(prodkey, "ProductIcon");
5729 RegDeleteValueA(prodkey, "Version");
5730 RegDeleteValueA(prodkey, "PackageCode");
5731 RegDeleteValueA(prodkey, "AssignmentType");
5732 RegDeleteValueA(prodkey, "ProductName");
5733 RegDeleteValueA(prodkey, "Language");
5734 RegDeleteValueA(prodkey, "Transforms");
5735 RegDeleteValueA(prodkey, "RegOwner");
5736 RegDeleteValueA(prodkey, "RegCompany");
5737 RegDeleteValueA(prodkey, "ProductID");
5738 RegDeleteValueA(prodkey, "DisplayVersion");
5739 RegDeleteValueA(prodkey, "VersionMajor");
5740 RegDeleteValueA(prodkey, "VersionMinor");
5741 RegDeleteValueA(prodkey, "URLUpdateInfo");
5742 RegDeleteValueA(prodkey, "URLInfoAbout");
5743 RegDeleteValueA(prodkey, "Publisher");
5744 RegDeleteValueA(prodkey, "LocalPackage");
5745 RegDeleteValueA(prodkey, "InstallSource");
5746 RegDeleteValueA(prodkey, "InstallLocation");
5747 RegDeleteValueA(prodkey, "DisplayName");
5748 RegDeleteValueA(prodkey, "InstallDate");
5749 RegDeleteValueA(prodkey, "HelpTelephone");
5750 RegDeleteValueA(prodkey, "HelpLink");
5751 RegDeleteValueA(prodkey, "LocalPackage");
5752 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5753 RegCloseKey(prodkey);
5754
5755 /* MSIINSTALLCONTEXT_USERMANAGED */
5756
5757 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5758 lstrcatA(keypath, usersid);
5759 lstrcatA(keypath, "\\Products\\");
5760 lstrcatA(keypath, prod_squashed);
5761
5762 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5763 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5764
5765 /* local user product key exists */
5766 sz = MAX_PATH;
5767 lstrcpyA(buf, "apple");
5768 r = pMsiGetProductInfoExA(prodcode, usersid,
5769 MSIINSTALLCONTEXT_USERMANAGED,
5770 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5771 ok(r == ERROR_UNKNOWN_PRODUCT,
5772 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5773 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5774 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5775
5776 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5777 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5778
5779 /* InstallProperties key exists */
5780 sz = MAX_PATH;
5781 lstrcpyA(buf, "apple");
5782 r = pMsiGetProductInfoExA(prodcode, usersid,
5783 MSIINSTALLCONTEXT_USERMANAGED,
5784 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5785 ok(r == ERROR_UNKNOWN_PRODUCT,
5786 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5787 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5788 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5789
5790 res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5791 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5792
5793 /* ManagedLocalPackage value exists */
5794 sz = MAX_PATH;
5795 lstrcpyA(buf, "apple");
5796 r = pMsiGetProductInfoExA(prodcode, usersid,
5797 MSIINSTALLCONTEXT_USERMANAGED,
5798 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5800 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5801 ok(sz == 1, "Expected 1, got %d\n", sz);
5802
5803 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5804 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5805
5806 /* HelpLink value exists */
5807 sz = MAX_PATH;
5808 lstrcpyA(buf, "apple");
5809 r = pMsiGetProductInfoExA(prodcode, usersid,
5810 MSIINSTALLCONTEXT_USERMANAGED,
5811 INSTALLPROPERTY_HELPLINK, buf, &sz);
5812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5813 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5814 ok(sz == 4, "Expected 4, got %d\n", sz);
5815
5816 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5817 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5818
5819 /* HelpTelephone value exists */
5820 sz = MAX_PATH;
5821 lstrcpyA(buf, "apple");
5822 r = pMsiGetProductInfoExA(prodcode, usersid,
5823 MSIINSTALLCONTEXT_USERMANAGED,
5824 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5825 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5826 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5827 ok(sz == 5, "Expected 5, got %d\n", sz);
5828
5829 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5830 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5831
5832 /* InstallDate value exists */
5833 sz = MAX_PATH;
5834 lstrcpyA(buf, "apple");
5835 r = pMsiGetProductInfoExA(prodcode, usersid,
5836 MSIINSTALLCONTEXT_USERMANAGED,
5837 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5838 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5839 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5840 ok(sz == 4, "Expected 4, got %d\n", sz);
5841
5842 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5843 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5844
5845 /* DisplayName value exists */
5846 sz = MAX_PATH;
5847 lstrcpyA(buf, "apple");
5848 r = pMsiGetProductInfoExA(prodcode, usersid,
5849 MSIINSTALLCONTEXT_USERMANAGED,
5850 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5851 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5852 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5853 ok(sz == 4, "Expected 4, got %d\n", sz);
5854
5855 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5857
5858 /* InstallLocation value exists */
5859 sz = MAX_PATH;
5860 lstrcpyA(buf, "apple");
5861 r = pMsiGetProductInfoExA(prodcode, usersid,
5862 MSIINSTALLCONTEXT_USERMANAGED,
5863 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5864 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5865 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5866 ok(sz == 3, "Expected 3, got %d\n", sz);
5867
5868 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5869 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5870
5871 /* InstallSource value exists */
5872 sz = MAX_PATH;
5873 lstrcpyA(buf, "apple");
5874 r = pMsiGetProductInfoExA(prodcode, usersid,
5875 MSIINSTALLCONTEXT_USERMANAGED,
5876 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5877 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5878 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5879 ok(sz == 6, "Expected 6, got %d\n", sz);
5880
5881 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5882 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5883
5884 /* LocalPackage value exists */
5885 sz = MAX_PATH;
5886 lstrcpyA(buf, "apple");
5887 r = pMsiGetProductInfoExA(prodcode, usersid,
5888 MSIINSTALLCONTEXT_USERMANAGED,
5889 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5891 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5892 ok(sz == 5, "Expected 5, got %d\n", sz);
5893
5894 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5895 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5896
5897 /* Publisher value exists */
5898 sz = MAX_PATH;
5899 lstrcpyA(buf, "apple");
5900 r = pMsiGetProductInfoExA(prodcode, usersid,
5901 MSIINSTALLCONTEXT_USERMANAGED,
5902 INSTALLPROPERTY_PUBLISHER, buf, &sz);
5903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5904 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5905 ok(sz == 3, "Expected 3, got %d\n", sz);
5906
5907 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5908 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5909
5910 /* URLInfoAbout value exists */
5911 sz = MAX_PATH;
5912 lstrcpyA(buf, "apple");
5913 r = pMsiGetProductInfoExA(prodcode, usersid,
5914 MSIINSTALLCONTEXT_USERMANAGED,
5915 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5916 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5917 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5918 ok(sz == 5, "Expected 5, got %d\n", sz);
5919
5920 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5921 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5922
5923 /* URLUpdateInfo value exists */
5924 sz = MAX_PATH;
5925 lstrcpyA(buf, "apple");
5926 r = pMsiGetProductInfoExA(prodcode, usersid,
5927 MSIINSTALLCONTEXT_USERMANAGED,
5928 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5930 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5931 ok(sz == 6, "Expected 6, got %d\n", sz);
5932
5933 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5934 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5935
5936 /* VersionMinor value exists */
5937 sz = MAX_PATH;
5938 lstrcpyA(buf, "apple");
5939 r = pMsiGetProductInfoExA(prodcode, usersid,
5940 MSIINSTALLCONTEXT_USERMANAGED,
5941 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5943 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5944 ok(sz == 1, "Expected 1, got %d\n", sz);
5945
5946 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5948
5949 /* VersionMajor value exists */
5950 sz = MAX_PATH;
5951 lstrcpyA(buf, "apple");
5952 r = pMsiGetProductInfoExA(prodcode, usersid,
5953 MSIINSTALLCONTEXT_USERMANAGED,
5954 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5955 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5956 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5957 ok(sz == 1, "Expected 1, got %d\n", sz);
5958
5959 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5960 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5961
5962 /* DisplayVersion value exists */
5963 sz = MAX_PATH;
5964 lstrcpyA(buf, "apple");
5965 r = pMsiGetProductInfoExA(prodcode, usersid,
5966 MSIINSTALLCONTEXT_USERMANAGED,
5967 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5969 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5970 ok(sz == 5, "Expected 5, got %d\n", sz);
5971
5972 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5973 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5974
5975 /* ProductID value exists */
5976 sz = MAX_PATH;
5977 lstrcpyA(buf, "apple");
5978 r = pMsiGetProductInfoExA(prodcode, usersid,
5979 MSIINSTALLCONTEXT_USERMANAGED,
5980 INSTALLPROPERTY_PRODUCTID, buf, &sz);
5981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5982 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5983 ok(sz == 2, "Expected 2, got %d\n", sz);
5984
5985 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5986 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5987
5988 /* RegCompany value exists */
5989 sz = MAX_PATH;
5990 lstrcpyA(buf, "apple");
5991 r = pMsiGetProductInfoExA(prodcode, usersid,
5992 MSIINSTALLCONTEXT_USERMANAGED,
5993 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5994 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5995 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5996 ok(sz == 4, "Expected 4, got %d\n", sz);
5997
5998 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5999 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6000
6001 /* RegOwner value exists */
6002 sz = MAX_PATH;
6003 lstrcpyA(buf, "apple");
6004 r = pMsiGetProductInfoExA(prodcode, usersid,
6005 MSIINSTALLCONTEXT_USERMANAGED,
6006 INSTALLPROPERTY_REGOWNER, buf, &sz);
6007 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6008 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6009 ok(sz == 5, "Expected 5, got %d\n", sz);
6010
6011 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6012 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6013
6014 /* Transforms value exists */
6015 sz = MAX_PATH;
6016 lstrcpyA(buf, "apple");
6017 r = pMsiGetProductInfoExA(prodcode, usersid,
6018 MSIINSTALLCONTEXT_USERMANAGED,
6019 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6020 ok(r == ERROR_UNKNOWN_PRODUCT,
6021 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6022 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6023 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6024
6025 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6026 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6027
6028 /* Language value exists */
6029 sz = MAX_PATH;
6030 lstrcpyA(buf, "apple");
6031 r = pMsiGetProductInfoExA(prodcode, usersid,
6032 MSIINSTALLCONTEXT_USERMANAGED,
6033 INSTALLPROPERTY_LANGUAGE, buf, &sz);
6034 ok(r == ERROR_UNKNOWN_PRODUCT,
6035 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6036 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6037 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6038
6039 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6040 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6041
6042 /* ProductName value exists */
6043 sz = MAX_PATH;
6044 lstrcpyA(buf, "apple");
6045 r = pMsiGetProductInfoExA(prodcode, usersid,
6046 MSIINSTALLCONTEXT_USERMANAGED,
6047 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6048 ok(r == ERROR_UNKNOWN_PRODUCT,
6049 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6050 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6051 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6052
6053 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6055
6056 /* FIXME */
6057
6058 /* AssignmentType value exists */
6059 sz = MAX_PATH;
6060 lstrcpyA(buf, "apple");
6061 r = pMsiGetProductInfoExA(prodcode, usersid,
6062 MSIINSTALLCONTEXT_USERMANAGED,
6063 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6064 ok(r == ERROR_UNKNOWN_PRODUCT,
6065 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6066 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6067 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6068
6069 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6070 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6071
6072 /* PackageCode value exists */
6073 sz = MAX_PATH;
6074 lstrcpyA(buf, "apple");
6075 r = pMsiGetProductInfoExA(prodcode, usersid,
6076 MSIINSTALLCONTEXT_USERMANAGED,
6077 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6078 ok(r == ERROR_UNKNOWN_PRODUCT,
6079 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6080 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6081 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6082
6083 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6084 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6085
6086 /* Version value exists */
6087 sz = MAX_PATH;
6088 lstrcpyA(buf, "apple");
6089 r = pMsiGetProductInfoExA(prodcode, usersid,
6090 MSIINSTALLCONTEXT_USERMANAGED,
6091 INSTALLPROPERTY_VERSION, buf, &sz);
6092 ok(r == ERROR_UNKNOWN_PRODUCT,
6093 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6094 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6095 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6096
6097 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6098 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6099
6100 /* ProductIcon value exists */
6101 sz = MAX_PATH;
6102 lstrcpyA(buf, "apple");
6103 r = pMsiGetProductInfoExA(prodcode, usersid,
6104 MSIINSTALLCONTEXT_USERMANAGED,
6105 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6106 ok(r == ERROR_UNKNOWN_PRODUCT,
6107 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6108 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6109 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6110
6111 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6112 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6113
6114 /* PackageName value exists */
6115 sz = MAX_PATH;
6116 lstrcpyA(buf, "apple");
6117 r = pMsiGetProductInfoExA(prodcode, usersid,
6118 MSIINSTALLCONTEXT_USERMANAGED,
6119 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6120 ok(r == ERROR_UNKNOWN_PRODUCT,
6121 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6122 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6123 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6124
6125 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6126 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6127
6128 /* AuthorizedLUAApp value exists */
6129 sz = MAX_PATH;
6130 lstrcpyA(buf, "apple");
6131 r = pMsiGetProductInfoExA(prodcode, usersid,
6132 MSIINSTALLCONTEXT_USERMANAGED,
6133 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6134 ok(r == ERROR_UNKNOWN_PRODUCT,
6135 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6136 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6137 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6138
6139 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6140 RegDeleteValueA(propkey, "PackageName");
6141 RegDeleteValueA(propkey, "ProductIcon");
6142 RegDeleteValueA(propkey, "Version");
6143 RegDeleteValueA(propkey, "PackageCode");
6144 RegDeleteValueA(propkey, "AssignmentType");
6145 RegDeleteValueA(propkey, "ProductName");
6146 RegDeleteValueA(propkey, "Language");
6147 RegDeleteValueA(propkey, "Transforms");
6148 RegDeleteValueA(propkey, "RegOwner");
6149 RegDeleteValueA(propkey, "RegCompany");
6150 RegDeleteValueA(propkey, "ProductID");
6151 RegDeleteValueA(propkey, "DisplayVersion");
6152 RegDeleteValueA(propkey, "VersionMajor");
6153 RegDeleteValueA(propkey, "VersionMinor");
6154 RegDeleteValueA(propkey, "URLUpdateInfo");
6155 RegDeleteValueA(propkey, "URLInfoAbout");
6156 RegDeleteValueA(propkey, "Publisher");
6157 RegDeleteValueA(propkey, "LocalPackage");
6158 RegDeleteValueA(propkey, "InstallSource");
6159 RegDeleteValueA(propkey, "InstallLocation");
6160 RegDeleteValueA(propkey, "DisplayName");
6161 RegDeleteValueA(propkey, "InstallDate");
6162 RegDeleteValueA(propkey, "HelpTelephone");
6163 RegDeleteValueA(propkey, "HelpLink");
6164 RegDeleteValueA(propkey, "ManagedLocalPackage");
6165 delete_key(propkey, "", access & KEY_WOW64_64KEY);
6166 RegCloseKey(propkey);
6167 delete_key(localkey, "", access & KEY_WOW64_64KEY);
6168 RegCloseKey(localkey);
6169
6170 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6171 lstrcatA(keypath, usersid);
6172 lstrcatA(keypath, "\\Installer\\Products\\");
6173 lstrcatA(keypath, prod_squashed);
6174
6175 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6176 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6177
6178 /* user product key exists */
6179 sz = MAX_PATH;
6180 lstrcpyA(buf, "apple");
6181 r = pMsiGetProductInfoExA(prodcode, usersid,
6182 MSIINSTALLCONTEXT_USERMANAGED,
6183 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6184 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6185 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6186 ok(sz == 1, "Expected 1, got %d\n", sz);
6187
6188 delete_key(userkey, "", access & KEY_WOW64_64KEY);
6189 RegCloseKey(userkey);
6190
6191 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6192 lstrcatA(keypath, prod_squashed);
6193
6194 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6195 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6196
6197 /* current user product key exists */
6198 sz = MAX_PATH;
6199 lstrcpyA(buf, "apple");
6200 r = pMsiGetProductInfoExA(prodcode, usersid,
6201 MSIINSTALLCONTEXT_USERMANAGED,
6202 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6203 ok(r == ERROR_UNKNOWN_PRODUCT,
6204 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6205 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6206 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6207
6208 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6209 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6210
6211 /* HelpLink value exists, user product key does not exist */
6212 sz = MAX_PATH;
6213 lstrcpyA(buf, "apple");
6214 r = pMsiGetProductInfoExA(prodcode, usersid,
6215 MSIINSTALLCONTEXT_USERMANAGED,
6216 INSTALLPROPERTY_HELPLINK, buf, &sz);
6217 ok(r == ERROR_UNKNOWN_PRODUCT,
6218 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6219 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6220 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6221
6222 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6223 lstrcatA(keypath, usersid);
6224 lstrcatA(keypath, "\\Installer\\Products\\");
6225 lstrcatA(keypath, prod_squashed);
6226
6227 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6228 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6229
6230 res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6231 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6232
6233 /* HelpLink value exists, user product key does exist */
6234 sz = MAX_PATH;
6235 lstrcpyA(buf, "apple");
6236 r = pMsiGetProductInfoExA(prodcode, usersid,
6237 MSIINSTALLCONTEXT_USERMANAGED,
6238 INSTALLPROPERTY_HELPLINK, buf, &sz);
6239 ok(r == ERROR_UNKNOWN_PROPERTY,
6240 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6241 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6242 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6243
6244 res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6245 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6246
6247 /* HelpTelephone value exists */
6248 sz = MAX_PATH;
6249 lstrcpyA(buf, "apple");
6250 r = pMsiGetProductInfoExA(prodcode, usersid,
6251 MSIINSTALLCONTEXT_USERMANAGED,
6252 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6253 ok(r == ERROR_UNKNOWN_PROPERTY,
6254 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6255 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6256 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6257
6258 res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6259 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6260
6261 /* InstallDate value exists */
6262 sz = MAX_PATH;
6263 lstrcpyA(buf, "apple");
6264 r = pMsiGetProductInfoExA(prodcode, usersid,
6265 MSIINSTALLCONTEXT_USERMANAGED,
6266 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6267 ok(r == ERROR_UNKNOWN_PROPERTY,
6268 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6269 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6270 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6271
6272 res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6273 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6274
6275 /* DisplayName value exists */
6276 sz = MAX_PATH;
6277 lstrcpyA(buf, "apple");
6278 r = pMsiGetProductInfoExA(prodcode, usersid,
6279 MSIINSTALLCONTEXT_USERMANAGED,
6280 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6281 ok(r == ERROR_UNKNOWN_PROPERTY,
6282 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6283 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6284 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6285
6286 res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6287 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6288
6289 /* InstallLocation value exists */
6290 sz = MAX_PATH;
6291 lstrcpyA(buf, "apple");
6292 r = pMsiGetProductInfoExA(prodcode, usersid,
6293 MSIINSTALLCONTEXT_USERMANAGED,
6294 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6295 ok(r == ERROR_UNKNOWN_PROPERTY,
6296 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6297 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6298 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6299
6300 res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6301 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6302
6303 /* InstallSource value exists */
6304 sz = MAX_PATH;
6305 lstrcpyA(buf, "apple");
6306 r = pMsiGetProductInfoExA(prodcode, usersid,
6307 MSIINSTALLCONTEXT_USERMANAGED,
6308 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6309 ok(r == ERROR_UNKNOWN_PROPERTY,
6310 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6311 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6312 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6313
6314 res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6315 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6316
6317 /* LocalPackage value exists */
6318 sz = MAX_PATH;
6319 lstrcpyA(buf, "apple");
6320 r = pMsiGetProductInfoExA(prodcode, usersid,
6321 MSIINSTALLCONTEXT_USERMANAGED,
6322 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6323 ok(r == ERROR_UNKNOWN_PROPERTY,
6324 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6325 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6326 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6327
6328 res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6330
6331 /* Publisher value exists */
6332 sz = MAX_PATH;
6333 lstrcpyA(buf, "apple");
6334 r = pMsiGetProductInfoExA(prodcode, usersid,
6335 MSIINSTALLCONTEXT_USERMANAGED,
6336 INSTALLPROPERTY_PUBLISHER, buf, &sz);
6337 ok(r == ERROR_UNKNOWN_PROPERTY,
6338 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6339 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6340 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6341
6342 res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6344
6345 /* URLInfoAbout value exists */
6346 sz = MAX_PATH;
6347 lstrcpyA(buf, "apple");
6348 r = pMsiGetProductInfoExA(prodcode, usersid,
6349 MSIINSTALLCONTEXT_USERMANAGED,
6350 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6351 ok(r == ERROR_UNKNOWN_PROPERTY,
6352 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6353 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6354 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6355
6356 res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6357 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6358
6359 /* URLUpdateInfo value exists */
6360 sz = MAX_PATH;
6361 lstrcpyA(buf, "apple");
6362 r = pMsiGetProductInfoExA(prodcode, usersid,
6363 MSIINSTALLCONTEXT_USERMANAGED,
6364 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6365 ok(r == ERROR_UNKNOWN_PROPERTY,
6366 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6367 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6368 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6369
6370 res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6372
6373 /* VersionMinor value exists */
6374 sz = MAX_PATH;
6375 lstrcpyA(buf, "apple");
6376 r = pMsiGetProductInfoExA(prodcode, usersid,
6377 MSIINSTALLCONTEXT_USERMANAGED,
6378 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6379 ok(r == ERROR_UNKNOWN_PROPERTY,
6380 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6381 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6382 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6383
6384 res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6385 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6386
6387 /* VersionMajor value exists */
6388 sz = MAX_PATH;
6389 lstrcpyA(buf, "apple");
6390 r = pMsiGetProductInfoExA(prodcode, usersid,
6391 MSIINSTALLCONTEXT_USERMANAGED,
6392 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6393 ok(r == ERROR_UNKNOWN_PROPERTY,
6394 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6395 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6396 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6397
6398 res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6399 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6400
6401 /* DisplayVersion value exists */
6402 sz = MAX_PATH;
6403 lstrcpyA(buf, "apple");
6404 r = pMsiGetProductInfoExA(prodcode, usersid,
6405 MSIINSTALLCONTEXT_USERMANAGED,
6406 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6407 ok(r == ERROR_UNKNOWN_PROPERTY,
6408 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6409 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6410 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6411
6412 res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6414
6415 /* ProductID value exists */
6416 sz = MAX_PATH;
6417 lstrcpyA(buf, "apple");
6418 r = pMsiGetProductInfoExA(prodcode, usersid,
6419 MSIINSTALLCONTEXT_USERMANAGED,
6420 INSTALLPROPERTY_PRODUCTID, buf, &sz);
6421 ok(r == ERROR_UNKNOWN_PROPERTY,
6422 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6423 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6424 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6425
6426 res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6427 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6428
6429 /* RegCompany value exists */
6430 sz = MAX_PATH;
6431 lstrcpyA(buf, "apple");
6432 r = pMsiGetProductInfoExA(prodcode, usersid,
6433 MSIINSTALLCONTEXT_USERMANAGED,
6434 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6435 ok(r == ERROR_UNKNOWN_PROPERTY,
6436 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6437 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6438 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6439
6440 res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6442
6443 /* RegOwner value exists */
6444 sz = MAX_PATH;
6445 lstrcpyA(buf, "apple");
6446 r = pMsiGetProductInfoExA(prodcode, usersid,
6447 MSIINSTALLCONTEXT_USERMANAGED,
6448 INSTALLPROPERTY_REGOWNER, buf, &sz);
6449 ok(r == ERROR_UNKNOWN_PROPERTY,
6450 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6451 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6452 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6453
6454 res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6455 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6456
6457 /* Transforms value exists */
6458 sz = MAX_PATH;
6459 lstrcpyA(buf, "apple");
6460 r = pMsiGetProductInfoExA(prodcode, usersid,
6461 MSIINSTALLCONTEXT_USERMANAGED,
6462 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6463 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6464 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6465 ok(sz == 5, "Expected 5, got %d\n", sz);
6466
6467 res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6469
6470 /* Language value exists */
6471 sz = MAX_PATH;
6472 lstrcpyA(buf, "apple");
6473 r = pMsiGetProductInfoExA(prodcode, usersid,
6474 MSIINSTALLCONTEXT_USERMANAGED,
6475 INSTALLPROPERTY_LANGUAGE, buf, &sz);
6476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6477 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6478 ok(sz == 4, "Expected 4, got %d\n", sz);
6479
6480 res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6481 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6482
6483 /* ProductName value exists */
6484 sz = MAX_PATH;
6485 lstrcpyA(buf, "apple");
6486 r = pMsiGetProductInfoExA(prodcode, usersid,
6487 MSIINSTALLCONTEXT_USERMANAGED,
6488 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6489 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6490 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6491 ok(sz == 4, "Expected 4, got %d\n", sz);
6492
6493 res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6494 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6495
6496 /* FIXME */
6497
6498 /* AssignmentType value exists */
6499 sz = MAX_PATH;
6500 lstrcpyA(buf, "apple");
6501 r = pMsiGetProductInfoExA(prodcode, usersid,
6502 MSIINSTALLCONTEXT_USERMANAGED,
6503 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6504 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6505 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6506 ok(sz == 0, "Expected 0, got %d\n", sz);
6507
6508 res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6509 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6510
6511 /* FIXME */
6512
6513 /* PackageCode value exists */
6514 sz = MAX_PATH;
6515 lstrcpyA(buf, "apple");
6516 r = pMsiGetProductInfoExA(prodcode, usersid,
6517 MSIINSTALLCONTEXT_USERMANAGED,
6518 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6519 todo_wine
6520 {
6521 ok(r == ERROR_BAD_CONFIGURATION,
6522 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6523 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6524 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6525 }
6526
6527 res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6528 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6529
6530 /* Version value exists */
6531 sz = MAX_PATH;
6532 lstrcpyA(buf, "apple");
6533 r = pMsiGetProductInfoExA(prodcode, usersid,
6534 MSIINSTALLCONTEXT_USERMANAGED,
6535 INSTALLPROPERTY_VERSION, buf, &sz);
6536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6537 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6538 ok(sz == 3, "Expected 3, got %d\n", sz);
6539
6540 res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6541 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6542
6543 /* ProductIcon value exists */
6544 sz = MAX_PATH;
6545 lstrcpyA(buf, "apple");
6546 r = pMsiGetProductInfoExA(prodcode, usersid,
6547 MSIINSTALLCONTEXT_USERMANAGED,
6548 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6549 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6550 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6551 ok(sz == 4, "Expected 4, got %d\n", sz);
6552
6553 res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6554 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6555
6556 /* PackageName value exists */
6557 sz = MAX_PATH;
6558 lstrcpyA(buf, "apple");
6559 r = pMsiGetProductInfoExA(prodcode, usersid,
6560 MSIINSTALLCONTEXT_USERMANAGED,
6561 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6562 todo_wine
6563 {
6564 ok(r == ERROR_UNKNOWN_PRODUCT,
6565 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6566 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6567 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6568 }
6569
6570 res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6571 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6572
6573 /* AuthorizedLUAApp value exists */
6574 sz = MAX_PATH;
6575 lstrcpyA(buf, "apple");
6576 r = pMsiGetProductInfoExA(prodcode, usersid,
6577 MSIINSTALLCONTEXT_USERMANAGED,
6578 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6579 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6580 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6581 ok(sz == 4, "Expected 4, got %d\n", sz);
6582
6583 RegDeleteValueA(userkey, "AuthorizedLUAApp");
6584 RegDeleteValueA(userkey, "PackageName");
6585 RegDeleteValueA(userkey, "ProductIcon");
6586 RegDeleteValueA(userkey, "Version");
6587 RegDeleteValueA(userkey, "PackageCode");
6588 RegDeleteValueA(userkey, "AssignmentType");
6589 RegDeleteValueA(userkey, "ProductName");
6590 RegDeleteValueA(userkey, "Language");
6591 RegDeleteValueA(userkey, "Transforms");
6592 RegDeleteValueA(userkey, "RegOwner");
6593 RegDeleteValueA(userkey, "RegCompany");
6594 RegDeleteValueA(userkey, "ProductID");
6595 RegDeleteValueA(userkey, "DisplayVersion");
6596 RegDeleteValueA(userkey, "VersionMajor");
6597 RegDeleteValueA(userkey, "VersionMinor");
6598 RegDeleteValueA(userkey, "URLUpdateInfo");
6599 RegDeleteValueA(userkey, "URLInfoAbout");
6600 RegDeleteValueA(userkey, "Publisher");
6601 RegDeleteValueA(userkey, "LocalPackage");
6602 RegDeleteValueA(userkey, "InstallSource");
6603 RegDeleteValueA(userkey, "InstallLocation");
6604 RegDeleteValueA(userkey, "DisplayName");
6605 RegDeleteValueA(userkey, "InstallDate");
6606 RegDeleteValueA(userkey, "HelpTelephone");
6607 RegDeleteValueA(userkey, "HelpLink");
6608 delete_key(userkey, "", access & KEY_WOW64_64KEY);
6609 RegCloseKey(userkey);
6610 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6611 RegCloseKey(prodkey);
6612
6613 /* MSIINSTALLCONTEXT_MACHINE */
6614
6615 /* szUserSid is non-NULL */
6616 sz = MAX_PATH;
6617 lstrcpyA(buf, "apple");
6618 r = pMsiGetProductInfoExA(prodcode, usersid,
6619 MSIINSTALLCONTEXT_MACHINE,
6620 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6621 ok(r == ERROR_INVALID_PARAMETER,
6622 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6623 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6624 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6625
6626 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6627 lstrcatA(keypath, prod_squashed);
6628
6629 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6630 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6631
6632 /* local system product key exists */
6633 sz = MAX_PATH;
6634 lstrcpyA(buf, "apple");
6635 r = pMsiGetProductInfoExA(prodcode, NULL,
6636 MSIINSTALLCONTEXT_MACHINE,
6637 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6638 ok(r == ERROR_UNKNOWN_PRODUCT,
6639 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6640 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6641 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6642
6643 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6644 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6645
6646 /* InstallProperties key exists */
6647 sz = MAX_PATH;
6648 lstrcpyA(buf, "apple");
6649 r = pMsiGetProductInfoExA(prodcode, NULL,
6650 MSIINSTALLCONTEXT_MACHINE,
6651 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6652 ok(r == ERROR_UNKNOWN_PRODUCT,
6653 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6654 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6655 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6656
6657 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6658 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6659
6660 /* LocalPackage value exists */
6661 sz = MAX_PATH;
6662 lstrcpyA(buf, "apple");
6663 r = pMsiGetProductInfoExA(prodcode, NULL,
6664 MSIINSTALLCONTEXT_MACHINE,
6665 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6667 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6668 ok(sz == 1, "Expected 1, got %d\n", sz);
6669
6670 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6671 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6672
6673 /* HelpLink value exists */
6674 sz = MAX_PATH;
6675 lstrcpyA(buf, "apple");
6676 r = pMsiGetProductInfoExA(prodcode, NULL,
6677 MSIINSTALLCONTEXT_MACHINE,
6678 INSTALLPROPERTY_HELPLINK, buf, &sz);
6679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6680 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6681 ok(sz == 4, "Expected 4, got %d\n", sz);
6682
6683 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6685
6686 /* HelpTelephone value exists */
6687 sz = MAX_PATH;
6688 lstrcpyA(buf, "apple");
6689 r = pMsiGetProductInfoExA(prodcode, NULL,
6690 MSIINSTALLCONTEXT_MACHINE,
6691 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6693 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6694 ok(sz == 5, "Expected 5, got %d\n", sz);
6695
6696 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6698
6699 /* InstallDate value exists */
6700 sz = MAX_PATH;
6701 lstrcpyA(buf, "apple");
6702 r = pMsiGetProductInfoExA(prodcode, NULL,
6703 MSIINSTALLCONTEXT_MACHINE,
6704 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6706 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6707 ok(sz == 4, "Expected 4, got %d\n", sz);
6708
6709 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6710 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6711
6712 /* DisplayName value exists */
6713 sz = MAX_PATH;
6714 lstrcpyA(buf, "apple");
6715 r = pMsiGetProductInfoExA(prodcode, NULL,
6716 MSIINSTALLCONTEXT_MACHINE,
6717 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6719 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6720 ok(sz == 4, "Expected 4, got %d\n", sz);
6721
6722 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6723 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6724
6725 /* InstallLocation value exists */
6726 sz = MAX_PATH;
6727 lstrcpyA(buf, "apple");
6728 r = pMsiGetProductInfoExA(prodcode, NULL,
6729 MSIINSTALLCONTEXT_MACHINE,
6730 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6732 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6733 ok(sz == 3, "Expected 3, got %d\n", sz);
6734
6735 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6736 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6737
6738 /* InstallSource value exists */
6739 sz = MAX_PATH;
6740 lstrcpyA(buf, "apple");
6741 r = pMsiGetProductInfoExA(prodcode, NULL,
6742 MSIINSTALLCONTEXT_MACHINE,
6743 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6744 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6745 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6746 ok(sz == 6, "Expected 6, got %d\n", sz);
6747
6748 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6749 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6750
6751 /* LocalPackage value exists */
6752 sz = MAX_PATH;
6753 lstrcpyA(buf, "apple");
6754 r = pMsiGetProductInfoExA(prodcode, NULL,
6755 MSIINSTALLCONTEXT_MACHINE,
6756 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6758 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6759 ok(sz == 5, "Expected 5, got %d\n", sz);
6760
6761 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6762 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6763
6764 /* Publisher value exists */
6765 sz = MAX_PATH;
6766 lstrcpyA(buf, "apple");
6767 r = pMsiGetProductInfoExA(prodcode, NULL,
6768 MSIINSTALLCONTEXT_MACHINE,
6769 INSTALLPROPERTY_PUBLISHER, buf, &sz);
6770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6771 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6772 ok(sz == 3, "Expected 3, got %d\n", sz);
6773
6774 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6775 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6776
6777 /* URLInfoAbout value exists */
6778 sz = MAX_PATH;
6779 lstrcpyA(buf, "apple");
6780 r = pMsiGetProductInfoExA(prodcode, NULL,
6781 MSIINSTALLCONTEXT_MACHINE,
6782 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6784 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6785 ok(sz == 5, "Expected 5, got %d\n", sz);
6786
6787 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6788 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6789
6790 /* URLUpdateInfo value exists */
6791 sz = MAX_PATH;
6792 lstrcpyA(buf, "apple");
6793 r = pMsiGetProductInfoExA(prodcode, NULL,
6794 MSIINSTALLCONTEXT_MACHINE,
6795 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6796 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6797 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6798 ok(sz == 6, "Expected 6, got %d\n", sz);
6799
6800 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6802
6803 /* VersionMinor value exists */
6804 sz = MAX_PATH;
6805 lstrcpyA(buf, "apple");
6806 r = pMsiGetProductInfoExA(prodcode, NULL,
6807 MSIINSTALLCONTEXT_MACHINE,
6808 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6809 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6810 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6811 ok(sz == 1, "Expected 1, got %d\n", sz);
6812
6813 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6814 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6815
6816 /* VersionMajor value exists */
6817 sz = MAX_PATH;
6818 lstrcpyA(buf, "apple");
6819 r = pMsiGetProductInfoExA(prodcode, NULL,
6820 MSIINSTALLCONTEXT_MACHINE,
6821 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6823 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6824 ok(sz == 1, "Expected 1, got %d\n", sz);
6825
6826 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6827 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6828
6829 /* DisplayVersion value exists */
6830 sz = MAX_PATH;
6831 lstrcpyA(buf, "apple");
6832 r = pMsiGetProductInfoExA(prodcode, NULL,
6833 MSIINSTALLCONTEXT_MACHINE,
6834 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6836 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6837 ok(sz == 5, "Expected 5, got %d\n", sz);
6838
6839 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6841
6842 /* ProductID value exists */
6843 sz = MAX_PATH;
6844 lstrcpyA(buf, "apple");
6845 r = pMsiGetProductInfoExA(prodcode, NULL,
6846 MSIINSTALLCONTEXT_MACHINE,
6847 INSTALLPROPERTY_PRODUCTID, buf, &sz);
6848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6849 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6850 ok(sz == 2, "Expected 2, got %d\n", sz);
6851
6852 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6853 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6854
6855 /* RegCompany value exists */
6856 sz = MAX_PATH;
6857 lstrcpyA(buf, "apple");
6858 r = pMsiGetProductInfoExA(prodcode, NULL,
6859 MSIINSTALLCONTEXT_MACHINE,
6860 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6861 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6862 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6863 ok(sz == 4, "Expected 4, got %d\n", sz);
6864
6865 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6866 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6867
6868 /* RegOwner value exists */
6869 sz = MAX_PATH;
6870 lstrcpyA(buf, "apple");
6871 r = pMsiGetProductInfoExA(prodcode, NULL,
6872 MSIINSTALLCONTEXT_MACHINE,
6873 INSTALLPROPERTY_REGOWNER, buf, &sz);
6874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6875 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6876 ok(sz == 5, "Expected 5, got %d\n", sz);
6877
6878 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6879 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6880
6881 /* Transforms value exists */
6882 sz = MAX_PATH;
6883 lstrcpyA(buf, "apple");
6884 r = pMsiGetProductInfoExA(prodcode, NULL,
6885 MSIINSTALLCONTEXT_MACHINE,
6886 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6887 ok(r == ERROR_UNKNOWN_PRODUCT,
6888 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6889 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6890 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6891
6892 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6893 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6894
6895 /* Language value exists */
6896 sz = MAX_PATH;
6897 lstrcpyA(buf, "apple");
6898 r = pMsiGetProductInfoExA(prodcode, NULL,
6899 MSIINSTALLCONTEXT_MACHINE,
6900 INSTALLPROPERTY_LANGUAGE, buf, &sz);
6901 ok(r == ERROR_UNKNOWN_PRODUCT,
6902 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6903 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6904 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6905
6906 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6907 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6908
6909 /* ProductName value exists */
6910 sz = MAX_PATH;
6911 lstrcpyA(buf, "apple");
6912 r = pMsiGetProductInfoExA(prodcode, NULL,
6913 MSIINSTALLCONTEXT_MACHINE,
6914 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6915 ok(r == ERROR_UNKNOWN_PRODUCT,
6916 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6917 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6918 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6919
6920 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6921 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6922
6923 /* FIXME */
6924
6925 /* AssignmentType value exists */
6926 sz = MAX_PATH;
6927 lstrcpyA(buf, "apple");
6928 r = pMsiGetProductInfoExA(prodcode, NULL,
6929 MSIINSTALLCONTEXT_MACHINE,
6930 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6931 ok(r == ERROR_UNKNOWN_PRODUCT,
6932 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6933 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6934 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6935
6936 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6937 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6938
6939 /* PackageCode value exists */
6940 sz = MAX_PATH;
6941 lstrcpyA(buf, "apple");
6942 r = pMsiGetProductInfoExA(prodcode, NULL,
6943 MSIINSTALLCONTEXT_MACHINE,
6944 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6945 ok(r == ERROR_UNKNOWN_PRODUCT,
6946 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6947 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6948 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6949
6950 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6951 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6952
6953 /* Version value exists */
6954 sz = MAX_PATH;
6955 lstrcpyA(buf, "apple");
6956 r = pMsiGetProductInfoExA(prodcode, NULL,
6957 MSIINSTALLCONTEXT_MACHINE,
6958 INSTALLPROPERTY_VERSION, buf, &sz);
6959 ok(r == ERROR_UNKNOWN_PRODUCT,
6960 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6961 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6962 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6963
6964 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6965 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6966
6967 /* ProductIcon value exists */
6968 sz = MAX_PATH;
6969 lstrcpyA(buf, "apple");
6970 r = pMsiGetProductInfoExA(prodcode, NULL,
6971 MSIINSTALLCONTEXT_MACHINE,
6972 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6973 ok(r == ERROR_UNKNOWN_PRODUCT,
6974 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6975 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6976 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6977
6978 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6979 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6980
6981 /* PackageName value exists */
6982 sz = MAX_PATH;
6983 lstrcpyA(buf, "apple");
6984 r = pMsiGetProductInfoExA(prodcode, NULL,
6985 MSIINSTALLCONTEXT_MACHINE,
6986 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6987 ok(r == ERROR_UNKNOWN_PRODUCT,
6988 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6989 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6990 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6991
6992 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6993 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6994
6995 /* AuthorizedLUAApp value exists */
6996 sz = MAX_PATH;
6997 lstrcpyA(buf, "apple");
6998 r = pMsiGetProductInfoExA(prodcode, NULL,
6999 MSIINSTALLCONTEXT_MACHINE,
7000 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7001 ok(r == ERROR_UNKNOWN_PRODUCT,
7002 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7003 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7004 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7005
7006 RegDeleteValueA(propkey, "AuthorizedLUAApp");
7007 RegDeleteValueA(propkey, "PackageName");
7008 RegDeleteValueA(propkey, "ProductIcon");
7009 RegDeleteValueA(propkey, "Version");
7010 RegDeleteValueA(propkey, "PackageCode");
7011 RegDeleteValueA(propkey, "AssignmentType");
7012 RegDeleteValueA(propkey, "ProductName");
7013 RegDeleteValueA(propkey, "Language");
7014 RegDeleteValueA(propkey, "Transforms");
7015 RegDeleteValueA(propkey, "RegOwner");
7016 RegDeleteValueA(propkey, "RegCompany");
7017 RegDeleteValueA(propkey, "ProductID");
7018 RegDeleteValueA(propkey, "DisplayVersion");
7019 RegDeleteValueA(propkey, "VersionMajor");
7020 RegDeleteValueA(propkey, "VersionMinor");
7021 RegDeleteValueA(propkey, "URLUpdateInfo");
7022 RegDeleteValueA(propkey, "URLInfoAbout");
7023 RegDeleteValueA(propkey, "Publisher");
7024 RegDeleteValueA(propkey, "LocalPackage");
7025 RegDeleteValueA(propkey, "InstallSource");
7026 RegDeleteValueA(propkey, "InstallLocation");
7027 RegDeleteValueA(propkey, "DisplayName");
7028 RegDeleteValueA(propkey, "InstallDate");
7029 RegDeleteValueA(propkey, "HelpTelephone");
7030 RegDeleteValueA(propkey, "HelpLink");
7031 RegDeleteValueA(propkey, "LocalPackage");
7032 delete_key(propkey, "", access & KEY_WOW64_64KEY);
7033 RegCloseKey(propkey);
7034 delete_key(localkey, "", access & KEY_WOW64_64KEY);
7035 RegCloseKey(localkey);
7036
7037 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7038 lstrcatA(keypath, prod_squashed);
7039
7040 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7041 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7042
7043 /* local classes product key exists */
7044 sz = MAX_PATH;
7045 lstrcpyA(buf, "apple");
7046 r = pMsiGetProductInfoExA(prodcode, NULL,
7047 MSIINSTALLCONTEXT_MACHINE,
7048 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
7049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7050 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
7051 ok(sz == 1, "Expected 1, got %d\n", sz);
7052
7053 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7055
7056 /* HelpLink value exists */
7057 sz = MAX_PATH;
7058 lstrcpyA(buf, "apple");
7059 r = pMsiGetProductInfoExA(prodcode, NULL,
7060 MSIINSTALLCONTEXT_MACHINE,
7061 INSTALLPROPERTY_HELPLINK, buf, &sz);
7062 ok(r == ERROR_UNKNOWN_PROPERTY,
7063 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7064 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7065 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7066
7067 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7068 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7069
7070 /* HelpTelephone value exists */
7071 sz = MAX_PATH;
7072 lstrcpyA(buf, "apple");
7073 r = pMsiGetProductInfoExA(prodcode, NULL,
7074 MSIINSTALLCONTEXT_MACHINE,
7075 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
7076 ok(r == ERROR_UNKNOWN_PROPERTY,
7077 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7078 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7079 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7080
7081 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7082 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7083
7084 /* InstallDate value exists */
7085 sz = MAX_PATH;
7086 lstrcpyA(buf, "apple");
7087 r = pMsiGetProductInfoExA(prodcode, NULL,
7088 MSIINSTALLCONTEXT_MACHINE,
7089 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
7090 ok(r == ERROR_UNKNOWN_PROPERTY,
7091 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7092 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7093 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7094
7095 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7096 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7097
7098 /* DisplayName value exists */
7099 sz = MAX_PATH;
7100 lstrcpyA(buf, "apple");
7101 r = pMsiGetProductInfoExA(prodcode, NULL,
7102 MSIINSTALLCONTEXT_MACHINE,
7103 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
7104 ok(r == ERROR_UNKNOWN_PROPERTY,
7105 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7106 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7107 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7108
7109 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7110 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7111
7112 /* InstallLocation value exists */
7113 sz = MAX_PATH;
7114 lstrcpyA(buf, "apple");
7115 r = pMsiGetProductInfoExA(prodcode, NULL,
7116 MSIINSTALLCONTEXT_MACHINE,
7117 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
7118 ok(r == ERROR_UNKNOWN_PROPERTY,
7119 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7120 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7121 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7122
7123 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7124 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7125
7126 /* InstallSource value exists */
7127 sz = MAX_PATH;
7128 lstrcpyA(buf, "apple");
7129 r = pMsiGetProductInfoExA(prodcode, NULL,
7130 MSIINSTALLCONTEXT_MACHINE,
7131 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
7132 ok(r == ERROR_UNKNOWN_PROPERTY,
7133 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7134 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7135 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7136
7137 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7138 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7139
7140 /* LocalPackage value exists */
7141 sz = MAX_PATH;
7142 lstrcpyA(buf, "apple");
7143 r = pMsiGetProductInfoExA(prodcode, NULL,
7144 MSIINSTALLCONTEXT_MACHINE,
7145 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
7146 ok(r == ERROR_UNKNOWN_PROPERTY,
7147 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7148 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7149 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7150
7151 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7152 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7153
7154 /* Publisher value exists */
7155 sz = MAX_PATH;
7156 lstrcpyA(buf, "apple");
7157 r = pMsiGetProductInfoExA(prodcode, NULL,
7158 MSIINSTALLCONTEXT_MACHINE,
7159 INSTALLPROPERTY_PUBLISHER, buf, &sz);
7160 ok(r == ERROR_UNKNOWN_PROPERTY,
7161 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7162 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7163 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7164
7165 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7166 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7167
7168 /* URLInfoAbout value exists */
7169 sz = MAX_PATH;
7170 lstrcpyA(buf, "apple");
7171 r = pMsiGetProductInfoExA(prodcode, NULL,
7172 MSIINSTALLCONTEXT_MACHINE,
7173 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
7174 ok(r == ERROR_UNKNOWN_PROPERTY,
7175 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7176 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7177 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7178
7179 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7180 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7181
7182 /* URLUpdateInfo value exists */
7183 sz = MAX_PATH;
7184 lstrcpyA(buf, "apple");
7185 r = pMsiGetProductInfoExA(prodcode, NULL,
7186 MSIINSTALLCONTEXT_MACHINE,
7187 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
7188 ok(r == ERROR_UNKNOWN_PROPERTY,
7189 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7190 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7191 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7192
7193 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7194 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7195
7196 /* VersionMinor value exists */
7197 sz = MAX_PATH;
7198 lstrcpyA(buf, "apple");
7199 r = pMsiGetProductInfoExA(prodcode, NULL,
7200 MSIINSTALLCONTEXT_MACHINE,
7201 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
7202 ok(r == ERROR_UNKNOWN_PROPERTY,
7203 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7204 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7205 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7206
7207 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7208 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7209
7210 /* VersionMajor value exists */
7211 sz = MAX_PATH;
7212 lstrcpyA(buf, "apple");
7213 r = pMsiGetProductInfoExA(prodcode, NULL,
7214 MSIINSTALLCONTEXT_MACHINE,
7215 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
7216 ok(r == ERROR_UNKNOWN_PROPERTY,
7217 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7218 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7219 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7220
7221 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7222 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7223
7224 /* DisplayVersion value exists */
7225 sz = MAX_PATH;
7226 lstrcpyA(buf, "apple");
7227 r = pMsiGetProductInfoExA(prodcode, NULL,
7228 MSIINSTALLCONTEXT_MACHINE,
7229 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
7230 ok(r == ERROR_UNKNOWN_PROPERTY,
7231 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7232 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7233 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7234
7235 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7236 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7237
7238 /* ProductID value exists */
7239 sz = MAX_PATH;
7240 lstrcpyA(buf, "apple");
7241 r = pMsiGetProductInfoExA(prodcode, NULL,
7242 MSIINSTALLCONTEXT_MACHINE,
7243 INSTALLPROPERTY_PRODUCTID, buf, &sz);
7244 ok(r == ERROR_UNKNOWN_PROPERTY,
7245 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7246 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7247 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7248
7249 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7251
7252 /* RegCompany value exists */
7253 sz = MAX_PATH;
7254 lstrcpyA(buf, "apple");
7255 r = pMsiGetProductInfoExA(prodcode, NULL,
7256 MSIINSTALLCONTEXT_MACHINE,
7257 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
7258 ok(r == ERROR_UNKNOWN_PROPERTY,
7259 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7260 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7261 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7262
7263 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7264 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7265
7266 /* RegOwner value exists */
7267 sz = MAX_PATH;
7268 lstrcpyA(buf, "apple");
7269 r = pMsiGetProductInfoExA(prodcode, NULL,
7270 MSIINSTALLCONTEXT_MACHINE,
7271 INSTALLPROPERTY_REGOWNER, buf, &sz);
7272 ok(r == ERROR_UNKNOWN_PROPERTY,
7273 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7274 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7275 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7276
7277 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7279
7280 /* Transforms value exists */
7281 sz = MAX_PATH;
7282 lstrcpyA(buf, "apple");
7283 r = pMsiGetProductInfoExA(prodcode, NULL,
7284 MSIINSTALLCONTEXT_MACHINE,
7285 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
7286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7287 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
7288 ok(sz == 5, "Expected 5, got %d\n", sz);
7289
7290 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7291 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7292
7293 /* Language value exists */
7294 sz = MAX_PATH;
7295 lstrcpyA(buf, "apple");
7296 r = pMsiGetProductInfoExA(prodcode, NULL,
7297 MSIINSTALLCONTEXT_MACHINE,
7298 INSTALLPROPERTY_LANGUAGE, buf, &sz);
7299 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7300 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
7301 ok(sz == 4, "Expected 4, got %d\n", sz);
7302
7303 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7305
7306 /* ProductName value exists */
7307 sz = MAX_PATH;
7308 lstrcpyA(buf, "apple");
7309 r = pMsiGetProductInfoExA(prodcode, NULL,
7310 MSIINSTALLCONTEXT_MACHINE,
7311 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
7312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7313 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7314 ok(sz == 4, "Expected 4, got %d\n", sz);
7315
7316 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7317 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7318
7319 /* FIXME */
7320
7321 /* AssignmentType value exists */
7322 sz = MAX_PATH;
7323 lstrcpyA(buf, "apple");
7324 r = pMsiGetProductInfoExA(prodcode, NULL,
7325 MSIINSTALLCONTEXT_MACHINE,
7326 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
7327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7328 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7329 ok(sz == 0, "Expected 0, got %d\n", sz);
7330
7331 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7332 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7333
7334 /* FIXME */
7335
7336 /* PackageCode value exists */
7337 sz = MAX_PATH;
7338 lstrcpyA(buf, "apple");
7339 r = pMsiGetProductInfoExA(prodcode, NULL,
7340 MSIINSTALLCONTEXT_MACHINE,
7341 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
7342 todo_wine
7343 {
7344 ok(r == ERROR_BAD_CONFIGURATION,
7345 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7346 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7347 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7348 }
7349
7350 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7351 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7352
7353 /* Version value exists */
7354 sz = MAX_PATH;
7355 lstrcpyA(buf, "apple");
7356 r = pMsiGetProductInfoExA(prodcode, NULL,
7357 MSIINSTALLCONTEXT_MACHINE,
7358 INSTALLPROPERTY_VERSION, buf, &sz);
7359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7360 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7361 ok(sz == 3, "Expected 3, got %d\n", sz);
7362
7363 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7364 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7365
7366 /* ProductIcon value exists */
7367 sz = MAX_PATH;
7368 lstrcpyA(buf, "apple");
7369 r = pMsiGetProductInfoExA(prodcode, NULL,
7370 MSIINSTALLCONTEXT_MACHINE,
7371 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
7372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7373 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7374 ok(sz == 4, "Expected 4, got %d\n", sz);
7375
7376 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7377 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7378
7379 /* PackageName value exists */
7380 sz = MAX_PATH;
7381 lstrcpyA(buf, "apple");
7382 r = pMsiGetProductInfoExA(prodcode, NULL,
7383 MSIINSTALLCONTEXT_MACHINE,
7384 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
7385 todo_wine
7386 {
7387 ok(r == ERROR_UNKNOWN_PRODUCT,
7388 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7389 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7390 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7391 }
7392
7393 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7394 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7395
7396 /* AuthorizedLUAApp value exists */
7397 sz = MAX_PATH;
7398 lstrcpyA(buf, "apple");
7399 r = pMsiGetProductInfoExA(prodcode, NULL,
7400 MSIINSTALLCONTEXT_MACHINE,
7401 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7403 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7404 ok(sz == 4, "Expected 4, got %d\n", sz);
7405
7406 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
7407 RegDeleteValueA(prodkey, "PackageName");
7408 RegDeleteValueA(prodkey, "ProductIcon");
7409 RegDeleteValueA(prodkey, "Version");
7410 RegDeleteValueA(prodkey, "PackageCode");
7411 RegDeleteValueA(prodkey, "AssignmentType");
7412 RegDeleteValueA(prodkey, "ProductName");
7413 RegDeleteValueA(prodkey, "Language");
7414 RegDeleteValueA(prodkey, "Transforms");
7415 RegDeleteValueA(prodkey, "RegOwner");
7416 RegDeleteValueA(prodkey, "RegCompany");
7417 RegDeleteValueA(prodkey, "ProductID");
7418 RegDeleteValueA(prodkey, "DisplayVersion");
7419 RegDeleteValueA(prodkey, "VersionMajor");
7420 RegDeleteValueA(prodkey, "VersionMinor");
7421 RegDeleteValueA(prodkey, "URLUpdateInfo");
7422 RegDeleteValueA(prodkey, "URLInfoAbout");
7423 RegDeleteValueA(prodkey, "Publisher");
7424 RegDeleteValueA(prodkey, "LocalPackage");
7425 RegDeleteValueA(prodkey, "InstallSource");
7426 RegDeleteValueA(prodkey, "InstallLocation");
7427 RegDeleteValueA(prodkey, "DisplayName");
7428 RegDeleteValueA(prodkey, "InstallDate");
7429 RegDeleteValueA(prodkey, "HelpTelephone");
7430 RegDeleteValueA(prodkey, "HelpLink");
7431 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7432 RegCloseKey(prodkey);
7433 LocalFree(usersid);
7434 }
7435
7436 #define INIT_USERINFO() \
7437 lstrcpyA(user, "apple"); \
7438 lstrcpyA(org, "orange"); \
7439 lstrcpyA(serial, "banana"); \
7440 usersz = orgsz = serialsz = MAX_PATH;
7441
7442 static void test_MsiGetUserInfo(void)
7443 {
7444 USERINFOSTATE state;
7445 CHAR user[MAX_PATH];
7446 CHAR org[MAX_PATH];
7447 CHAR serial[MAX_PATH];
7448 DWORD usersz, orgsz, serialsz;
7449 CHAR keypath[MAX_PATH * 2];
7450 CHAR prodcode[MAX_PATH];
7451 CHAR prod_squashed[MAX_PATH];
7452 HKEY prodkey, userprod, props;
7453 LPSTR usersid;
7454 LONG res;
7455 REGSAM access = KEY_ALL_ACCESS;
7456
7457 create_test_guid(prodcode, prod_squashed);
7458 usersid = get_user_sid();
7459
7460 if (is_wow64)
7461 access |= KEY_WOW64_64KEY;
7462
7463 /* NULL szProduct */
7464 INIT_USERINFO();
7465 state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
7466 ok(state == USERINFOSTATE_INVALIDARG,
7467 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7468 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7469 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7470 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7471 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7472 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7473 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7474
7475 /* empty szProductCode */
7476 INIT_USERINFO();
7477 state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
7478 ok(state == USERINFOSTATE_INVALIDARG,
7479 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7480 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7481 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7482 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7483 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7484 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7485 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7486
7487 /* garbage szProductCode */
7488 INIT_USERINFO();
7489 state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
7490 ok(state == USERINFOSTATE_INVALIDARG,
7491 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7492 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7493 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7494 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7495 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7496 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7497 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7498
7499 /* guid without brackets */
7500 INIT_USERINFO();
7501 state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
7502 user, &usersz, org, &orgsz, serial, &serialsz);
7503 ok(state == USERINFOSTATE_INVALIDARG,
7504 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7505 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7506 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7507 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7508 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7509 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7510 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7511
7512 /* guid with brackets */
7513 INIT_USERINFO();
7514 state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
7515 user, &usersz, org, &orgsz, serial, &serialsz);
7516 ok(state == USERINFOSTATE_UNKNOWN,
7517 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7518 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7519 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7520 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7521 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7522 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7523 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7524
7525 /* NULL lpUserNameBuf */
7526 INIT_USERINFO();
7527 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7528 ok(state == USERINFOSTATE_UNKNOWN,
7529 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7530 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7531 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7532 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7533 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7534 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7535
7536 /* NULL pcchUserNameBuf */
7537 INIT_USERINFO();
7538 state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
7539 ok(state == USERINFOSTATE_INVALIDARG,
7540 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7541 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7542 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7543 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7544 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7545 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7546
7547 /* both lpUserNameBuf and pcchUserNameBuf NULL */
7548 INIT_USERINFO();
7549 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7550 ok(state == USERINFOSTATE_UNKNOWN,
7551 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7552 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7553 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7554 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7555 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7556
7557 /* NULL lpOrgNameBuf */
7558 INIT_USERINFO();
7559 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
7560 ok(state == USERINFOSTATE_UNKNOWN,
7561 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7562 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7563 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7564 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7565 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7566 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7567
7568 /* NULL pcchOrgNameBuf */
7569 INIT_USERINFO();
7570 state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7571 ok(state == USERINFOSTATE_INVALIDARG,
7572 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7573 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7574 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7575 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7576 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7577 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7578
7579 /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7580 INIT_USERINFO();
7581 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7582 ok(state == USERINFOSTATE_UNKNOWN,
7583 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7584 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7585 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7586 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7587 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7588
7589 /* NULL lpSerialBuf */
7590 INIT_USERINFO();
7591 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7592 ok(state == USERINFOSTATE_UNKNOWN,
7593 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7594 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7595 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7596 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7597 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7598 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7599
7600 /* NULL pcchSerialBuf */
7601 INIT_USERINFO();
7602 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7603 ok(state == USERINFOSTATE_INVALIDARG,
7604 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7605 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7606 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7607 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7608 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7609 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7610
7611 /* both lpSerialBuf and pcchSerialBuf NULL */
7612 INIT_USERINFO();
7613 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7614 ok(state == USERINFOSTATE_UNKNOWN,
7615 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7616 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7617 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7618 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7619 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7620
7621 /* MSIINSTALLCONTEXT_USERMANAGED */
7622
7623 /* create local system product key */
7624 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7625 lstrcatA(keypath, usersid);
7626 lstrcatA(keypath, "\\Installer\\Products\\");
7627 lstrcatA(keypath, prod_squashed);
7628
7629 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7630 if (res == ERROR_ACCESS_DENIED)
7631 {
7632 skip("Not enough rights to perform tests\n");
7633 LocalFree(usersid);
7634 return;
7635 }
7636 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7637
7638 /* managed product key exists */
7639 INIT_USERINFO();
7640 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7641 ok(state == USERINFOSTATE_ABSENT,
7642 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7643 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7644 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7645 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7646 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7647 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7648 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7649
7650 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7651 lstrcatA(keypath, "Installer\\UserData\\");
7652 lstrcatA(keypath, usersid);
7653 lstrcatA(keypath, "\\Products\\");
7654 lstrcatA(keypath, prod_squashed);
7655
7656 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7657 if (res == ERROR_ACCESS_DENIED)
7658 {
7659 skip("Not enough rights to perform tests\n");
7660 LocalFree(usersid);
7661 return;
7662 }
7663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7664
7665 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7666 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7667
7668 /* InstallProperties key exists */
7669 INIT_USERINFO();
7670 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7671 ok(state == USERINFOSTATE_ABSENT,
7672 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7673 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7674 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7675 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7676 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7677 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7678 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7679
7680 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7681 INIT_USERINFO();
7682 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7683 ok(state == USERINFOSTATE_ABSENT,
7684 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7685 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7686 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7687 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7688 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7689
7690 /* RegOwner, RegCompany don't exist, out params are NULL */
7691 INIT_USERINFO();
7692 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7693 ok(state == USERINFOSTATE_ABSENT,
7694 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7695 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7696 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7697
7698 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7699 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7700
7701 /* RegOwner value exists */
7702 INIT_USERINFO();
7703 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7704 ok(state == USERINFOSTATE_ABSENT,
7705 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7706 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7707 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7708 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7709 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7710 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7711 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7712
7713 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7714 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7715
7716 /* RegCompany value exists */
7717 INIT_USERINFO();
7718 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7719 ok(state == USERINFOSTATE_ABSENT,
7720 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7721 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7722 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7723 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7724 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7725 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7726 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7727
7728 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7729 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7730
7731 /* ProductID value exists */
7732 INIT_USERINFO();
7733 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7734 ok(state == USERINFOSTATE_PRESENT,
7735 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7736 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7737 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7738 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7739 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7740 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7741 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7742
7743 /* pcchUserNameBuf is too small */
7744 INIT_USERINFO();
7745 usersz = 0;
7746 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7747 ok(state == USERINFOSTATE_MOREDATA,
7748 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7749 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7750 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7751 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7752 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7753 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7754 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7755
7756 /* pcchUserNameBuf has no room for NULL terminator */
7757 INIT_USERINFO();
7758 usersz = 5;
7759 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7760 ok(state == USERINFOSTATE_MOREDATA,
7761 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7762 todo_wine
7763 {
7764 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7765 }
7766 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7767 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7768 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7769 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7770 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7771
7772 /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7773 INIT_USERINFO();
7774 usersz = 0;
7775 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7776 ok(state == USERINFOSTATE_PRESENT,
7777 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7778 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7779 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7780 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7781 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7782 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7783 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7784
7785 RegDeleteValueA(props, "ProductID");
7786 RegDeleteValueA(props, "RegCompany");
7787 RegDeleteValueA(props, "RegOwner");
7788 delete_key(props, "", access & KEY_WOW64_64KEY);
7789 RegCloseKey(props);
7790 delete_key(userprod, "", access & KEY_WOW64_64KEY);
7791 RegCloseKey(userprod);
7792 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7793 RegCloseKey(prodkey);
7794
7795 /* MSIINSTALLCONTEXT_USERUNMANAGED */
7796
7797 /* create local system product key */
7798 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7799 lstrcatA(keypath, prod_squashed);
7800
7801 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7802 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7803
7804 /* product key exists */
7805 INIT_USERINFO();
7806 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7807 ok(state == USERINFOSTATE_ABSENT,
7808 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7809 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7810 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7811 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7812 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7813 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7814 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7815
7816 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7817 lstrcatA(keypath, "Installer\\UserData\\");
7818 lstrcatA(keypath, usersid);
7819 lstrcatA(keypath, "\\Products\\");
7820 lstrcatA(keypath, prod_squashed);
7821
7822 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7823 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7824
7825 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7826 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7827
7828 /* InstallProperties key exists */
7829 INIT_USERINFO();
7830 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7831 ok(state == USERINFOSTATE_ABSENT,
7832 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7833 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7834 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7835 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7836 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7837 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7838 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7839
7840 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7841 INIT_USERINFO();
7842 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7843 ok(state == USERINFOSTATE_ABSENT,
7844 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7845 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7846 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7847 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7848 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7849
7850 /* RegOwner, RegCompany don't exist, out params are NULL */
7851 INIT_USERINFO();
7852 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7853 ok(state == USERINFOSTATE_ABSENT,
7854 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7855 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7856 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7857
7858 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7859 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7860
7861 /* RegOwner value exists */
7862 INIT_USERINFO();
7863 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7864 ok(state == USERINFOSTATE_ABSENT,
7865 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7866 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7867 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7868 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7869 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7870 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7871 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7872
7873 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7875
7876 /* RegCompany value exists */
7877 INIT_USERINFO();
7878 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7879 ok(state == USERINFOSTATE_ABSENT,
7880 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7881 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7882 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7883 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7884 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7885 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7886 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7887
7888 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7889 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7890
7891 /* ProductID value exists */
7892 INIT_USERINFO();
7893 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7894 ok(state == USERINFOSTATE_PRESENT,
7895 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7896 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7897 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7898 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7899 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7900 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7901 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7902
7903 RegDeleteValueA(props, "ProductID");
7904 RegDeleteValueA(props, "RegCompany");
7905 RegDeleteValueA(props, "RegOwner");
7906 delete_key(props, "", access & KEY_WOW64_64KEY);
7907 RegCloseKey(props);
7908 delete_key(userprod, "", access & KEY_WOW64_64KEY);
7909 RegCloseKey(userprod);
7910 RegDeleteKeyA(prodkey, "");
7911 RegCloseKey(prodkey);
7912
7913 /* MSIINSTALLCONTEXT_MACHINE */
7914
7915 /* create local system product key */
7916 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7917 lstrcatA(keypath, prod_squashed);
7918
7919 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7920 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7921
7922 /* product key exists */
7923 INIT_USERINFO();
7924 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7925 ok(state == USERINFOSTATE_ABSENT,
7926 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7927 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7928 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7929 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7930 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7931 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7932 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7933
7934 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7935 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7936 lstrcatA(keypath, "\\Products\\");
7937 lstrcatA(keypath, prod_squashed);
7938
7939 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7940 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7941
7942 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7943 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7944
7945 /* InstallProperties key exists */
7946 INIT_USERINFO();
7947 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7948 ok(state == USERINFOSTATE_ABSENT,
7949 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7950 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7951 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7952 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7953 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7954 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7955 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7956
7957 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7958 INIT_USERINFO();
7959 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7960 ok(state == USERINFOSTATE_ABSENT,
7961 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7962 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7963 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7964 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7965 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7966
7967 /* RegOwner, RegCompany don't exist, out params are NULL */
7968 INIT_USERINFO();
7969 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7970 ok(state == USERINFOSTATE_ABSENT,
7971 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7972 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7973 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7974
7975 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7977
7978 /* RegOwner value exists */
7979 INIT_USERINFO();
7980 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7981 ok(state == USERINFOSTATE_ABSENT,
7982 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7983 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7984 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7985 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7986 ok(usersz == 5, "Expected 5, got %d\n", usersz);
7987 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7988 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7989
7990 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7991 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7992
7993 /* RegCompany value exists */
7994 INIT_USERINFO();
7995 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7996 ok(state == USERINFOSTATE_ABSENT,
7997 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7998 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7999 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8000 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8001 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8002 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8003 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8004
8005 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8006 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8007
8008 /* ProductID value exists */
8009 INIT_USERINFO();
8010 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8011 ok(state == USERINFOSTATE_PRESENT,
8012 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8013 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8014 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8015 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8016 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8017 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8018 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8019
8020 RegDeleteValueA(props, "ProductID");
8021 RegDeleteValueA(props, "RegCompany");
8022 RegDeleteValueA(props, "RegOwner");
8023 delete_key(props, "", access & KEY_WOW64_64KEY);
8024 RegCloseKey(props);
8025 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8026 RegCloseKey(userprod);
8027 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8028 RegCloseKey(prodkey);
8029 LocalFree(usersid);
8030 }
8031
8032 static void test_MsiOpenProduct(void)
8033 {
8034 MSIHANDLE hprod, hdb;
8035 CHAR val[MAX_PATH];
8036 CHAR path[MAX_PATH];
8037 CHAR keypath[MAX_PATH*2];
8038 CHAR prodcode[MAX_PATH];
8039 CHAR prod_squashed[MAX_PATH];
8040 HKEY prodkey, userkey, props;
8041 LPSTR usersid;
8042 DWORD size;
8043 LONG res;
8044 UINT r;
8045 REGSAM access = KEY_ALL_ACCESS;
8046
8047 GetCurrentDirectoryA(MAX_PATH, path);
8048 lstrcatA(path, "\\");
8049
8050 create_test_guid(prodcode, prod_squashed);
8051 usersid = get_user_sid();
8052
8053 if (is_wow64)
8054 access |= KEY_WOW64_64KEY;
8055
8056 hdb = create_package_db(prodcode);
8057 MsiCloseHandle(hdb);
8058
8059 /* NULL szProduct */
8060 hprod = 0xdeadbeef;
8061 r = MsiOpenProductA(NULL, &hprod);
8062 ok(r == ERROR_INVALID_PARAMETER,
8063 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8064 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8065
8066 /* empty szProduct */
8067 hprod = 0xdeadbeef;
8068 r = MsiOpenProductA("", &hprod);
8069 ok(r == ERROR_INVALID_PARAMETER,
8070 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8071 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8072
8073 /* garbage szProduct */
8074 hprod = 0xdeadbeef;
8075 r = MsiOpenProductA("garbage", &hprod);
8076 ok(r == ERROR_INVALID_PARAMETER,
8077 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8078 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8079
8080 /* guid without brackets */
8081 hprod = 0xdeadbeef;
8082 r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
8083 ok(r == ERROR_INVALID_PARAMETER,
8084 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8085 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8086
8087 /* guid with brackets */
8088 hprod = 0xdeadbeef;
8089 r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
8090 ok(r == ERROR_UNKNOWN_PRODUCT,
8091 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8092 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8093
8094 /* same length as guid, but random */
8095 hprod = 0xdeadbeef;
8096 r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
8097 ok(r == ERROR_INVALID_PARAMETER,
8098 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8099 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8100
8101 /* hProduct is NULL */
8102 hprod = 0xdeadbeef;
8103 r = MsiOpenProductA(prodcode, NULL);
8104 ok(r == ERROR_INVALID_PARAMETER,
8105 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8106 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8107
8108 /* MSIINSTALLCONTEXT_USERMANAGED */
8109
8110 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8111 lstrcatA(keypath, "Installer\\Managed\\");
8112 lstrcatA(keypath, usersid);
8113 lstrcatA(keypath, "\\Installer\\Products\\");
8114 lstrcatA(keypath, prod_squashed);
8115
8116 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8117 if (res == ERROR_ACCESS_DENIED)
8118 {
8119 skip("Not enough rights to perform tests\n");
8120 LocalFree(usersid);
8121 return;
8122 }
8123 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8124
8125 /* managed product key exists */
8126 hprod = 0xdeadbeef;
8127 r = MsiOpenProductA(prodcode, &hprod);
8128 ok(r == ERROR_UNKNOWN_PRODUCT,
8129 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8130 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8131
8132 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8133 lstrcatA(keypath, "Installer\\UserData\\");
8134 lstrcatA(keypath, usersid);
8135 lstrcatA(keypath, "\\Products\\");
8136 lstrcatA(keypath, prod_squashed);
8137
8138 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8139 if (res == ERROR_ACCESS_DENIED)
8140 {
8141 skip("Not enough rights to perform tests\n");
8142 LocalFree(usersid);
8143 return;
8144 }
8145 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8146
8147 /* user product key exists */
8148 hprod = 0xdeadbeef;
8149 r = MsiOpenProductA(prodcode, &hprod);
8150 ok(r == ERROR_UNKNOWN_PRODUCT,
8151 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8152 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8153
8154 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8155 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8156
8157 /* InstallProperties key exists */
8158 hprod = 0xdeadbeef;
8159 r = MsiOpenProductA(prodcode, &hprod);
8160 ok(r == ERROR_UNKNOWN_PRODUCT,
8161 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8162 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8163
8164 lstrcpyA(val, path);
8165 lstrcatA(val, "\\winetest.msi");
8166 res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
8167 (const BYTE *)val, lstrlenA(val) + 1);
8168 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8169
8170 /* ManagedLocalPackage value exists */
8171 hprod = 0xdeadbeef;
8172 r = MsiOpenProductA(prodcode, &hprod);
8173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8174 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8175
8176 size = MAX_PATH;
8177 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8178 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8179 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8180 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
8181
8182 MsiCloseHandle(hprod);
8183
8184 RegDeleteValueA(props, "ManagedLocalPackage");
8185 delete_key(props, "", access & KEY_WOW64_64KEY);
8186 RegCloseKey(props);
8187 delete_key(userkey, "", access & KEY_WOW64_64KEY);
8188 RegCloseKey(userkey);
8189 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8190 RegCloseKey(prodkey);
8191
8192 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8193
8194 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8195 lstrcatA(keypath, prod_squashed);
8196
8197 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8198 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8199
8200 /* unmanaged product key exists */
8201 hprod = 0xdeadbeef;
8202 r = MsiOpenProductA(prodcode, &hprod);
8203 ok(r == ERROR_UNKNOWN_PRODUCT,
8204 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8205 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8206
8207 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8208 lstrcatA(keypath, "Installer\\UserData\\");
8209 lstrcatA(keypath, usersid);
8210 lstrcatA(keypath, "\\Products\\");
8211 lstrcatA(keypath, prod_squashed);
8212
8213 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8214 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8215
8216 /* user product key exists */
8217 hprod = 0xdeadbeef;
8218 r = MsiOpenProductA(prodcode, &hprod);
8219 ok(r == ERROR_UNKNOWN_PRODUCT,
8220 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8221 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8222
8223 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8224 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8225
8226 /* InstallProperties key exists */
8227 hprod = 0xdeadbeef;
8228 r = MsiOpenProductA(prodcode, &hprod);
8229 ok(r == ERROR_UNKNOWN_PRODUCT,
8230 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8231 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8232
8233 lstrcpyA(val, path);
8234 lstrcatA(val, "\\winetest.msi");
8235 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8236 (const BYTE *)val, lstrlenA(val) + 1);
8237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8238
8239 /* LocalPackage value exists */
8240 hprod = 0xdeadbeef;
8241 r = MsiOpenProductA(prodcode, &hprod);
8242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8243 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8244
8245 size = MAX_PATH;
8246 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8248 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8249 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
8250
8251 MsiCloseHandle(hprod);
8252
8253 RegDeleteValueA(props, "LocalPackage");
8254 delete_key(props, "", access & KEY_WOW64_64KEY);
8255 RegCloseKey(props);
8256 delete_key(userkey, "", access & KEY_WOW64_64KEY);
8257 RegCloseKey(userkey);
8258 RegDeleteKeyA(prodkey, "");
8259 RegCloseKey(prodkey);
8260
8261 /* MSIINSTALLCONTEXT_MACHINE */
8262
8263 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8264 lstrcatA(keypath, prod_squashed);
8265
8266 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8267 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8268
8269 /* managed product key exists */
8270 hprod = 0xdeadbeef;
8271 r = MsiOpenProductA(prodcode, &hprod);
8272 ok(r == ERROR_UNKNOWN_PRODUCT,
8273 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8274 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8275
8276 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8277 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8278 lstrcatA(keypath, prod_squashed);
8279
8280 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8281 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8282
8283 /* user product key exists */
8284 hprod = 0xdeadbeef;
8285 r = MsiOpenProductA(prodcode, &hprod);
8286 ok(r == ERROR_UNKNOWN_PRODUCT,
8287 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8288 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8289
8290 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8291 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8292
8293 /* InstallProperties key exists */
8294 hprod = 0xdeadbeef;
8295 r = MsiOpenProductA(prodcode, &hprod);
8296 ok(r == ERROR_UNKNOWN_PRODUCT,
8297 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8298 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8299
8300 lstrcpyA(val, path);
8301 lstrcatA(val, "\\winetest.msi");
8302 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8303 (const BYTE *)val, lstrlenA(val) + 1);
8304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8305
8306 /* LocalPackage value exists */
8307 hprod = 0xdeadbeef;
8308 r = MsiOpenProductA(prodcode, &hprod);
8309 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8310 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8311
8312 size = MAX_PATH;
8313 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8315 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8316 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
8317
8318 MsiCloseHandle(hprod);
8319
8320 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8321 (const BYTE *)"winetest.msi", 13);
8322 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8323
8324 /* LocalPackage has just the package name */
8325 hprod = 0xdeadbeef;
8326 r = MsiOpenProductA(prodcode, &hprod);
8327 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
8328 {
8329 skip("Not enough rights to perform tests\n");
8330 goto error;
8331 }
8332 ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
8333 "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
8334 if (r == ERROR_SUCCESS)
8335 MsiCloseHandle(hprod);
8336 else
8337 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8338
8339 lstrcpyA(val, path);
8340 lstrcatA(val, "\\winetest.msi");
8341 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8342 (const BYTE *)val, lstrlenA(val) + 1);
8343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8344
8345 DeleteFileA(msifile);
8346
8347 /* local package does not exist */
8348 hprod = 0xdeadbeef;
8349 r = MsiOpenProductA(prodcode, &hprod);
8350 ok(r == ERROR_UNKNOWN_PRODUCT,
8351 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8352 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8353
8354 error:
8355 RegDeleteValueA(props, "LocalPackage");
8356 delete_key(props, "", access & KEY_WOW64_64KEY);
8357 RegCloseKey(props);
8358 delete_key(userkey, "", access & KEY_WOW64_64KEY);
8359 RegCloseKey(userkey);
8360 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8361 RegCloseKey(prodkey);
8362
8363 DeleteFileA(msifile);
8364 LocalFree(usersid);
8365 }
8366
8367 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
8368 {
8369 MSIINSTALLCONTEXT context;
8370 CHAR keypath[MAX_PATH], patch[MAX_PATH];
8371 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8372 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8373 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8374 HKEY prodkey, patches, udprod, udpatch, hpatch;
8375 DWORD size, data;
8376 LONG res;
8377 UINT r;
8378 REGSAM access = KEY_ALL_ACCESS;
8379
8380 create_test_guid(prodcode, prod_squashed);
8381 create_test_guid(patch, patch_squashed);
8382
8383 if (is_wow64)
8384 access |= KEY_WOW64_64KEY;
8385
8386 /* MSIPATCHSTATE_APPLIED */
8387
8388 lstrcpyA(patchcode, "apple");
8389 lstrcpyA(targetprod, "banana");
8390 context = 0xdeadbeef;
8391 lstrcpyA(targetsid, "kiwi");
8392 size = MAX_PATH;
8393 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8394 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8395 &context, targetsid, &size);
8396 if (r == ERROR_ACCESS_DENIED)
8397 {
8398 skip("Not enough rights to perform tests\n");
8399 return;
8400 }
8401 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8402 ok(!lstrcmpA(patchcode, "apple"),
8403 "Expected patchcode to be unchanged, got %s\n", patchcode);
8404 ok(!lstrcmpA(targetprod, "banana"),
8405 "Expected targetprod to be unchanged, got %s\n", targetprod);
8406 ok(context == 0xdeadbeef,
8407 "Expected context to be unchanged, got %d\n", context);
8408 ok(!lstrcmpA(targetsid, "kiwi"),
8409 "Expected targetsid to be unchanged, got %s\n", targetsid);
8410 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8411
8412 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8413 lstrcatA(keypath, expectedsid);
8414 lstrcatA(keypath, "\\Installer\\Products\\");
8415 lstrcatA(keypath, prod_squashed);
8416
8417 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8418 if (res == ERROR_ACCESS_DENIED)
8419 {
8420 skip("Not enough rights to perform tests\n");
8421 return;
8422 }
8423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8424
8425 /* managed product key exists */
8426 lstrcpyA(patchcode, "apple");
8427 lstrcpyA(targetprod, "banana");
8428 context = 0xdeadbeef;
8429 lstrcpyA(targetsid, "kiwi");
8430 size = MAX_PATH;
8431 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8432 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8433 &context, targetsid, &size);
8434 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8435 ok(!lstrcmpA(patchcode, "apple"),
8436 "Expected patchcode to be unchanged, got %s\n", patchcode);
8437 ok(!lstrcmpA(targetprod, "banana"),
8438 "Expected targetprod to be unchanged, got %s\n", targetprod);
8439 ok(context == 0xdeadbeef,
8440 "Expected context to be unchanged, got %d\n", context);
8441 ok(!lstrcmpA(targetsid, "kiwi"),
8442 "Expected targetsid to be unchanged, got %s\n", targetsid);
8443 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8444
8445 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8446 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8447
8448 /* patches key exists */
8449 lstrcpyA(patchcode, "apple");
8450 lstrcpyA(targetprod, "banana");
8451 context = 0xdeadbeef;
8452 lstrcpyA(targetsid, "kiwi");
8453 size = MAX_PATH;
8454 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8455 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8456 &context, targetsid, &size);
8457 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8458 ok(!lstrcmpA(patchcode, "apple"),
8459 "Expected patchcode to be unchanged, got %s\n", patchcode);
8460 ok(!lstrcmpA(targetprod, "banana"),
8461 "Expected targetprod to be unchanged, got %s\n", targetprod);
8462 ok(context == 0xdeadbeef,
8463 "Expected context to be unchanged, got %d\n", context);
8464 ok(!lstrcmpA(targetsid, "kiwi"),
8465 "Expected targetsid to be unchanged, got %s\n", targetsid);
8466 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8467
8468 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8469 (const BYTE *)patch_squashed,
8470 lstrlenA(patch_squashed) + 1);
8471 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8472
8473 /* Patches value exists, is not REG_MULTI_SZ */
8474 lstrcpyA(patchcode, "apple");
8475 lstrcpyA(targetprod, "banana");
8476 context = 0xdeadbeef;
8477 lstrcpyA(targetsid, "kiwi");
8478 size = MAX_PATH;
8479 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8480 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8481 &context, targetsid, &size);
8482 ok(r == ERROR_BAD_CONFIGURATION,
8483 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8484 ok(!lstrcmpA(patchcode, "apple"),
8485 "Expected patchcode to be unchanged, got %s\n", patchcode);
8486 ok(!lstrcmpA(targetprod, "banana"),
8487 "Expected targetprod to be unchanged, got %s\n", targetprod);
8488 ok(context == 0xdeadbeef,
8489 "Expected context to be unchanged, got %d\n", context);
8490 ok(!lstrcmpA(targetsid, "kiwi"),
8491 "Expected targetsid to be unchanged, got %s\n", targetsid);
8492 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8493
8494 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8495 (const BYTE *)"a\0b\0c\0\0", 7);
8496 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8497
8498 /* Patches value exists, is not a squashed guid */
8499 lstrcpyA(patchcode, "apple");
8500 lstrcpyA(targetprod, "banana");
8501 context = 0xdeadbeef;
8502 lstrcpyA(targetsid, "kiwi");
8503 size = MAX_PATH;
8504 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8505 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8506 &context, targetsid, &size);
8507 ok(r == ERROR_BAD_CONFIGURATION,
8508 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8509 ok(!lstrcmpA(patchcode, "apple"),
8510 "Expected patchcode to be unchanged, got %s\n", patchcode);
8511 ok(!lstrcmpA(targetprod, "banana"),
8512 "Expected targetprod to be unchanged, got %s\n", targetprod);
8513 ok(context == 0xdeadbeef,
8514 "Expected context to be unchanged, got %d\n", context);
8515 ok(!lstrcmpA(targetsid, "kiwi"),
8516 "Expected targetsid to be unchanged, got %s\n", targetsid);
8517 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8518
8519 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8520 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8521 (const BYTE *)patch_squashed,
8522 lstrlenA(patch_squashed) + 2);
8523 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8524
8525 /* Patches value exists */
8526 lstrcpyA(patchcode, "apple");
8527 lstrcpyA(targetprod, "banana");
8528 context = 0xdeadbeef;
8529 lstrcpyA(targetsid, "kiwi");
8530 size = MAX_PATH;
8531 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8532 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8533 &context, targetsid, &size);
8534 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8535 ok(!lstrcmpA(patchcode, "apple"),
8536 "Expected patchcode to be unchanged, got %s\n", patchcode);
8537 ok(!lstrcmpA(targetprod, "banana"),
8538 "Expected targetprod to be unchanged, got %s\n", targetprod);
8539 ok(context == 0xdeadbeef,
8540 "Expected context to be unchanged, got %d\n", context);
8541 ok(!lstrcmpA(targetsid, "kiwi"),
8542 "Expected targetsid to be unchanged, got %s\n", targetsid);
8543 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8544
8545 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8546 (const BYTE *)"whatever", 9);
8547 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8548
8549 /* patch squashed value exists */
8550 lstrcpyA(patchcode, "apple");
8551 lstrcpyA(targetprod, "banana");
8552 context = 0xdeadbeef;
8553 lstrcpyA(targetsid, "kiwi");
8554 size = MAX_PATH;
8555 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8556 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8557 &context, targetsid, &size);
8558 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8559 ok(!lstrcmpA(patchcode, patch),
8560 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8561 ok(!lstrcmpA(targetprod, prodcode),
8562 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8563 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8564 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8565 ok(!lstrcmpA(targetsid, expectedsid),
8566 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8567 ok(size == lstrlenA(expectedsid),
8568 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8569
8570 /* increase the index */
8571 lstrcpyA(patchcode, "apple");
8572 lstrcpyA(targetprod, "banana");
8573 context = 0xdeadbeef;
8574 lstrcpyA(targetsid, "kiwi");
8575 size = MAX_PATH;
8576 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8577 MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
8578 &context, targetsid, &size);
8579 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8580 ok(!lstrcmpA(patchcode, "apple"),
8581 "Expected patchcode to be unchanged, got %s\n", patchcode);
8582 ok(!lstrcmpA(targetprod, "banana"),
8583 "Expected targetprod to be unchanged, got %s\n", targetprod);
8584 ok(context == 0xdeadbeef,
8585 "Expected context to be unchanged, got %d\n", context);
8586 ok(!lstrcmpA(targetsid, "kiwi"),
8587 "Expected targetsid to be unchanged, got %s\n", targetsid);
8588 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8589
8590 /* increase again */
8591 lstrcpyA(patchcode, "apple");
8592 lstrcpyA(targetprod, "banana");
8593 context = 0xdeadbeef;
8594 lstrcpyA(targetsid, "kiwi");
8595 size = MAX_PATH;
8596 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8597 MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8598 &context, targetsid, &size);
8599 ok(r == ERROR_INVALID_PARAMETER,
8600 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8601 ok(!lstrcmpA(patchcode, "apple"),
8602 "Expected patchcode to be unchanged, got %s\n", patchcode);
8603 ok(!lstrcmpA(targetprod, "banana"),
8604 "Expected targetprod to be unchanged, got %s\n", targetprod);
8605 ok(context == 0xdeadbeef,
8606 "Expected context to be unchanged, got %d\n", context);
8607 ok(!lstrcmpA(targetsid, "kiwi"),
8608 "Expected targetsid to be unchanged, got %s\n", targetsid);
8609 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8610
8611 /* szPatchCode is NULL */
8612 lstrcpyA(targetprod, "banana");
8613 context = 0xdeadbeef;
8614 lstrcpyA(targetsid, "kiwi");
8615 size = MAX_PATH;
8616 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8617 MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8618 &context, targetsid, &size);
8619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8620 ok(!lstrcmpA(targetprod, prodcode),
8621 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8622 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8623 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8624 ok(!lstrcmpA(targetsid, expectedsid),
8625 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8626 ok(size == lstrlenA(expectedsid),
8627 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8628
8629 /* szTargetProductCode is NULL */
8630 lstrcpyA(patchcode, "apple");
8631 context = 0xdeadbeef;
8632 lstrcpyA(targetsid, "kiwi");
8633 size = MAX_PATH;
8634 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8635 MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8636 &context, targetsid, &size);
8637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8638 ok(!lstrcmpA(patchcode, patch),
8639 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8640 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8641 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8642 ok(!lstrcmpA(targetsid, expectedsid),
8643 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8644 ok(size == lstrlenA(expectedsid),
8645 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8646
8647 /* pdwTargetProductContext is NULL */
8648 lstrcpyA(patchcode, "apple");
8649 lstrcpyA(targetprod, "banana");
8650 lstrcpyA(targetsid, "kiwi");
8651 size = MAX_PATH;
8652 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8653 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8654 NULL, targetsid, &size);
8655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8656 ok(!lstrcmpA(patchcode, patch),
8657 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8658 ok(!lstrcmpA(targetprod, prodcode),
8659 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8660 ok(!lstrcmpA(targetsid, expectedsid),
8661 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8662 ok(size == lstrlenA(expectedsid),
8663 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8664
8665 /* szTargetUserSid is NULL */
8666 lstrcpyA(patchcode, "apple");
8667 lstrcpyA(targetprod, "banana");
8668 context = 0xdeadbeef;
8669 size = MAX_PATH;
8670 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8671 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8672 &context, NULL, &size);
8673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8674 ok(!lstrcmpA(patchcode, patch),
8675 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8676 ok(!lstrcmpA(targetprod, prodcode),
8677 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8678 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8679 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8680 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8681 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8682
8683 /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8684 lstrcpyA(patchcode, "apple");
8685 lstrcpyA(targetprod, "banana");
8686 context = 0xdeadbeef;
8687 lstrcpyA(targetsid, "kiwi");
8688 size = lstrlenA(expectedsid);
8689 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8690 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8691 &context, targetsid, &size);
8692 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8693 ok(!lstrcmpA(patchcode, patch),
8694 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8695 ok(!lstrcmpA(targetprod, prodcode),
8696 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8697 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8698 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8699 ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8700 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8701 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8702 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8703
8704 /* pcchTargetUserSid has enough room for NULL terminator */
8705 lstrcpyA(patchcode, "apple");
8706 lstrcpyA(targetprod, "banana");
8707 context = 0xdeadbeef;
8708 lstrcpyA(targetsid, "kiwi");
8709 size = lstrlenA(expectedsid) + 1;
8710 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8711 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8712 &context, targetsid, &size);
8713 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8714 ok(!lstrcmpA(patchcode, patch),
8715 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8716 ok(!lstrcmpA(targetprod, prodcode),
8717 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8718 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8719 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8720 ok(!lstrcmpA(targetsid, expectedsid),
8721 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8722 ok(size == lstrlenA(expectedsid),
8723 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8724
8725 /* both szTargetuserSid and pcchTargetUserSid are NULL */
8726 lstrcpyA(patchcode, "apple");
8727 lstrcpyA(targetprod, "banana");
8728 context = 0xdeadbeef;
8729 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8730 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8731 &context, NULL, NULL);
8732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8733 ok(!lstrcmpA(patchcode, patch),
8734 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8735 ok(!lstrcmpA(targetprod, prodcode),
8736 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8737 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8738 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8739
8740 /* MSIPATCHSTATE_SUPERSEDED */
8741
8742 lstrcpyA(patchcode, "apple");
8743 lstrcpyA(targetprod, "banana");
8744 context = 0xdeadbeef;
8745 lstrcpyA(targetsid, "kiwi");
8746 size = MAX_PATH;
8747 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8748 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8749 &context, targetsid, &size);
8750 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8751 ok(!lstrcmpA(patchcode, "apple"),
8752 "Expected patchcode to be unchanged, got %s\n", patchcode);
8753 ok(!lstrcmpA(targetprod, "banana"),
8754 "Expected targetprod to be unchanged, got %s\n", targetprod);
8755 ok(context == 0xdeadbeef,
8756 "Expected context to be unchanged, got %d\n", context);
8757 ok(!lstrcmpA(targetsid, "kiwi"),
8758 "Expected targetsid to be unchanged, got %s\n", targetsid);
8759 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8760
8761 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8762 lstrcatA(keypath, expectedsid);
8763 lstrcatA(keypath, "\\Products\\");
8764 lstrcatA(keypath, prod_squashed);
8765
8766 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8767 if (res == ERROR_ACCESS_DENIED)
8768 {
8769 skip("Not enough rights to perform tests\n");
8770 return;
8771 }
8772 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8773
8774 /* UserData product key exists */
8775 lstrcpyA(patchcode, "apple");
8776 lstrcpyA(targetprod, "banana");
8777 context = 0xdeadbeef;
8778 lstrcpyA(targetsid, "kiwi");
8779 size = MAX_PATH;
8780 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8781 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8782 &context, targetsid, &size);
8783 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8784 ok(!lstrcmpA(patchcode, "apple"),
8785 "Expected patchcode to be unchanged, got %s\n", patchcode);
8786 ok(!lstrcmpA(targetprod, "banana"),
8787 "Expected targetprod to be unchanged, got %s\n", targetprod);
8788 ok(context == 0xdeadbeef,
8789 "Expected context to be unchanged, got %d\n", context);
8790 ok(!lstrcmpA(targetsid, "kiwi"),
8791 "Expected targetsid to be unchanged, got %s\n", targetsid);
8792 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8793
8794 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8795 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8796
8797 /* UserData patches key exists */
8798 lstrcpyA(patchcode, "apple");
8799 lstrcpyA(targetprod, "banana");
8800 context = 0xdeadbeef;
8801 lstrcpyA(targetsid, "kiwi");
8802 size = MAX_PATH;
8803 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8804 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8805 &context, targetsid, &size);
8806 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8807 ok(!lstrcmpA(patchcode, "apple"),
8808 "Expected patchcode to be unchanged, got %s\n", patchcode);
8809 ok(!lstrcmpA(targetprod, "banana"),
8810 "Expected targetprod to be unchanged, got %s\n", targetprod);
8811 ok(context == 0xdeadbeef,
8812 "Expected context to be unchanged, got %d\n", context);
8813 ok(!lstrcmpA(targetsid, "kiwi"),
8814 "Expected targetsid to be unchanged, got %s\n", targetsid);
8815 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8816
8817 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8818 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8819
8820 /* specific UserData patch key exists */
8821 lstrcpyA(patchcode, "apple");
8822 lstrcpyA(targetprod, "banana");
8823 context = 0xdeadbeef;
8824 lstrcpyA(targetsid, "kiwi");
8825 size = MAX_PATH;
8826 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8827 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8828 &context, targetsid, &size);
8829 ok(r == ERROR_BAD_CONFIGURATION,
8830 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8831 ok(!lstrcmpA(patchcode, "apple"),
8832 "Expected patchcode to be unchanged, got %s\n", patchcode);
8833 ok(!lstrcmpA(targetprod, "banana"),
8834 "Expected targetprod to be unchanged, got %s\n", targetprod);
8835 ok(context == 0xdeadbeef,
8836 "Expected context to be unchanged, got %d\n", context);
8837 ok(!lstrcmpA(targetsid, "kiwi"),
8838 "Expected targetsid to be unchanged, got %s\n", targetsid);
8839 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8840
8841 data = MSIPATCHSTATE_SUPERSEDED;
8842 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8843 (const BYTE *)&data, sizeof(DWORD));
8844 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8845
8846 /* State value exists */
8847 lstrcpyA(patchcode, "apple");
8848 lstrcpyA(targetprod, "banana");
8849 context = 0xdeadbeef;
8850 lstrcpyA(targetsid, "kiwi");
8851 size = MAX_PATH;
8852 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8853 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8854 &context, targetsid, &size);
8855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8856 ok(!lstrcmpA(patchcode, patch),
8857 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8858 ok(!lstrcmpA(targetprod, prodcode),
8859 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8860 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8861 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8862 ok(!lstrcmpA(targetsid, expectedsid),
8863 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8864 ok(size == lstrlenA(expectedsid),
8865 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8866
8867 /* MSIPATCHSTATE_OBSOLETED */
8868
8869 lstrcpyA(patchcode, "apple");
8870 lstrcpyA(targetprod, "banana");
8871 context = 0xdeadbeef;
8872 lstrcpyA(targetsid, "kiwi");
8873 size = MAX_PATH;
8874 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8875 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8876 &context, targetsid, &size);
8877 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8878 ok(!lstrcmpA(patchcode, "apple"),
8879 "Expected patchcode to be unchanged, got %s\n", patchcode);
8880 ok(!lstrcmpA(targetprod, "banana"),
8881 "Expected targetprod to be unchanged, got %s\n", targetprod);
8882 ok(context == 0xdeadbeef,
8883 "Expected context to be unchanged, got %d\n", context);
8884 ok(!lstrcmpA(targetsid, "kiwi"),
8885 "Expected targetsid to be unchanged, got %s\n", targetsid);
8886 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8887
8888 data = MSIPATCHSTATE_OBSOLETED;
8889 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8890 (const BYTE *)&data, sizeof(DWORD));
8891 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8892
8893 /* State value is obsoleted */
8894 lstrcpyA(patchcode, "apple");
8895 lstrcpyA(targetprod, "banana");
8896 context = 0xdeadbeef;
8897 lstrcpyA(targetsid, "kiwi");
8898 size = MAX_PATH;
8899 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8900 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8901 &context, targetsid, &size);
8902 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8903 ok(!lstrcmpA(patchcode, patch),
8904 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8905 ok(!lstrcmpA(targetprod, prodcode),
8906 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8907 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8908 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8909 ok(!lstrcmpA(targetsid, expectedsid),
8910 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8911 ok(size == lstrlenA(expectedsid),
8912 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8913
8914 /* MSIPATCHSTATE_REGISTERED */
8915 /* FIXME */
8916
8917 /* MSIPATCHSTATE_ALL */
8918
8919 /* 1st */
8920 lstrcpyA(patchcode, "apple");
8921 lstrcpyA(targetprod, "banana");
8922 context = 0xdeadbeef;
8923 lstrcpyA(targetsid, "kiwi");
8924 size = MAX_PATH;
8925 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8926 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8927 &context, targetsid, &size);
8928 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8929 ok(!lstrcmpA(patchcode, patch),
8930 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8931 ok(!lstrcmpA(targetprod, prodcode),
8932 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8933 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8934 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8935 ok(!lstrcmpA(targetsid, expectedsid),
8936 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8937 ok(size == lstrlenA(expectedsid),
8938 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8939
8940 /* same patch in multiple places, only one is enumerated */
8941 lstrcpyA(patchcode, "apple");
8942 lstrcpyA(targetprod, "banana");
8943 context = 0xdeadbeef;
8944 lstrcpyA(targetsid, "kiwi");
8945 size = MAX_PATH;
8946 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8947 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8948 &context, targetsid, &size);
8949 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8950 ok(!lstrcmpA(patchcode, "apple"),
8951 "Expected patchcode to be unchanged, got %s\n", patchcode);
8952 ok(!lstrcmpA(targetprod, "banana"),
8953 "Expected targetprod to be unchanged, got %s\n", targetprod);
8954 ok(context == 0xdeadbeef,
8955 "Expected context to be unchanged, got %d\n", context);
8956 ok(!lstrcmpA(targetsid, "kiwi"),
8957 "Expected targetsid to be unchanged, got %s\n", targetsid);
8958 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8959
8960 RegDeleteValueA(hpatch, "State");
8961 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8962 RegCloseKey(hpatch);
8963 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8964 RegCloseKey(udpatch);
8965 delete_key(udprod, "", access & KEY_WOW64_64KEY);
8966 RegCloseKey(udprod);
8967 RegDeleteValueA(patches, "Patches");
8968 delete_key(patches, "", access & KEY_WOW64_64KEY);
8969 RegCloseKey(patches);
8970 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8971 RegCloseKey(prodkey);
8972 }
8973
8974 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8975 {
8976 MSIINSTALLCONTEXT context;
8977 CHAR keypath[MAX_PATH], patch[MAX_PATH];
8978 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8979 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8980 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8981 HKEY prodkey, patches, udprod, udpatch;
8982 HKEY userkey, hpatch;
8983 DWORD size, data;
8984 LONG res;
8985 UINT r;
8986 REGSAM access = KEY_ALL_ACCESS;
8987
8988 create_test_guid(prodcode, prod_squashed);
8989 create_test_guid(patch, patch_squashed);
8990
8991 if (is_wow64)
8992 access |= KEY_WOW64_64KEY;
8993
8994 /* MSIPATCHSTATE_APPLIED */
8995
8996 lstrcpyA(patchcode, "apple");
8997 lstrcpyA(targetprod, "banana");
8998 context = 0xdeadbeef;
8999 lstrcpyA(targetsid, "kiwi");
9000 size = MAX_PATH;
9001 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9002 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9003 &context, targetsid, &size);
9004 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9005 ok(!lstrcmpA(patchcode, "apple"),
9006 "Expected patchcode to be unchanged, got %s\n", patchcode);
9007 ok(!lstrcmpA(targetprod, "banana"),
9008 "Expected targetprod to be unchanged, got %s\n", targetprod);
9009 ok(context == 0xdeadbeef,
9010 "Expected context to be unchanged, got %d\n", context);
9011 ok(!lstrcmpA(targetsid, "kiwi"),
9012 "Expected targetsid to be unchanged, got %s\n", targetsid);
9013 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9014
9015 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9016 lstrcatA(keypath, prod_squashed);
9017
9018 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9019 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9020
9021 /* current user product key exists */
9022 lstrcpyA(patchcode, "apple");
9023 lstrcpyA(targetprod, "banana");
9024 context = 0xdeadbeef;
9025 lstrcpyA(targetsid, "kiwi");
9026 size = MAX_PATH;
9027 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9028 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9029 &context, targetsid, &size);
9030 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9031 ok(!lstrcmpA(patchcode, "apple"),
9032 "Expected patchcode to be unchanged, got %s\n", patchcode);
9033 ok(!lstrcmpA(targetprod, "banana"),
9034 "Expected targetprod to be unchanged, got %s\n", targetprod);
9035 ok(context == 0xdeadbeef,
9036 "Expected context to be unchanged, got %d\n", context);
9037 ok(!lstrcmpA(targetsid, "kiwi"),
9038 "Expected targetsid to be unchanged, got %s\n", targetsid);
9039 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9040
9041 res = RegCreateKeyA(prodkey, "Patches", &patches);
9042 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9043
9044 /* Patches key exists */
9045 lstrcpyA(patchcode, "apple");
9046 lstrcpyA(targetprod, "banana");
9047 context = 0xdeadbeef;
9048 lstrcpyA(targetsid, "kiwi");
9049 size = MAX_PATH;
9050 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9051 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9052 &context, targetsid, &size);
9053 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9054 ok(!lstrcmpA(patchcode, "apple"),
9055 "Expected patchcode to be unchanged, got %s\n", patchcode);
9056 ok(!lstrcmpA(targetprod, "banana"),
9057 "Expected targetprod to be unchanged, got %s\n", targetprod);
9058 ok(context == 0xdeadbeef,
9059 "Expected context to be unchanged, got %d\n", context);
9060 ok(!lstrcmpA(targetsid, "kiwi"),
9061 "Expected targetsid to be unchanged, got %s\n", targetsid);
9062 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9063
9064 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9065 (const BYTE *)patch_squashed,
9066 lstrlenA(patch_squashed) + 1);
9067 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9068
9069 /* Patches value exists, is not REG_MULTI_SZ */
9070 lstrcpyA(patchcode, "apple");
9071 lstrcpyA(targetprod, "banana");
9072 context = 0xdeadbeef;
9073 lstrcpyA(targetsid, "kiwi");
9074 size = MAX_PATH;
9075 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9076 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9077 &context, targetsid, &size);
9078 ok(r == ERROR_BAD_CONFIGURATION,
9079 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9080 ok(!lstrcmpA(patchcode, "apple"),
9081 "Expected patchcode to be unchanged, got %s\n", patchcode);
9082 ok(!lstrcmpA(targetprod, "banana"),
9083 "Expected targetprod to be unchanged, got %s\n", targetprod);
9084 ok(context == 0xdeadbeef,
9085 "Expected context to be unchanged, got %d\n", context);
9086 ok(!lstrcmpA(targetsid, "kiwi"),
9087 "Expected targetsid to be unchanged, got %s\n", targetsid);
9088 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9089
9090 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9091 (const BYTE *)"a\0b\0c\0\0", 7);
9092 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9093
9094 /* Patches value exists, is not a squashed guid */
9095 lstrcpyA(patchcode, "apple");
9096 lstrcpyA(targetprod, "banana");
9097 context = 0xdeadbeef;
9098 lstrcpyA(targetsid, "kiwi");
9099 size = MAX_PATH;
9100 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9101 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9102 &context, targetsid, &size);
9103 ok(r == ERROR_BAD_CONFIGURATION,
9104 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9105 ok(!lstrcmpA(patchcode, "apple"),
9106 "Expected patchcode to be unchanged, got %s\n", patchcode);
9107 ok(!lstrcmpA(targetprod, "banana"),
9108 "Expected targetprod to be unchanged, got %s\n", targetprod);
9109 ok(context == 0xdeadbeef,
9110 "Expected context to be unchanged, got %d\n", context);
9111 ok(!lstrcmpA(targetsid, "kiwi"),
9112 "Expected targetsid to be unchanged, got %s\n", targetsid);
9113 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9114
9115 patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
9116 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9117 (const BYTE *)patch_squashed,
9118 lstrlenA(patch_squashed) + 2);
9119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9120
9121 /* Patches value exists */
9122 lstrcpyA(patchcode, "apple");
9123 lstrcpyA(targetprod, "banana");
9124 context = 0xdeadbeef;
9125 lstrcpyA(targetsid, "kiwi");
9126 size = MAX_PATH;
9127 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9128 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9129 &context, targetsid, &size);
9130 ok(r == ERROR_NO_MORE_ITEMS ||
9131 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
9132 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9133 ok(!lstrcmpA(patchcode, "apple"),
9134 "Expected patchcode to be unchanged, got %s\n", patchcode);
9135 ok(!lstrcmpA(targetprod, "banana"),
9136 "Expected targetprod to be unchanged, got %s\n", targetprod);
9137 ok(context == 0xdeadbeef,
9138 "Expected context to be unchanged, got %d\n", context);
9139 ok(!lstrcmpA(targetsid, "kiwi"),
9140 "Expected targetsid to be unchanged, got %s\n", targetsid);
9141 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9142
9143 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9144 (const BYTE *)"whatever", 9);
9145 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9146
9147 /* patch code value exists */
9148 lstrcpyA(patchcode, "apple");
9149 lstrcpyA(targetprod, "banana");
9150 context = 0xdeadbeef;
9151 lstrcpyA(targetsid, "kiwi");
9152 size = MAX_PATH;
9153 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9154 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9155 &context, targetsid, &size);
9156 ok(r == ERROR_NO_MORE_ITEMS ||
9157 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
9158 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9159 ok(!lstrcmpA(patchcode, "apple"),
9160 "Expected patchcode to be unchanged, got %s\n", patchcode);
9161 ok(!lstrcmpA(targetprod, "banana"),
9162 "Expected targetprod to be unchanged, got %s\n", targetprod);
9163 ok(context == 0xdeadbeef,
9164 "Expected context to be unchanged, got %d\n", context);
9165 ok(!lstrcmpA(targetsid, "kiwi"),
9166 "Expected targetsid to be unchanged, got %s\n", targetsid);
9167 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9168
9169 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9170 lstrcatA(keypath, expectedsid);
9171 lstrcatA(keypath, "\\Patches\\");
9172 lstrcatA(keypath, patch_squashed);
9173
9174 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9175 if (res == ERROR_ACCESS_DENIED)
9176 {
9177 skip("Not enough rights to perform tests\n");
9178 goto error;
9179 }
9180 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9181
9182 /* userdata patch key exists */
9183 lstrcpyA(patchcode, "apple");
9184 lstrcpyA(targetprod, "banana");
9185 context = 0xdeadbeef;
9186 lstrcpyA(targetsid, "kiwi");
9187 size = MAX_PATH;
9188 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9189 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9190 &context, targetsid, &size);
9191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9192 ok(!lstrcmpA(patchcode, patch),
9193 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9194 ok(!lstrcmpA(targetprod, prodcode),
9195 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9196 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9197 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9198 ok(!lstrcmpA(targetsid, expectedsid),
9199 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9200 ok(size == lstrlenA(expectedsid),
9201 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9202
9203 /* MSIPATCHSTATE_SUPERSEDED */
9204
9205 lstrcpyA(patchcode, "apple");
9206 lstrcpyA(targetprod, "banana");
9207 context = 0xdeadbeef;
9208 lstrcpyA(targetsid, "kiwi");
9209 size = MAX_PATH;
9210 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9211 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9212 &context, targetsid, &size);
9213 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9214 ok(!lstrcmpA(patchcode, "apple"),
9215 "Expected patchcode to be unchanged, got %s\n", patchcode);
9216 ok(!lstrcmpA(targetprod, "banana"),
9217 "Expected targetprod to be unchanged, got %s\n", targetprod);
9218 ok(context == 0xdeadbeef,
9219 "Expected context to be unchanged, got %d\n", context);
9220 ok(!lstrcmpA(targetsid, "kiwi"),
9221 "Expected targetsid to be unchanged, got %s\n", targetsid);
9222 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9223
9224 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9225 lstrcatA(keypath, expectedsid);
9226 lstrcatA(keypath, "\\Products\\");
9227 lstrcatA(keypath, prod_squashed);
9228
9229 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9230 if (res == ERROR_ACCESS_DENIED)
9231 {
9232 skip("Not enough rights to perform tests\n");
9233 goto error;
9234 }
9235 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9236
9237 /* UserData product key exists */
9238 lstrcpyA(patchcode, "apple");
9239 lstrcpyA(targetprod, "banana");
9240 context = 0xdeadbeef;
9241 lstrcpyA(targetsid, "kiwi");
9242 size = MAX_PATH;
9243 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9244 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9245 &context, targetsid, &size);
9246 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9247 ok(!lstrcmpA(patchcode, "apple"),
9248 "Expected patchcode to be unchanged, got %s\n", patchcode);
9249 ok(!lstrcmpA(targetprod, "banana"),
9250 "Expected targetprod to be unchanged, got %s\n", targetprod);
9251 ok(context == 0xdeadbeef,
9252 "Expected context to be unchanged, got %d\n", context);
9253 ok(!lstrcmpA(targetsid, "kiwi"),
9254 "Expected targetsid to be unchanged, got %s\n", targetsid);
9255 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9256
9257 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9258 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9259
9260 /* UserData patches key exists */
9261 lstrcpyA(patchcode, "apple");
9262 lstrcpyA(targetprod, "banana");
9263 context = 0xdeadbeef;
9264 lstrcpyA(targetsid, "kiwi");
9265 size = MAX_PATH;
9266 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9267 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9268 &context, targetsid, &size);
9269 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9270 ok(!lstrcmpA(patchcode, "apple"),
9271 "Expected patchcode to be unchanged, got %s\n", patchcode);
9272 ok(!lstrcmpA(targetprod, "banana"),
9273 "Expected targetprod to be unchanged, got %s\n", targetprod);
9274 ok(context == 0xdeadbeef,
9275 "Expected context to be unchanged, got %d\n", context);
9276 ok(!lstrcmpA(targetsid, "kiwi"),
9277 "Expected targetsid to be unchanged, got %s\n", targetsid);
9278 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9279
9280 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9281 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9282
9283 /* specific UserData patch key exists */
9284 lstrcpyA(patchcode, "apple");
9285 lstrcpyA(targetprod, "banana");
9286 context = 0xdeadbeef;
9287 lstrcpyA(targetsid, "kiwi");
9288 size = MAX_PATH;
9289 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9290 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9291 &context, targetsid, &size);
9292 ok(r == ERROR_BAD_CONFIGURATION,
9293 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9294 ok(!lstrcmpA(patchcode, "apple"),
9295 "Expected patchcode to be unchanged, got %s\n", patchcode);
9296 ok(!lstrcmpA(targetprod, "banana"),
9297 "Expected targetprod to be unchanged, got %s\n", targetprod);
9298 ok(context == 0xdeadbeef,
9299 "Expected context to be unchanged, got %d\n", context);
9300 ok(!lstrcmpA(targetsid, "kiwi"),
9301 "Expected targetsid to be unchanged, got %s\n", targetsid);
9302 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9303
9304 data = MSIPATCHSTATE_SUPERSEDED;
9305 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9306 (const BYTE *)&data, sizeof(DWORD));
9307 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9308
9309 /* State value exists */
9310 lstrcpyA(patchcode, "apple");
9311 lstrcpyA(targetprod, "banana");
9312 context = 0xdeadbeef;
9313 lstrcpyA(targetsid, "kiwi");
9314 size = MAX_PATH;
9315 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9316 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9317 &context, targetsid, &size);
9318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9319 ok(!lstrcmpA(patchcode, patch),
9320 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9321 ok(!lstrcmpA(targetprod, prodcode),
9322 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9323 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9324 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9325 ok(!lstrcmpA(targetsid, expectedsid),
9326 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9327 ok(size == lstrlenA(expectedsid),
9328 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9329
9330 /* MSIPATCHSTATE_OBSOLETED */
9331
9332 lstrcpyA(patchcode, "apple");
9333 lstrcpyA(targetprod, "banana");
9334 context = 0xdeadbeef;
9335 lstrcpyA(targetsid, "kiwi");
9336 size = MAX_PATH;
9337 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9338 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9339 &context, targetsid, &size);
9340 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9341 ok(!lstrcmpA(patchcode, "apple"),
9342 "Expected patchcode to be unchanged, got %s\n", patchcode);
9343 ok(!lstrcmpA(targetprod, "banana"),
9344 "Expected targetprod to be unchanged, got %s\n", targetprod);
9345 ok(context == 0xdeadbeef,
9346 "Expected context to be unchanged, got %d\n", context);
9347 ok(!lstrcmpA(targetsid, "kiwi"),
9348 "Expected targetsid to be unchanged, got %s\n", targetsid);
9349 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9350
9351 data = MSIPATCHSTATE_OBSOLETED;
9352 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9353 (const BYTE *)&data, sizeof(DWORD));
9354 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9355
9356 /* State value is obsoleted */
9357 lstrcpyA(patchcode, "apple");
9358 lstrcpyA(targetprod, "banana");
9359 context = 0xdeadbeef;
9360 lstrcpyA(targetsid, "kiwi");
9361 size = MAX_PATH;
9362 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9363 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9364 &context, targetsid, &size);
9365 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9366 ok(!lstrcmpA(patchcode, patch),
9367 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9368 ok(!lstrcmpA(targetprod, prodcode),
9369 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9370 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9371 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9372 ok(!lstrcmpA(targetsid, expectedsid),
9373 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9374 ok(size == lstrlenA(expectedsid),
9375 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9376
9377 /* MSIPATCHSTATE_REGISTERED */
9378 /* FIXME */
9379
9380 /* MSIPATCHSTATE_ALL */
9381
9382 /* 1st */
9383 lstrcpyA(patchcode, "apple");
9384 lstrcpyA(targetprod, "banana");
9385 context = 0xdeadbeef;
9386 lstrcpyA(targetsid, "kiwi");
9387 size = MAX_PATH;
9388 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9389 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9390 &context, targetsid, &size);
9391 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9392 ok(!lstrcmpA(patchcode, patch),
9393 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9394 ok(!lstrcmpA(targetprod, prodcode),
9395 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9396 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9397 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9398 ok(!lstrcmpA(targetsid, expectedsid),
9399 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9400 ok(size == lstrlenA(expectedsid),
9401 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9402
9403 /* same patch in multiple places, only one is enumerated */
9404 lstrcpyA(patchcode, "apple");
9405 lstrcpyA(targetprod, "banana");
9406 context = 0xdeadbeef;
9407 lstrcpyA(targetsid, "kiwi");
9408 size = MAX_PATH;
9409 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9410 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9411 &context, targetsid, &size);
9412 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9413 ok(!lstrcmpA(patchcode, "apple"),
9414 "Expected patchcode to be unchanged, got %s\n", patchcode);
9415 ok(!lstrcmpA(targetprod, "banana"),
9416 "Expected targetprod to be unchanged, got %s\n", targetprod);
9417 ok(context == 0xdeadbeef,
9418 "Expected context to be unchanged, got %d\n", context);
9419 ok(!lstrcmpA(targetsid, "kiwi"),
9420 "Expected targetsid to be unchanged, got %s\n", targetsid);
9421 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9422
9423 RegDeleteValueA(hpatch, "State");
9424 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9425 RegCloseKey(hpatch);
9426 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9427 RegCloseKey(udpatch);
9428 delete_key(udprod, "", access & KEY_WOW64_64KEY);
9429 RegCloseKey(udprod);
9430 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9431 RegCloseKey(userkey);
9432 RegDeleteValueA(patches, patch_squashed);
9433 RegDeleteValueA(patches, "Patches");
9434
9435 error:
9436 RegDeleteKeyA(patches, "");
9437 RegCloseKey(patches);
9438 RegDeleteKeyA(prodkey, "");
9439 RegCloseKey(prodkey);
9440 }
9441
9442 static void test_MsiEnumPatchesEx_machine(void)
9443 {
9444 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9445 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9446 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9447 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9448 HKEY prodkey, patches, udprod, udpatch;
9449 HKEY hpatch;
9450 MSIINSTALLCONTEXT context;
9451 DWORD size, data;
9452 LONG res;
9453 UINT r;
9454 REGSAM access = KEY_ALL_ACCESS;
9455
9456 create_test_guid(prodcode, prod_squashed);
9457 create_test_guid(patch, patch_squashed);
9458
9459 if (is_wow64)
9460 access |= KEY_WOW64_64KEY;
9461
9462 /* MSIPATCHSTATE_APPLIED */
9463
9464 lstrcpyA(patchcode, "apple");
9465 lstrcpyA(targetprod, "banana");
9466 context = 0xdeadbeef;
9467 lstrcpyA(targetsid, "kiwi");
9468 size = MAX_PATH;
9469 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9470 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9471 &context, targetsid, &size);
9472 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9473 ok(!lstrcmpA(patchcode, "apple"),
9474 "Expected patchcode to be unchanged, got %s\n", patchcode);
9475 ok(!lstrcmpA(targetprod, "banana"),
9476 "Expected targetprod to be unchanged, got %s\n", targetprod);
9477 ok(context == 0xdeadbeef,
9478 "Expected context to be unchanged, got %d\n", context);
9479 ok(!lstrcmpA(targetsid, "kiwi"),
9480 "Expected targetsid to be unchanged, got %s\n", targetsid);
9481 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9482
9483 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9484 lstrcatA(keypath, prod_squashed);
9485
9486 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9487 if (res == ERROR_ACCESS_DENIED)
9488 {
9489 skip("Not enough rights to perform tests\n");
9490 return;
9491 }
9492 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9493
9494 /* local product key exists */
9495 lstrcpyA(patchcode, "apple");
9496 lstrcpyA(targetprod, "banana");
9497 context = 0xdeadbeef;
9498 lstrcpyA(targetsid, "kiwi");
9499 size = MAX_PATH;
9500 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9501 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9502 &context, targetsid, &size);
9503 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9504 ok(!lstrcmpA(patchcode, "apple"),
9505 "Expected patchcode to be unchanged, got %s\n", patchcode);
9506 ok(!lstrcmpA(targetprod, "banana"),
9507 "Expected targetprod to be unchanged, got %s\n", targetprod);
9508 ok(context == 0xdeadbeef,
9509 "Expected context to be unchanged, got %d\n", context);
9510 ok(!lstrcmpA(targetsid, "kiwi"),
9511 "Expected targetsid to be unchanged, got %s\n", targetsid);
9512 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9513
9514 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9515 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9516
9517 /* Patches key exists */
9518 lstrcpyA(patchcode, "apple");
9519 lstrcpyA(targetprod, "banana");
9520 context = 0xdeadbeef;
9521 lstrcpyA(targetsid, "kiwi");
9522 size = MAX_PATH;
9523 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9524 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9525 &context, targetsid, &size);
9526 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9527 ok(!lstrcmpA(patchcode, "apple"),
9528 "Expected patchcode to be unchanged, got %s\n", patchcode);
9529 ok(!lstrcmpA(targetprod, "banana"),
9530 "Expected targetprod to be unchanged, got %s\n", targetprod);
9531 ok(context == 0xdeadbeef,
9532 "Expected context to be unchanged, got %d\n", context);
9533 ok(!lstrcmpA(targetsid, "kiwi"),
9534 "Expected targetsid to be unchanged, got %s\n", targetsid);
9535 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9536
9537 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9538 (const BYTE *)patch_squashed,
9539 lstrlenA(patch_squashed) + 1);
9540 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9541
9542 /* Patches value exists, is not REG_MULTI_SZ */
9543 lstrcpyA(patchcode, "apple");
9544 lstrcpyA(targetprod, "banana");
9545 context = 0xdeadbeef;
9546 lstrcpyA(targetsid, "kiwi");
9547 size = MAX_PATH;
9548 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9549 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9550 &context, targetsid, &size);
9551 ok(r == ERROR_BAD_CONFIGURATION,
9552 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9553 ok(!lstrcmpA(patchcode, "apple"),
9554 "Expected patchcode to be unchanged, got %s\n", patchcode);
9555 ok(!lstrcmpA(targetprod, "banana"),
9556 "Expected targetprod to be unchanged, got %s\n", targetprod);
9557 ok(context == 0xdeadbeef,
9558 "Expected context to be unchanged, got %d\n", context);
9559 ok(!lstrcmpA(targetsid, "kiwi"),
9560 "Expected targetsid to be unchanged, got %s\n", targetsid);
9561 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9562
9563 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9564 (const BYTE *)"a\0b\0c\0\0", 7);
9565 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9566
9567 /* Patches value exists, is not a squashed guid */
9568 lstrcpyA(patchcode, "apple");
9569 lstrcpyA(targetprod, "banana");
9570 context = 0xdeadbeef;
9571 lstrcpyA(targetsid, "kiwi");
9572 size = MAX_PATH;
9573 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9574 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9575 &context, targetsid, &size);
9576 ok(r == ERROR_BAD_CONFIGURATION,
9577 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9578 ok(!lstrcmpA(patchcode, "apple"),
9579 "Expected patchcode to be unchanged, got %s\n", patchcode);
9580 ok(!lstrcmpA(targetprod, "banana"),
9581 "Expected targetprod to be unchanged, got %s\n", targetprod);
9582 ok(context == 0xdeadbeef,
9583 "Expected context to be unchanged, got %d\n", context);
9584 ok(!lstrcmpA(targetsid, "kiwi"),
9585 "Expected targetsid to be unchanged, got %s\n", targetsid);
9586 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9587
9588 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9589 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9590 (const BYTE *)patch_squashed,
9591 lstrlenA(patch_squashed) + 2);
9592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9593
9594 /* Patches value exists */
9595 lstrcpyA(patchcode, "apple");
9596 lstrcpyA(targetprod, "banana");
9597 context = 0xdeadbeef;
9598 lstrcpyA(targetsid, "kiwi");
9599 size = MAX_PATH;
9600 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9601 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9602 &context, targetsid, &size);
9603 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9604 ok(!lstrcmpA(patchcode, "apple"),
9605 "Expected patchcode to be unchanged, got %s\n", patchcode);
9606 ok(!lstrcmpA(targetprod, "banana"),
9607 "Expected targetprod to be unchanged, got %s\n", targetprod);
9608 ok(context == 0xdeadbeef,
9609 "Expected context to be unchanged, got %d\n", context);
9610 ok(!lstrcmpA(targetsid, "kiwi"),
9611 "Expected targetsid to be unchanged, got %s\n", targetsid);
9612 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9613
9614 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9615 (const BYTE *)"whatever", 9);
9616 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9617
9618 /* patch code value exists */
9619 lstrcpyA(patchcode, "apple");
9620 lstrcpyA(targetprod, "banana");
9621 context = 0xdeadbeef;
9622 lstrcpyA(targetsid, "kiwi");
9623 size = MAX_PATH;
9624 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9625 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9626 &context, targetsid, &size);
9627 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9628 ok(!lstrcmpA(patchcode, patch),
9629 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9630 ok(!lstrcmpA(targetprod, prodcode),
9631 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9632 ok(context == MSIINSTALLCONTEXT_MACHINE,
9633 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9634 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9635 ok(size == 0, "Expected 0, got %d\n", size);
9636
9637 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9638 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9639 lstrcatA(keypath, prod_squashed);
9640
9641 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9642 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9643
9644 /* local UserData product key exists */
9645 lstrcpyA(patchcode, "apple");
9646 lstrcpyA(targetprod, "banana");
9647 context = 0xdeadbeef;
9648 lstrcpyA(targetsid, "kiwi");
9649 size = MAX_PATH;
9650 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9651 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9652 &context, targetsid, &size);
9653 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9654 ok(!lstrcmpA(patchcode, patch),
9655 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9656 ok(!lstrcmpA(targetprod, prodcode),
9657 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9658 ok(context == MSIINSTALLCONTEXT_MACHINE,
9659 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9660 ok(!lstrcmpA(targetsid, ""),
9661 "Expected \"\", got \"%s\"\n", targetsid);
9662 ok(size == 0, "Expected 0, got %d\n", size);
9663
9664 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9666
9667 /* local UserData Patches key exists */
9668 lstrcpyA(patchcode, "apple");
9669 lstrcpyA(targetprod, "banana");
9670 context = 0xdeadbeef;
9671 lstrcpyA(targetsid, "kiwi");
9672 size = MAX_PATH;
9673 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9674 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9675 &context, targetsid, &size);
9676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9677 ok(!lstrcmpA(patchcode, patch),
9678 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9679 ok(!lstrcmpA(targetprod, prodcode),
9680 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9681 ok(context == MSIINSTALLCONTEXT_MACHINE,
9682 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9683 ok(!lstrcmpA(targetsid, ""),
9684 "Expected \"\", got \"%s\"\n", targetsid);
9685 ok(size == 0, "Expected 0, got %d\n", size);
9686
9687 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9688 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9689
9690 /* local UserData Product patch key exists */
9691 lstrcpyA(patchcode, "apple");
9692 lstrcpyA(targetprod, "banana");
9693 context = 0xdeadbeef;
9694 lstrcpyA(targetsid, "kiwi");
9695 size = MAX_PATH;
9696 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9697 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9698 &context, targetsid, &size);
9699 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9700 ok(!lstrcmpA(patchcode, "apple"),
9701 "Expected patchcode to be unchanged, got %s\n", patchcode);
9702 ok(!lstrcmpA(targetprod, "banana"),
9703 "Expected targetprod to be unchanged, got %s\n", targetprod);
9704 ok(context == 0xdeadbeef,
9705 "Expected context to be unchanged, got %d\n", context);
9706 ok(!lstrcmpA(targetsid, "kiwi"),
9707 "Expected targetsid to be unchanged, got %s\n", targetsid);
9708 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9709
9710 data = MSIPATCHSTATE_APPLIED;
9711 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9712 (const BYTE *)&data, sizeof(DWORD));
9713 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9714
9715 /* State value exists */
9716 lstrcpyA(patchcode, "apple");
9717 lstrcpyA(targetprod, "banana");
9718 context = 0xdeadbeef;
9719 lstrcpyA(targetsid, "kiwi");
9720 size = MAX_PATH;
9721 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9722 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9723 &context, targetsid, &size);
9724 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9725 ok(!lstrcmpA(patchcode, patch),
9726 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9727 ok(!lstrcmpA(targetprod, prodcode),
9728 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9729 ok(context == MSIINSTALLCONTEXT_MACHINE,
9730 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9731 ok(!lstrcmpA(targetsid, ""),
9732 "Expected \"\", got \"%s\"\n", targetsid);
9733 ok(size == 0, "Expected 0, got %d\n", size);
9734
9735 /* MSIPATCHSTATE_SUPERSEDED */
9736
9737 lstrcpyA(patchcode, "apple");
9738 lstrcpyA(targetprod, "banana");
9739 context = 0xdeadbeef;
9740 lstrcpyA(targetsid, "kiwi");
9741 size = MAX_PATH;
9742 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9743 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9744 &context, targetsid, &size);
9745 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9746 ok(!lstrcmpA(patchcode, "apple"),
9747 "Expected patchcode to be unchanged, got %s\n", patchcode);
9748 ok(!lstrcmpA(targetprod, "banana"),
9749 "Expected targetprod to be unchanged, got %s\n", targetprod);
9750 ok(context == 0xdeadbeef,
9751 "Expected context to be unchanged, got %d\n", context);
9752 ok(!lstrcmpA(targetsid, "kiwi"),
9753 "Expected targetsid to be unchanged, got %s\n", targetsid);
9754 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9755
9756 data = MSIPATCHSTATE_SUPERSEDED;
9757 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9758 (const BYTE *)&data, sizeof(DWORD));
9759 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9760
9761 /* State value is MSIPATCHSTATE_SUPERSEDED */
9762 lstrcpyA(patchcode, "apple");
9763 lstrcpyA(targetprod, "banana");
9764 context = 0xdeadbeef;
9765 lstrcpyA(targetsid, "kiwi");
9766 size = MAX_PATH;
9767 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9768 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9769 &context, targetsid, &size);
9770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9771 ok(!lstrcmpA(patchcode, patch),
9772 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9773 ok(!lstrcmpA(targetprod, prodcode),
9774 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9775 ok(context == MSIINSTALLCONTEXT_MACHINE,
9776 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9777 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9778 ok(size == 0, "Expected 0, got %d\n", size);
9779
9780 /* MSIPATCHSTATE_OBSOLETED */
9781
9782 lstrcpyA(patchcode, "apple");
9783 lstrcpyA(targetprod, "banana");
9784 context = 0xdeadbeef;
9785 lstrcpyA(targetsid, "kiwi");
9786 size = MAX_PATH;
9787 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9788 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9789 &context, targetsid, &size);
9790 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9791 ok(!lstrcmpA(patchcode, "apple"),
9792 "Expected patchcode to be unchanged, got %s\n", patchcode);
9793 ok(!lstrcmpA(targetprod, "banana"),
9794 "Expected targetprod to be unchanged, got %s\n", targetprod);
9795 ok(context == 0xdeadbeef,
9796 "Expected context to be unchanged, got %d\n", context);
9797 ok(!lstrcmpA(targetsid, "kiwi"),
9798 "Expected targetsid to be unchanged, got %s\n", targetsid);
9799 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9800
9801 data = MSIPATCHSTATE_OBSOLETED;
9802 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9803 (const BYTE *)&data, sizeof(DWORD));
9804 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9805
9806 /* State value is obsoleted */
9807 lstrcpyA(patchcode, "apple");
9808 lstrcpyA(targetprod, "banana");
9809 context = 0xdeadbeef;
9810 lstrcpyA(targetsid, "kiwi");
9811 size = MAX_PATH;
9812 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9813 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9814 &context, targetsid, &size);
9815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9816 ok(!lstrcmpA(patchcode, patch),
9817 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9818 ok(!lstrcmpA(targetprod, prodcode),
9819 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9820 ok(context == MSIINSTALLCONTEXT_MACHINE,
9821 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9822 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9823 ok(size == 0, "Expected 0, got %d\n", size);
9824
9825 /* MSIPATCHSTATE_REGISTERED */
9826 /* FIXME */
9827
9828 /* MSIPATCHSTATE_ALL */
9829
9830 /* 1st */
9831 lstrcpyA(patchcode, "apple");
9832 lstrcpyA(targetprod, "banana");
9833 context = 0xdeadbeef;
9834 lstrcpyA(targetsid, "kiwi");
9835 size = MAX_PATH;
9836 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9837 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9838 &context, targetsid, &size);
9839 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9840 ok(!lstrcmpA(patchcode, patch),
9841 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9842 ok(!lstrcmpA(targetprod, prodcode),
9843 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9844 ok(context == MSIINSTALLCONTEXT_MACHINE,
9845 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9846 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9847 ok(size == 0, "Expected 0, got %d\n", size);
9848
9849 /* same patch in multiple places, only one is enumerated */
9850 lstrcpyA(patchcode, "apple");
9851 lstrcpyA(targetprod, "banana");
9852 context = 0xdeadbeef;
9853 lstrcpyA(targetsid, "kiwi");
9854 size = MAX_PATH;
9855 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9856 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9857 &context, targetsid, &size);
9858 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9859 ok(!lstrcmpA(patchcode, "apple"),
9860 "Expected patchcode to be unchanged, got %s\n", patchcode);
9861 ok(!lstrcmpA(targetprod, "banana"),
9862 "Expected targetprod to be unchanged, got %s\n", targetprod);
9863 ok(context == 0xdeadbeef,
9864 "Expected context to be unchanged, got %d\n", context);
9865 ok(!lstrcmpA(targetsid, "kiwi"),
9866 "Expected targetsid to be unchanged, got %s\n", targetsid);
9867 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9868
9869 RegDeleteValueA(patches, patch_squashed);
9870 RegDeleteValueA(patches, "Patches");
9871 delete_key(patches, "", access & KEY_WOW64_64KEY);
9872 RegCloseKey(patches);
9873 RegDeleteValueA(hpatch, "State");
9874 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9875 RegCloseKey(hpatch);
9876 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9877 RegCloseKey(udpatch);
9878 delete_key(udprod, "", access & KEY_WOW64_64KEY);
9879 RegCloseKey(udprod);
9880 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9881 RegCloseKey(prodkey);
9882 }
9883
9884 static void test_MsiEnumPatchesEx(void)
9885 {
9886 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9887 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9888 CHAR patchcode[MAX_PATH];
9889 MSIINSTALLCONTEXT context;
9890 LPSTR usersid;
9891 DWORD size;
9892 UINT r;
9893
9894 if (!pMsiEnumPatchesExA)
9895 {
9896 win_skip("MsiEnumPatchesExA not implemented\n");
9897 return;
9898 }
9899
9900 create_test_guid(prodcode, prod_squashed);
9901 usersid = get_user_sid();
9902
9903 /* empty szProductCode */
9904 lstrcpyA(patchcode, "apple");
9905 lstrcpyA(targetprod, "banana");
9906 context = 0xdeadbeef;
9907 lstrcpyA(targetsid, "kiwi");
9908 size = MAX_PATH;
9909 r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9910 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9911 targetsid, &size);
9912 ok(r == ERROR_INVALID_PARAMETER,
9913 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9914 ok(!lstrcmpA(patchcode, "apple"),
9915 "Expected patchcode to be unchanged, got %s\n", patchcode);
9916 ok(!lstrcmpA(targetprod, "banana"),
9917 "Expected targetprod to be unchanged, got %s\n", targetprod);
9918 ok(context == 0xdeadbeef,
9919 "Expected context to be unchanged, got %d\n", context);
9920 ok(!lstrcmpA(targetsid, "kiwi"),
9921 "Expected targetsid to be unchanged, got %s\n", targetsid);
9922 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9923
9924 /* garbage szProductCode */
9925 lstrcpyA(patchcode, "apple");
9926 lstrcpyA(targetprod, "banana");
9927 context = 0xdeadbeef;
9928 lstrcpyA(targetsid, "kiwi");
9929 size = MAX_PATH;
9930 r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9931 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9932 targetsid, &size);
9933 ok(r == ERROR_INVALID_PARAMETER,
9934 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9935 ok(!lstrcmpA(patchcode, "apple"),
9936 "Expected patchcode to be unchanged, got %s\n", patchcode);
9937 ok(!lstrcmpA(targetprod, "banana"),
9938 "Expected targetprod to be unchanged, got %s\n", targetprod);
9939 ok(context == 0xdeadbeef,
9940 "Expected context to be unchanged, got %d\n", context);
9941 ok(!lstrcmpA(targetsid, "kiwi"),
9942 "Expected targetsid to be unchanged, got %s\n", targetsid);
9943 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9944
9945 /* guid without brackets */
9946 lstrcpyA(patchcode, "apple");
9947 lstrcpyA(targetprod, "banana");
9948 context = 0xdeadbeef;
9949 lstrcpyA(targetsid, "kiwi");
9950 size = MAX_PATH;
9951 r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9952 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9953 0, patchcode, targetprod, &context,
9954 targetsid, &size);
9955 ok(r == ERROR_INVALID_PARAMETER,
9956 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9957 ok(!lstrcmpA(patchcode, "apple"),
9958 "Expected patchcode to be unchanged, got %s\n", patchcode);
9959 ok(!lstrcmpA(targetprod, "banana"),
9960 "Expected targetprod to be unchanged, got %s\n", targetprod);
9961 ok(context == 0xdeadbeef,
9962 "Expected context to be unchanged, got %d\n", context);
9963 ok(!lstrcmpA(targetsid, "kiwi"),
9964 "Expected targetsid to be unchanged, got %s\n", targetsid);
9965 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9966
9967 /* guid with brackets */
9968 lstrcpyA(patchcode, "apple");
9969 lstrcpyA(targetprod, "banana");
9970 context = 0xdeadbeef;
9971 lstrcpyA(targetsid, "kiwi");
9972 size = MAX_PATH;
9973 r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9974 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9975 0, patchcode, targetprod, &context,
9976 targetsid, &size);
9977 ok(r == ERROR_NO_MORE_ITEMS,
9978 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9979 ok(!lstrcmpA(patchcode, "apple"),
9980 "Expected patchcode to be unchanged, got %s\n", patchcode);
9981 ok(!lstrcmpA(targetprod, "banana"),
9982 "Expected targetprod to be unchanged, got %s\n", targetprod);
9983 ok(context == 0xdeadbeef,
9984 "Expected context to be unchanged, got %d\n", context);
9985 ok(!lstrcmpA(targetsid, "kiwi"),
9986 "Expected targetsid to be unchanged, got %s\n", targetsid);
9987 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9988
9989 /* szUserSid is S-1-5-18 */
9990 lstrcpyA(patchcode, "apple");
9991 lstrcpyA(targetprod, "banana");
9992 context = 0xdeadbeef;
9993 lstrcpyA(targetsid, "kiwi");
9994 size = MAX_PATH;
9995 r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9996 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9997 0, patchcode, targetprod, &context,
9998 targetsid, &size);
9999 ok(r == ERROR_INVALID_PARAMETER,
10000 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10001 ok(!lstrcmpA(patchcode, "apple"),
10002 "Expected patchcode to be unchanged, got %s\n", patchcode);
10003 ok(!lstrcmpA(targetprod, "banana"),
10004 "Expected targetprod to be unchanged, got %s\n", targetprod);
10005 ok(context == 0xdeadbeef,
10006 "Expected context to be unchanged, got %d\n", context);
10007 ok(!lstrcmpA(targetsid, "kiwi"),
10008 "Expected targetsid to be unchanged, got %s\n", targetsid);
10009 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10010
10011 /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
10012 lstrcpyA(patchcode, "apple");
10013 lstrcpyA(targetprod, "banana");
10014 context = 0xdeadbeef;
10015 lstrcpyA(targetsid, "kiwi");
10016 size = MAX_PATH;
10017 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
10018 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10019 &context, targetsid, &size);
10020 ok(r == ERROR_INVALID_PARAMETER,
10021 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10022 ok(!lstrcmpA(patchcode, "apple"),
10023 "Expected patchcode to be unchanged, got %s\n", patchcode);
10024 ok(!lstrcmpA(targetprod, "banana"),
10025 "Expected targetprod to be unchanged, got %s\n", targetprod);
10026 ok(context == 0xdeadbeef,
10027 "Expected context to be unchanged, got %d\n", context);
10028 ok(!lstrcmpA(targetsid, "kiwi"),
10029 "Expected targetsid to be unchanged, got %s\n", targetsid);
10030 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10031
10032 /* dwContext is out of bounds */
10033 lstrcpyA(patchcode, "apple");
10034 lstrcpyA(targetprod, "banana");
10035 context = 0xdeadbeef;
10036 lstrcpyA(targetsid, "kiwi");
10037 size = MAX_PATH;
10038 r = pMsiEnumPatchesExA(prodcode, usersid, 0,
10039 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10040 &context, targetsid, &size);
10041 ok(r == ERROR_INVALID_PARAMETER,
10042 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10043 ok(!lstrcmpA(patchcode, "apple"),
10044 "Expected patchcode to be unchanged, got %s\n", patchcode);
10045 ok(!lstrcmpA(targetprod, "banana"),
10046 "Expected targetprod to be unchanged, got %s\n", targetprod);
10047 ok(context == 0xdeadbeef,
10048 "Expected context to be unchanged, got %d\n", context);
10049 ok(!lstrcmpA(targetsid, "kiwi"),
10050 "Expected targetsid to be unchanged, got %s\n", targetsid);
10051 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10052
10053 /* dwContext is out of bounds */
10054 lstrcpyA(patchcode, "apple");
10055 lstrcpyA(targetprod, "banana");
10056 context = 0xdeadbeef;
10057 lstrcpyA(targetsid, "kiwi");
10058 size = MAX_PATH;
10059 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
10060 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10061 &context, targetsid, &size);
10062 ok(r == ERROR_INVALID_PARAMETER,
10063 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10064 ok(!lstrcmpA(patchcode, "apple"),
10065 "Expected patchcode to be unchanged, got %s\n", patchcode);
10066 ok(!lstrcmpA(targetprod, "banana"),
10067 "Expected targetprod to be unchanged, got %s\n", targetprod);
10068 ok(context == 0xdeadbeef,
10069 "Expected context to be unchanged, got %d\n", context);
10070 ok(!lstrcmpA(targetsid, "kiwi"),
10071 "Expected targetsid to be unchanged, got %s\n", targetsid);
10072 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10073
10074 /* dwFilter is out of bounds */
10075 lstrcpyA(patchcode, "apple");
10076 lstrcpyA(targetprod, "banana");
10077 context = 0xdeadbeef;
10078 lstrcpyA(targetsid, "kiwi");
10079 size = MAX_PATH;
10080 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10081 MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
10082 &context, targetsid, &size);
10083 ok(r == ERROR_INVALID_PARAMETER,
10084 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10085 ok(!lstrcmpA(patchcode, "apple"),
10086 "Expected patchcode to be unchanged, got %s\n", patchcode);
10087 ok(!lstrcmpA(targetprod, "banana"),
10088 "Expected targetprod to be unchanged, got %s\n", targetprod);
10089 ok(context == 0xdeadbeef,
10090 "Expected context to be unchanged, got %d\n", context);
10091 ok(!lstrcmpA(targetsid, "kiwi"),
10092 "Expected targetsid to be unchanged, got %s\n", targetsid);
10093 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10094
10095 /* dwFilter is out of bounds */
10096 lstrcpyA(patchcode, "apple");
10097 lstrcpyA(targetprod, "banana");
10098 context = 0xdeadbeef;
10099 lstrcpyA(targetsid, "kiwi");
10100 size = MAX_PATH;
10101 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10102 MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
10103 &context, targetsid, &size);
10104 ok(r == ERROR_INVALID_PARAMETER,
10105 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10106 ok(!lstrcmpA(patchcode, "apple"),
10107 "Expected patchcode to be unchanged, got %s\n", patchcode);
10108 ok(!lstrcmpA(targetprod, "banana"),
10109 "Expected targetprod to be unchanged, got %s\n", targetprod);
10110 ok(context == 0xdeadbeef,
10111 "Expected context to be unchanged, got %d\n", context);
10112 ok(!lstrcmpA(targetsid, "kiwi"),
10113 "Expected targetsid to be unchanged, got %s\n", targetsid);
10114 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10115
10116 /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
10117 lstrcpyA(patchcode, "apple");
10118 lstrcpyA(targetprod, "banana");
10119 context = 0xdeadbeef;
10120 lstrcpyA(targetsid, "kiwi");
10121 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10122 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10123 &context, targetsid, NULL);
10124 ok(r == ERROR_INVALID_PARAMETER,
10125 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10126 ok(!lstrcmpA(patchcode, "apple"),
10127 "Expected patchcode to be unchanged, got %s\n", patchcode);
10128 ok(!lstrcmpA(targetprod, "banana"),
10129 "Expected targetprod to be unchanged, got %s\n", targetprod);
10130 ok(context == 0xdeadbeef,
10131 "Expected context to be unchanged, got %d\n", context);
10132 ok(!lstrcmpA(targetsid, "kiwi"),
10133 "Expected targetsid to be unchanged, got %s\n", targetsid);
10134
10135 test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
10136 test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
10137 test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
10138 test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
10139 test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
10140 /* FIXME: Successfully test userunmanaged with a different user */
10141 test_MsiEnumPatchesEx_machine();
10142 LocalFree(usersid);
10143 }
10144
10145 static void test_MsiEnumPatches(void)
10146 {
10147 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10148 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10149 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10150 CHAR transforms[MAX_PATH];
10151 WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
10152 HKEY prodkey, patches, udprod;
10153 HKEY userkey, hpatch, udpatch;
10154 DWORD size, data;
10155 LPSTR usersid;
10156 LONG res;
10157 UINT r;
10158 REGSAM access = KEY_ALL_ACCESS;
10159
10160 create_test_guid(prodcode, prod_squashed);
10161 create_test_guid(patchcode, patch_squashed);
10162 usersid = get_user_sid();
10163
10164 if (is_wow64)
10165 access |= KEY_WOW64_64KEY;
10166
10167 /* NULL szProduct */
10168 size = MAX_PATH;
10169 lstrcpyA(patch, "apple");
10170 lstrcpyA(transforms, "banana");
10171 r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
10172 ok(r == ERROR_INVALID_PARAMETER,
10173 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10174 ok(!lstrcmpA(patch, "apple"),
10175 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10176 ok(!lstrcmpA(transforms, "banana"),
10177 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10178 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10179
10180 /* empty szProduct */
10181 size = MAX_PATH;
10182 lstrcpyA(patch, "apple");
10183 lstrcpyA(transforms, "banana");
10184 r = MsiEnumPatchesA("", 0, patch, transforms, &size);
10185 ok(r == ERROR_INVALID_PARAMETER,
10186 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10187 ok(!lstrcmpA(patch, "apple"),
10188 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10189 ok(!lstrcmpA(transforms, "banana"),
10190 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10191 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10192
10193 /* garbage szProduct */
10194 size = MAX_PATH;
10195 lstrcpyA(patch, "apple");
10196 lstrcpyA(transforms, "banana");
10197 r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
10198 ok(r == ERROR_INVALID_PARAMETER,
10199 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10200 ok(!lstrcmpA(patch, "apple"),
10201 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10202 ok(!lstrcmpA(transforms, "banana"),
10203 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10204 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10205
10206 /* guid without brackets */
10207 size = MAX_PATH;
10208 lstrcpyA(patch, "apple");
10209 lstrcpyA(transforms, "banana");
10210 r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
10211 transforms, &size);
10212 ok(r == ERROR_INVALID_PARAMETER,
10213 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10214 ok(!lstrcmpA(patch, "apple"),
10215 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10216 ok(!lstrcmpA(transforms, "banana"),
10217 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10218 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10219
10220 /* guid with brackets */
10221 size = MAX_PATH;
10222 lstrcpyA(patch, "apple");
10223 lstrcpyA(transforms, "banana");
10224 r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
10225 transforms, &size);
10226 ok(r == ERROR_UNKNOWN_PRODUCT,
10227 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10228 ok(!lstrcmpA(patch, "apple"),
10229 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10230 ok(!lstrcmpA(transforms, "banana"),
10231 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10232 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10233
10234 /* same length as guid, but random */
10235 size = MAX_PATH;
10236 lstrcpyA(patch, "apple");
10237 lstrcpyA(transforms, "banana");
10238 r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
10239 transforms, &size);
10240 ok(r == ERROR_INVALID_PARAMETER,
10241 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10242 ok(!lstrcmpA(patch, "apple"),
10243 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10244 ok(!lstrcmpA(transforms, "banana"),
10245 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10246 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10247
10248 /* MSIINSTALLCONTEXT_USERMANAGED */
10249
10250 size = MAX_PATH;
10251 lstrcpyA(patch, "apple");
10252 lstrcpyA(transforms, "banana");
10253 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10254 ok(r == ERROR_UNKNOWN_PRODUCT,
10255 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10256 ok(!lstrcmpA(patch, "apple"),
10257 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10258 ok(!lstrcmpA(transforms, "banana"),
10259 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10260 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10261
10262 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10263 lstrcatA(keypath, usersid);
10264 lstrcatA(keypath, "\\Installer\\Products\\");
10265 lstrcatA(keypath, prod_squashed);
10266
10267 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10268 if (res == ERROR_ACCESS_DENIED)
10269 {
10270 skip("Not enough rights to perform tests\n");
10271 LocalFree(usersid);
10272 return;
10273 }
10274 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10275
10276 /* managed product key exists */
10277 size = MAX_PATH;
10278 lstrcpyA(patch, "apple");
10279 lstrcpyA(transforms, "banana");
10280 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10281 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10282 ok(!lstrcmpA(patch, "apple"),
10283 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10284 ok(!lstrcmpA(transforms, "banana"),
10285 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10286 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10287
10288 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10289 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10290
10291 /* patches key exists */
10292 size = MAX_PATH;
10293 lstrcpyA(patch, "apple");
10294 lstrcpyA(transforms, "banana");
10295 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10296 ok(r == ERROR_NO_MORE_ITEMS ||
10297 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10298 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10299 ok(!lstrcmpA(patch, "apple"),
10300 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10301 ok(!lstrcmpA(transforms, "banana"),
10302 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10303 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10304
10305 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10306 (const BYTE *)patch_squashed,
10307 lstrlenA(patch_squashed) + 1);
10308 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10309
10310 /* Patches value exists, is not REG_MULTI_SZ */
10311 size = MAX_PATH;
10312 lstrcpyA(patch, "apple");
10313 lstrcpyA(transforms, "banana");
10314 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10315 ok(r == ERROR_BAD_CONFIGURATION ||
10316 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10317 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10318 ok(!lstrcmpA(patch, "apple"),
10319 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10320 ok(!lstrcmpA(transforms, "banana"),
10321 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10322 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10323
10324 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10325 (const BYTE *)"a\0b\0c\0\0", 7);
10326 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10327
10328 /* Patches value exists, is not a squashed guid */
10329 size = MAX_PATH;
10330 lstrcpyA(patch, "apple");
10331 lstrcpyA(transforms, "banana");
10332 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10333 ok(r == ERROR_BAD_CONFIGURATION,
10334 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10335 ok(!lstrcmpA(patch, "apple"),
10336 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10337 ok(!lstrcmpA(transforms, "banana"),
10338 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10339 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10340
10341 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10342 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10343 (const BYTE *)patch_squashed,
10344 lstrlenA(patch_squashed) + 2);
10345 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10346
10347 /* Patches value exists */
10348 size = MAX_PATH;
10349 lstrcpyA(patch, "apple");
10350 lstrcpyA(transforms, "banana");
10351 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10352 ok(r == ERROR_NO_MORE_ITEMS ||
10353 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10354 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10355 ok(!lstrcmpA(patch, "apple") ||
10356 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10357 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10358 ok(!lstrcmpA(transforms, "banana"),
10359 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10360 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10361
10362 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10363 (const BYTE *)"whatever", 9);
10364 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10365
10366 /* patch squashed value exists */
10367 size = MAX_PATH;
10368 lstrcpyA(patch, "apple");
10369 lstrcpyA(transforms, "banana");
10370 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10371 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10372 ok(!lstrcmpA(patch, patchcode),
10373 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10374 ok(!lstrcmpA(transforms, "whatever"),
10375 "Expected \"whatever\", got \"%s\"\n", transforms);
10376 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10377
10378 /* lpPatchBuf is NULL */
10379 size = MAX_PATH;
10380 lstrcpyA(transforms, "banana");
10381 r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
10382 ok(r == ERROR_INVALID_PARAMETER,
10383 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10384 ok(!lstrcmpA(transforms, "banana"),
10385 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10386 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10387
10388 /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
10389 size = MAX_PATH;
10390 lstrcpyA(patch, "apple");
10391 r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
10392 ok(r == ERROR_INVALID_PARAMETER,
10393 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10394 ok(!lstrcmpA(patch, "apple"),
10395 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10396 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10397
10398 /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
10399 lstrcpyA(patch, "apple");
10400 lstrcpyA(transforms, "banana");
10401 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
10402 ok(r == ERROR_INVALID_PARAMETER,
10403 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10404 ok(!lstrcmpA(patch, "apple"),
10405 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10406 ok(!lstrcmpA(transforms, "banana"),
10407 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10408
10409 /* pcchTransformsBuf is too small */
10410 size = 6;
10411 lstrcpyA(patch, "apple");
10412 lstrcpyA(transforms, "banana");
10413 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10414 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10415 ok(!lstrcmpA(patch, patchcode),
10416 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10417 ok(!lstrcmpA(transforms, "whate") ||
10418 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10419 "Expected \"whate\", got \"%s\"\n", transforms);
10420 ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
10421
10422 /* increase the index */
10423 size = MAX_PATH;
10424 lstrcpyA(patch, "apple");
10425 lstrcpyA(transforms, "banana");
10426 r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
10427 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10428 ok(!lstrcmpA(patch, "apple"),
10429 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10430 ok(!lstrcmpA(transforms, "banana"),
10431 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10432 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10433
10434 /* increase again */
10435 size = MAX_PATH;
10436 lstrcpyA(patch, "apple");
10437 lstrcpyA(transforms, "banana");
10438 r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
10439 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10440 ok(!lstrcmpA(patch, "apple"),
10441 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10442 ok(!lstrcmpA(transforms, "banana"),
10443 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10444 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10445
10446 RegDeleteValueA(patches, "Patches");
10447 delete_key(patches, "", access & KEY_WOW64_64KEY);
10448 RegCloseKey(patches);
10449 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10450 RegCloseKey(prodkey);
10451
10452 /* MSIINSTALLCONTEXT_USERUNMANAGED */
10453
10454 size = MAX_PATH;
10455 lstrcpyA(patch, "apple");
10456 lstrcpyA(transforms, "banana");
10457 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10458 ok(r == ERROR_UNKNOWN_PRODUCT,
10459 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10460 ok(!lstrcmpA(patch, "apple"),
10461 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10462 ok(!lstrcmpA(transforms, "banana"),
10463 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10464 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10465
10466 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10467 lstrcatA(keypath, prod_squashed);
10468
10469 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10470 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10471
10472 /* current user product key exists */
10473 size = MAX_PATH;
10474 lstrcpyA(patch, "apple");
10475 lstrcpyA(transforms, "banana");
10476 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10477 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10478 ok(!lstrcmpA(patch, "apple"),
10479 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10480 ok(!lstrcmpA(transforms, "banana"),
10481 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10482 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10483
10484 res = RegCreateKeyA(prodkey, "Patches", &patches);
10485 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10486
10487 /* Patches key exists */
10488 size = MAX_PATH;
10489 lstrcpyA(patch, "apple");
10490 lstrcpyA(transforms, "banana");
10491 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10492 ok(r == ERROR_NO_MORE_ITEMS ||
10493 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10494 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10495 ok(!lstrcmpA(patch, "apple"),
10496 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10497 ok(!lstrcmpA(transforms, "banana"),
10498 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10499 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10500
10501 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10502 (const BYTE *)patch_squashed,
10503 lstrlenA(patch_squashed) + 1);
10504 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10505
10506 /* Patches value exists, is not REG_MULTI_SZ */
10507 size = MAX_PATH;
10508 lstrcpyA(patch, "apple");
10509 lstrcpyA(transforms, "banana");
10510 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10511 ok(r == ERROR_BAD_CONFIGURATION ||
10512 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10513 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10514 ok(!lstrcmpA(patch, "apple"),
10515 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10516 ok(!lstrcmpA(transforms, "banana"),
10517 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10518 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10519
10520 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10521 (const BYTE *)"a\0b\0c\0\0", 7);
10522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10523
10524 /* Patches value exists, is not a squashed guid */
10525 size = MAX_PATH;
10526 lstrcpyA(patch, "apple");
10527 lstrcpyA(transforms, "banana");
10528 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10529 ok(r == ERROR_BAD_CONFIGURATION,
10530 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10531 ok(!lstrcmpA(patch, "apple"),
10532 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10533 ok(!lstrcmpA(transforms, "banana"),
10534 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10535 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10536
10537 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10538 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10539 (const BYTE *)patch_squashed,
10540 lstrlenA(patch_squashed) + 2);
10541 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10542
10543 /* Patches value exists */
10544 size = MAX_PATH;
10545 lstrcpyA(patch, "apple");
10546 lstrcpyA(transforms, "banana");
10547 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10548 ok(r == ERROR_NO_MORE_ITEMS ||
10549 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10550 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10551 ok(!lstrcmpA(patch, "apple") ||
10552 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10553 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10554 ok(!lstrcmpA(transforms, "banana"),
10555 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10556 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10557
10558 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10559 (const BYTE *)"whatever", 9);
10560 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10561
10562 /* patch code value exists */
10563 size = MAX_PATH;
10564 lstrcpyA(patch, "apple");
10565 lstrcpyA(transforms, "banana");
10566 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10567 ok(r == ERROR_NO_MORE_ITEMS ||
10568 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10569 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10570 ok(!lstrcmpA(patch, "apple") ||
10571 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10572 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10573 ok(!lstrcmpA(transforms, "banana") ||
10574 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10575 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10576 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10577
10578 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10579 lstrcatA(keypath, usersid);
10580 lstrcatA(keypath, "\\Patches\\");
10581 lstrcatA(keypath, patch_squashed);
10582
10583 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10584 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10585
10586 /* userdata patch key exists */
10587 size = MAX_PATH;
10588 lstrcpyA(patch, "apple");
10589 lstrcpyA(transforms, "banana");
10590 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10592 ok(!lstrcmpA(patch, patchcode),
10593 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10594 ok(!lstrcmpA(transforms, "whatever"),
10595 "Expected \"whatever\", got \"%s\"\n", transforms);
10596 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10597
10598 delete_key(userkey, "", access & KEY_WOW64_64KEY);
10599 RegCloseKey(userkey);
10600 RegDeleteValueA(patches, patch_squashed);
10601 RegDeleteValueA(patches, "Patches");
10602 RegDeleteKeyA(patches, "");
10603 RegCloseKey(patches);
10604 RegDeleteKeyA(prodkey, "");
10605 RegCloseKey(prodkey);
10606
10607 /* MSIINSTALLCONTEXT_MACHINE */
10608
10609 size = MAX_PATH;
10610 lstrcpyA(patch, "apple");
10611 lstrcpyA(transforms, "banana");
10612 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10613 ok(r == ERROR_UNKNOWN_PRODUCT,
10614 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10615 ok(!lstrcmpA(patch, "apple"),
10616 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10617 ok(!lstrcmpA(transforms, "banana"),
10618 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10619 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10620
10621 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10622 lstrcatA(keypath, prod_squashed);
10623
10624 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10625 if (res == ERROR_ACCESS_DENIED)
10626 {
10627 skip("Not enough rights to perform tests\n");
10628 LocalFree(usersid);
10629 return;
10630 }
10631 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10632
10633 /* local product key exists */
10634 size = MAX_PATH;
10635 lstrcpyA(patch, "apple");
10636 lstrcpyA(transforms, "banana");
10637 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10638 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10639 ok(!lstrcmpA(patch, "apple"),
10640 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10641 ok(!lstrcmpA(transforms, "banana"),
10642 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10643 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10644
10645 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10646 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10647
10648 /* Patches key exists */
10649 size = MAX_PATH;
10650 lstrcpyA(patch, "apple");
10651 lstrcpyA(transforms, "banana");
10652 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10653 ok(r == ERROR_NO_MORE_ITEMS ||
10654 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10655 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10656 ok(!lstrcmpA(patch, "apple"),
10657 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10658 ok(!lstrcmpA(transforms, "banana"),
10659 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10660 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10661
10662 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10663 (const BYTE *)patch_squashed,
10664 lstrlenA(patch_squashed) + 1);
10665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10666
10667 /* Patches value exists, is not REG_MULTI_SZ */
10668 size = MAX_PATH;
10669 lstrcpyA(patch, "apple");
10670 lstrcpyA(transforms, "banana");
10671 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10672 ok(r == ERROR_BAD_CONFIGURATION ||
10673 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10674 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10675 ok(!lstrcmpA(patch, "apple"),
10676 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10677 ok(!lstrcmpA(transforms, "banana"),
10678 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10679 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10680
10681 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10682 (const BYTE *)"a\0b\0c\0\0", 7);
10683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10684
10685 /* Patches value exists, is not a squashed guid */
10686 size = MAX_PATH;
10687 lstrcpyA(patch, "apple");
10688 lstrcpyA(transforms, "banana");
10689 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10690 ok(r == ERROR_BAD_CONFIGURATION,
10691 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10692 ok(!lstrcmpA(patch, "apple"),
10693 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10694 ok(!lstrcmpA(transforms, "banana"),
10695 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10696 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10697
10698 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10699 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10700 (const BYTE *)patch_squashed,
10701 lstrlenA(patch_squashed) + 2);
10702 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10703
10704 /* Patches value exists */
10705 size = MAX_PATH;
10706 lstrcpyA(patch, "apple");
10707 lstrcpyA(transforms, "banana");
10708 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10709 ok(r == ERROR_NO_MORE_ITEMS ||
10710 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10711 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10712 ok(!lstrcmpA(patch, "apple") ||
10713 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10714 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10715 ok(!lstrcmpA(transforms, "banana"),
10716 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10717 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10718
10719 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10720 (const BYTE *)"whatever", 9);
10721 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10722
10723 /* patch code value exists */
10724 size = MAX_PATH;
10725 lstrcpyA(patch, "apple");
10726 lstrcpyA(transforms, "banana");
10727 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10729 ok(!lstrcmpA(patch, patchcode),
10730 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10731 ok(!lstrcmpA(transforms, "whatever"),
10732 "Expected \"whatever\", got \"%s\"\n", transforms);
10733 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10734
10735 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10736 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10737 lstrcatA(keypath, prod_squashed);
10738
10739 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10740 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10741
10742 /* local UserData product key exists */
10743 size = MAX_PATH;
10744 lstrcpyA(patch, "apple");
10745 lstrcpyA(transforms, "banana");
10746 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10747 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10748 ok(!lstrcmpA(patch, patchcode),
10749 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10750 ok(!lstrcmpA(transforms, "whatever"),
10751 "Expected \"whatever\", got \"%s\"\n", transforms);
10752 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10753
10754 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10755 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10756
10757 /* local UserData Patches key exists */
10758 size = MAX_PATH;
10759 lstrcpyA(patch, "apple");
10760 lstrcpyA(transforms, "banana");
10761 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10763 ok(!lstrcmpA(patch, patchcode),
10764 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10765 ok(!lstrcmpA(transforms, "whatever"),
10766 "Expected \"whatever\", got \"%s\"\n", transforms);
10767 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10768
10769 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10770 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10771
10772 /* local UserData Product patch key exists */
10773 size = MAX_PATH;
10774 lstrcpyA(patch, "apple");
10775 lstrcpyA(transforms, "banana");
10776 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10777 ok(r == ERROR_NO_MORE_ITEMS ||
10778 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10779 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10780 ok(!lstrcmpA(patch, "apple") ||
10781 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10782 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10783 ok(!lstrcmpA(transforms, "banana") ||
10784 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10785 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10786 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10787
10788 data = MSIPATCHSTATE_APPLIED;
10789 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10790 (const BYTE *)&data, sizeof(DWORD));
10791 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10792
10793 /* State value exists */
10794 size = MAX_PATH;
10795 lstrcpyA(patch, "apple");
10796 lstrcpyA(transforms, "banana");
10797 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10799 ok(!lstrcmpA(patch, patchcode),
10800 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10801 ok(!lstrcmpA(transforms, "whatever"),
10802 "Expected \"whatever\", got \"%s\"\n", transforms);
10803 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10804
10805 /* now duplicate some of the tests for the W version */
10806
10807 /* pcchTransformsBuf is too small */
10808 size = 6;
10809 MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10810 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10811 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10812 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10813 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10814 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10815 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10816 ok(!lstrcmpA(patch, patchcode),
10817 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10818 ok(!lstrcmpA(transforms, "whate") ||
10819 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10820 "Expected \"whate\", got \"%s\"\n", transforms);
10821 ok(size == 8, "Expected 8, got %d\n", size);
10822
10823 /* patch code value exists */
10824 size = MAX_PATH;
10825 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10826 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10827 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10828 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10829 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10830 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10831 ok(!lstrcmpA(patch, patchcode),
10832 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10833 ok(!lstrcmpA(transforms, "whatever"),
10834 "Expected \"whatever\", got \"%s\"\n", transforms);
10835 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10836
10837 RegDeleteValueA(patches, patch_squashed);
10838 RegDeleteValueA(patches, "Patches");
10839 delete_key(patches, "", access & KEY_WOW64_64KEY);
10840 RegCloseKey(patches);
10841 RegDeleteValueA(hpatch, "State");
10842 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10843 RegCloseKey(hpatch);
10844 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10845 RegCloseKey(udpatch);
10846 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10847 RegCloseKey(udprod);
10848 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10849 RegCloseKey(prodkey);
10850 LocalFree(usersid);
10851 }
10852
10853 static void test_MsiGetPatchInfoEx(void)
10854 {
10855 CHAR keypath[MAX_PATH], val[MAX_PATH];
10856 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10857 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10858 HKEY prodkey, patches, udprod, props;
10859 HKEY hpatch, udpatch, prodpatches;
10860 LPSTR usersid;
10861 DWORD size;
10862 LONG res;
10863 UINT r;
10864 REGSAM access = KEY_ALL_ACCESS;
10865
10866 if (!pMsiGetPatchInfoExA)
10867 {
10868 win_skip("MsiGetPatchInfoEx not implemented\n");
10869 return;
10870 }
10871
10872 create_test_guid(prodcode, prod_squashed);
10873 create_test_guid(patchcode, patch_squashed);
10874 usersid = get_user_sid();
10875
10876 if (is_wow64)
10877 access |= KEY_WOW64_64KEY;
10878
10879 /* NULL szPatchCode */
10880 lstrcpyA(val, "apple");
10881 size = MAX_PATH;
10882 r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10883 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10884 ok(r == ERROR_INVALID_PARAMETER,
10885 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10886 ok(!lstrcmpA(val, "apple"),
10887 "Expected val to be unchanged, got \"%s\"\n", val);
10888 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10889
10890 /* empty szPatchCode */
10891 size = MAX_PATH;
10892 lstrcpyA(val, "apple");
10893 r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10894 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10895 ok(r == ERROR_INVALID_PARAMETER,
10896 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10897 ok(!lstrcmpA(val, "apple"),
10898 "Expected val to be unchanged, got \"%s\"\n", val);
10899 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10900
10901 /* garbage szPatchCode */
10902 size = MAX_PATH;
10903 lstrcpyA(val, "apple");
10904 r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10905 MSIINSTALLCONTEXT_USERMANAGED,
10906 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10907 ok(r == ERROR_INVALID_PARAMETER,
10908 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10909 ok(!lstrcmpA(val, "apple"),
10910 "Expected val to be unchanged, got \"%s\"\n", val);
10911 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10912
10913 /* guid without brackets */
10914 size = MAX_PATH;
10915 lstrcpyA(val, "apple");
10916 r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10917 NULL, MSIINSTALLCONTEXT_USERMANAGED,
10918 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10919 ok(r == ERROR_INVALID_PARAMETER,
10920 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10921 ok(!lstrcmpA(val, "apple"),
10922 "Expected val to be unchanged, got \"%s\"\n", val);
10923 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10924
10925 /* guid with brackets */
10926 size = MAX_PATH;
10927 lstrcpyA(val, "apple");
10928 r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10929 NULL, MSIINSTALLCONTEXT_USERMANAGED,
10930 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10931 ok(r == ERROR_UNKNOWN_PRODUCT,
10932 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10933 ok(!lstrcmpA(val, "apple"),
10934 "Expected val to be unchanged, got \"%s\"\n", val);
10935 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10936
10937 /* same length as guid, but random */
10938 size = MAX_PATH;
10939 lstrcpyA(val, "apple");
10940 r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10941 NULL, MSIINSTALLCONTEXT_USERMANAGED,
10942 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10943 ok(r == ERROR_INVALID_PARAMETER,
10944 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10945 ok(!lstrcmpA(val, "apple"),
10946 "Expected val to be unchanged, got \"%s\"\n", val);
10947 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10948
10949 /* NULL szProductCode */
10950 lstrcpyA(val, "apple");
10951 size = MAX_PATH;
10952 r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10953 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10954 ok(r == ERROR_INVALID_PARAMETER,
10955 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10956 ok(!lstrcmpA(val, "apple"),
10957 "Expected val to be unchanged, got \"%s\"\n", val);
10958 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10959
10960 /* empty szProductCode */
10961 size = MAX_PATH;
10962 lstrcpyA(val, "apple");
10963 r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10964 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10965 ok(r == ERROR_INVALID_PARAMETER,
10966 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10967 ok(!lstrcmpA(val, "apple"),
10968 "Expected val to be unchanged, got \"%s\"\n", val);
10969 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10970
10971 /* garbage szProductCode */
10972 size = MAX_PATH;
10973 lstrcpyA(val, "apple");
10974 r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10975 MSIINSTALLCONTEXT_USERMANAGED,
10976 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10977 ok(r == ERROR_INVALID_PARAMETER,
10978 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10979 ok(!lstrcmpA(val, "apple"),
10980 "Expected val to be unchanged, got \"%s\"\n", val);
10981 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10982
10983 /* guid without brackets */
10984 size = MAX_PATH;
10985 lstrcpyA(val, "apple");
10986 r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10987 NULL, MSIINSTALLCONTEXT_USERMANAGED,
10988 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10989 ok(r == ERROR_INVALID_PARAMETER,
10990 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10991 ok(!lstrcmpA(val, "apple"),
10992 "Expected val to be unchanged, got \"%s\"\n", val);
10993 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10994
10995 /* guid with brackets */
10996 size = MAX_PATH;
10997 lstrcpyA(val, "apple");
10998 r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10999 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11000 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11001 ok(r == ERROR_UNKNOWN_PRODUCT,
11002 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11003 ok(!lstrcmpA(val, "apple"),
11004 "Expected val to be unchanged, got \"%s\"\n", val);
11005 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11006
11007 /* same length as guid, but random */
11008 size = MAX_PATH;
11009 lstrcpyA(val, "apple");
11010 r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
11011 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11012 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11013 ok(r == ERROR_INVALID_PARAMETER,
11014 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11015 ok(!lstrcmpA(val, "apple"),
11016 "Expected val to be unchanged, got \"%s\"\n", val);
11017 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11018
11019 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
11020 size = MAX_PATH;
11021 lstrcpyA(val, "apple");
11022 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11023 MSIINSTALLCONTEXT_USERMANAGED,
11024 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11025 ok(r == ERROR_INVALID_PARAMETER,
11026 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11027 ok(!lstrcmpA(val, "apple"),
11028 "Expected val to be unchanged, got \"%s\"\n", val);
11029 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11030
11031 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
11032 size = MAX_PATH;
11033 lstrcpyA(val, "apple");
11034 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11035 MSIINSTALLCONTEXT_USERUNMANAGED,
11036 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11037 ok(r == ERROR_INVALID_PARAMETER,
11038 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11039 ok(!lstrcmpA(val, "apple"),
11040 "Expected val to be unchanged, got \"%s\"\n", val);
11041 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11042
11043 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
11044 size = MAX_PATH;
11045 lstrcpyA(val, "apple");
11046 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11047 MSIINSTALLCONTEXT_MACHINE,
11048 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11049 ok(r == ERROR_INVALID_PARAMETER,
11050 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11051 ok(!lstrcmpA(val, "apple"),
11052 "Expected val to be unchanged, got \"%s\"\n", val);
11053 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11054
11055 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
11056 size = MAX_PATH;
11057 lstrcpyA(val, "apple");
11058 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11059 MSIINSTALLCONTEXT_MACHINE,
11060 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11061 ok(r == ERROR_INVALID_PARAMETER,
11062 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11063 ok(!lstrcmpA(val, "apple"),
11064 "Expected val to be unchanged, got \"%s\"\n", val);
11065 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11066
11067 /* dwContext is out of range */
11068 size = MAX_PATH;
11069 lstrcpyA(val, "apple");
11070 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11071 MSIINSTALLCONTEXT_NONE,
11072 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11073 ok(r == ERROR_INVALID_PARAMETER,
11074 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11075 ok(!lstrcmpA(val, "apple"),
11076 "Expected val to be unchanged, got \"%s\"\n", val);
11077 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11078
11079 /* dwContext is out of range */
11080 size = MAX_PATH;
11081 lstrcpyA(val, "apple");
11082 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11083 MSIINSTALLCONTEXT_ALL,
11084 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11085 ok(r == ERROR_INVALID_PARAMETER,
11086 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11087 ok(!lstrcmpA(val, "apple"),
11088 "Expected val to be unchanged, got \"%s\"\n", val);
11089 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11090
11091 /* dwContext is invalid */
11092 size = MAX_PATH;
11093 lstrcpyA(val, "apple");
11094 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
11095 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11096 ok(r == ERROR_INVALID_PARAMETER,
11097 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11098 ok(!lstrcmpA(val, "apple"),
11099 "Expected val to be unchanged, got \"%s\"\n", val);
11100 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11101
11102 /* MSIINSTALLCONTEXT_USERMANAGED */
11103
11104 size = MAX_PATH;
11105 lstrcpyA(val, "apple");
11106 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11107 MSIINSTALLCONTEXT_USERMANAGED,
11108 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11109 ok(r == ERROR_UNKNOWN_PRODUCT,
11110 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11111 ok(!lstrcmpA(val, "apple"),
11112 "Expected val to be unchanged, got \"%s\"\n", val);
11113 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11114
11115 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11116 lstrcatA(keypath, usersid);
11117 lstrcatA(keypath, "\\Products\\");
11118 lstrcatA(keypath, prod_squashed);
11119
11120 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11121 if (res == ERROR_ACCESS_DENIED)
11122 {
11123 skip("Not enough rights to perform tests\n");
11124 LocalFree(usersid);
11125 return;
11126 }
11127 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11128
11129 /* local UserData product key exists */
11130 size = MAX_PATH;
11131 lstrcpyA(val, "apple");
11132 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11133 MSIINSTALLCONTEXT_USERMANAGED,
11134 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11135 ok(r == ERROR_UNKNOWN_PRODUCT,
11136 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11137 ok(!lstrcmpA(val, "apple"),
11138 "Expected val to be unchanged, got \"%s\"\n", val);
11139 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11140
11141 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11142 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11143
11144 /* InstallProperties key exists */
11145 size = MAX_PATH;
11146 lstrcpyA(val, "apple");
11147 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11148 MSIINSTALLCONTEXT_USERMANAGED,
11149 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11150 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11151 ok(!lstrcmpA(val, "apple"),
11152 "Expected val to be unchanged, got \"%s\"\n", val);
11153 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11154
11155 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11156 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11157
11158 /* Patches key exists */
11159 size = MAX_PATH;
11160 lstrcpyA(val, "apple");
11161 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11162 MSIINSTALLCONTEXT_USERMANAGED,
11163 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11164 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11165 ok(!lstrcmpA(val, "apple"),
11166 "Expected val to be unchanged, got \"%s\"\n", val);
11167 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11168
11169 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11170 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11171
11172 /* Patches key exists */
11173 size = MAX_PATH;
11174 lstrcpyA(val, "apple");
11175 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11176 MSIINSTALLCONTEXT_USERMANAGED,
11177 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11178 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11179 ok(!lstrcmpA(val, "apple"),
11180 "Expected val to be unchanged, got \"%s\"\n", val);
11181 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11182
11183 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11184 lstrcatA(keypath, usersid);
11185 lstrcatA(keypath, "\\Installer\\Products\\");
11186 lstrcatA(keypath, prod_squashed);
11187
11188 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11190
11191 /* managed product key exists */
11192 size = MAX_PATH;
11193 lstrcpyA(val, "apple");
11194 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11195 MSIINSTALLCONTEXT_USERMANAGED,
11196 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11197 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11198 ok(!lstrcmpA(val, "apple"),
11199 "Expected val to be unchanged, got \"%s\"\n", val);
11200 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11201
11202 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11203 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11204
11205 /* Patches key exists */
11206 size = MAX_PATH;
11207 lstrcpyA(val, "apple");
11208 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11209 MSIINSTALLCONTEXT_USERMANAGED,
11210 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11211 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11212 ok(!lstrcmpA(val, "apple"),
11213 "Expected val to be unchanged, got \"%s\"\n", val);
11214 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11215
11216 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11217 (const BYTE *)"transforms", 11);
11218 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11219
11220 /* specific patch value exists */
11221 size = MAX_PATH;
11222 lstrcpyA(val, "apple");
11223 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11224 MSIINSTALLCONTEXT_USERMANAGED,
11225 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11226 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11227 ok(!lstrcmpA(val, "apple"),
11228 "Expected val to be unchanged, got \"%s\"\n", val);
11229 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11230
11231 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11232 lstrcatA(keypath, usersid);
11233 lstrcatA(keypath, "\\Patches\\");
11234 lstrcatA(keypath, patch_squashed);
11235
11236 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11238
11239 /* UserData Patches key exists */
11240 size = MAX_PATH;
11241 lstrcpyA(val, "apple");
11242 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11243 MSIINSTALLCONTEXT_USERMANAGED,
11244 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11246 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11247 ok(size == 0, "Expected 0, got %d\n", size);
11248
11249 res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
11250 (const BYTE *)"pack", 5);
11251 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11252
11253 /* ManagedLocalPatch value exists */
11254 size = MAX_PATH;
11255 lstrcpyA(val, "apple");
11256 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11257 MSIINSTALLCONTEXT_USERMANAGED,
11258 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11260 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11261 ok(size == 4, "Expected 4, got %d\n", size);
11262
11263 size = MAX_PATH;
11264 lstrcpyA(val, "apple");
11265 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11266 MSIINSTALLCONTEXT_USERMANAGED,
11267 INSTALLPROPERTY_TRANSFORMS, val, &size);
11268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11269 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11270 ok(size == 10, "Expected 10, got %d\n", size);
11271
11272 res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
11273 (const BYTE *)"mydate", 7);
11274 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11275
11276 /* Installed value exists */
11277 size = MAX_PATH;
11278 lstrcpyA(val, "apple");
11279 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11280 MSIINSTALLCONTEXT_USERMANAGED,
11281 INSTALLPROPERTY_INSTALLDATE, val, &size);
11282 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11283 ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
11284 ok(size == 6, "Expected 6, got %d\n", size);
11285
11286 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
11287 (const BYTE *)"yes", 4);
11288 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11289
11290 /* Uninstallable value exists */
11291 size = MAX_PATH;
11292 lstrcpyA(val, "apple");
11293 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11294 MSIINSTALLCONTEXT_USERMANAGED,
11295 INSTALLPROPERTY_UNINSTALLABLE, val, &size);
11296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11297 ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
11298 ok(size == 3, "Expected 3, got %d\n", size);
11299
11300 res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
11301 (const BYTE *)"good", 5);
11302 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11303
11304 /* State value exists */
11305 size = MAX_PATH;
11306 lstrcpyA(val, "apple");
11307 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11308 MSIINSTALLCONTEXT_USERMANAGED,
11309 INSTALLPROPERTY_PATCHSTATE, val, &size);
11310 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11311 ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
11312 ok(size == 4, "Expected 4, got %d\n", size);
11313
11314 size = 1;
11315 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11316 (const BYTE *)&size, sizeof(DWORD));
11317 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11318
11319 /* State value exists */
11320 size = MAX_PATH;
11321 lstrcpyA(val, "apple");
11322 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11323 MSIINSTALLCONTEXT_USERMANAGED,
11324 INSTALLPROPERTY_PATCHSTATE, val, &size);
11325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11326 todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
11327 ok(size == 1, "Expected 1, got %d\n", size);
11328
11329 res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
11330 (const BYTE *)"display", 8);
11331 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11332
11333 /* DisplayName value exists */
11334 size = MAX_PATH;
11335 lstrcpyA(val, "apple");
11336 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11337 MSIINSTALLCONTEXT_USERMANAGED,
11338 INSTALLPROPERTY_DISPLAYNAME, val, &size);
11339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11340 ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
11341 ok(size == 7, "Expected 7, got %d\n", size);
11342
11343 res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
11344 (const BYTE *)"moreinfo", 9);
11345 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11346
11347 /* MoreInfoURL value exists */
11348 size = MAX_PATH;
11349 lstrcpyA(val, "apple");
11350 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11351 MSIINSTALLCONTEXT_USERMANAGED,
11352 INSTALLPROPERTY_MOREINFOURL, val, &size);
11353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11354 ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
11355 ok(size == 8, "Expected 8, got %d\n", size);
11356
11357 /* szProperty is invalid */
11358 size = MAX_PATH;
11359 lstrcpyA(val, "apple");
11360 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11361 MSIINSTALLCONTEXT_USERMANAGED,
11362 "IDontExist", val, &size);
11363 ok(r == ERROR_UNKNOWN_PROPERTY,
11364 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
11365 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11366 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11367
11368 /* lpValue is NULL, while pcchValue is non-NULL */
11369 size = MAX_PATH;
11370 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11371 MSIINSTALLCONTEXT_USERMANAGED,
11372 INSTALLPROPERTY_MOREINFOURL, NULL, &size);
11373 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11374 ok(size == 16, "Expected 16, got %d\n", size);
11375
11376 /* pcchValue is NULL, while lpValue is non-NULL */
11377 lstrcpyA(val, "apple");
11378 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11379 MSIINSTALLCONTEXT_USERMANAGED,
11380 INSTALLPROPERTY_MOREINFOURL, val, NULL);
11381 ok(r == ERROR_INVALID_PARAMETER,
11382 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11383 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11384
11385 /* both lpValue and pcchValue are NULL */
11386 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11387 MSIINSTALLCONTEXT_USERMANAGED,
11388 INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
11389 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11390
11391 /* pcchValue doesn't have enough room for NULL terminator */
11392 size = 8;
11393 lstrcpyA(val, "apple");
11394 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11395 MSIINSTALLCONTEXT_USERMANAGED,
11396 INSTALLPROPERTY_MOREINFOURL, val, &size);
11397 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11398 ok(!lstrcmpA(val, "moreinf"),
11399 "Expected \"moreinf\", got \"%s\"\n", val);
11400 ok(size == 16, "Expected 16, got %d\n", size);
11401
11402 /* pcchValue has exactly enough room for NULL terminator */
11403 size = 9;
11404 lstrcpyA(val, "apple");
11405 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11406 MSIINSTALLCONTEXT_USERMANAGED,
11407 INSTALLPROPERTY_MOREINFOURL, val, &size);
11408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11409 ok(!lstrcmpA(val, "moreinfo"),
11410 "Expected \"moreinfo\", got \"%s\"\n", val);
11411 ok(size == 8, "Expected 8, got %d\n", size);
11412
11413 /* pcchValue is too small, lpValue is NULL */
11414 size = 0;
11415 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11416 MSIINSTALLCONTEXT_USERMANAGED,
11417 INSTALLPROPERTY_MOREINFOURL, NULL, &size);
11418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11419 ok(size == 16, "Expected 16, got %d\n", size);
11420
11421 RegDeleteValueA(prodpatches, patch_squashed);
11422 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11423 RegCloseKey(prodpatches);
11424 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11425 RegCloseKey(prodkey);
11426
11427 /* UserData is sufficient for all properties
11428 * except INSTALLPROPERTY_TRANSFORMS
11429 */
11430 size = MAX_PATH;
11431 lstrcpyA(val, "apple");
11432 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11433 MSIINSTALLCONTEXT_USERMANAGED,
11434 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11435 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11436 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11437 ok(size == 4, "Expected 4, got %d\n", size);
11438
11439 /* UserData is sufficient for all properties
11440 * except INSTALLPROPERTY_TRANSFORMS
11441 */
11442 size = MAX_PATH;
11443 lstrcpyA(val, "apple");
11444 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11445 MSIINSTALLCONTEXT_USERMANAGED,
11446 INSTALLPROPERTY_TRANSFORMS, val, &size);
11447 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11448 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11449 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11450
11451 RegDeleteValueA(hpatch, "MoreInfoURL");
11452 RegDeleteValueA(hpatch, "Display");
11453 RegDeleteValueA(hpatch, "State");
11454 RegDeleteValueA(hpatch, "Uninstallable");
11455 RegDeleteValueA(hpatch, "Installed");
11456 RegDeleteValueA(udpatch, "ManagedLocalPackage");
11457 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11458 RegCloseKey(udpatch);
11459 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11460 RegCloseKey(hpatch);
11461 delete_key(patches, "", access & KEY_WOW64_64KEY);
11462 RegCloseKey(patches);
11463 delete_key(props, "", access & KEY_WOW64_64KEY);
11464 RegCloseKey(props);
11465 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11466 RegCloseKey(udprod);
11467
11468 /* MSIINSTALLCONTEXT_USERUNMANAGED */
11469
11470 size = MAX_PATH;
11471 lstrcpyA(val, "apple");
11472 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11473 MSIINSTALLCONTEXT_USERUNMANAGED,
11474 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11475 ok(r == ERROR_UNKNOWN_PRODUCT,
11476 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11477 ok(!lstrcmpA(val, "apple"),
11478 "Expected val to be unchanged, got \"%s\"\n", val);
11479 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11480
11481 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11482 lstrcatA(keypath, usersid);
11483 lstrcatA(keypath, "\\Products\\");
11484 lstrcatA(keypath, prod_squashed);
11485
11486 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11487 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11488
11489 /* local UserData product key exists */
11490 size = MAX_PATH;
11491 lstrcpyA(val, "apple");
11492 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11493 MSIINSTALLCONTEXT_USERUNMANAGED,
11494 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11495 ok(r == ERROR_UNKNOWN_PRODUCT,
11496 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11497 ok(!lstrcmpA(val, "apple"),
11498 "Expected val to be unchanged, got \"%s\"\n", val);
11499 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11500
11501 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11502 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11503
11504 /* InstallProperties key exists */
11505 size = MAX_PATH;
11506 lstrcpyA(val, "apple");
11507 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11508 MSIINSTALLCONTEXT_USERUNMANAGED,
11509 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11510 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11511 ok(!lstrcmpA(val, "apple"),
11512 "Expected val to be unchanged, got \"%s\"\n", val);
11513 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11514
11515 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11516 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11517
11518 /* Patches key exists */
11519 size = MAX_PATH;
11520 lstrcpyA(val, "apple");
11521 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11522 MSIINSTALLCONTEXT_USERUNMANAGED,
11523 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11524 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11525 ok(!lstrcmpA(val, "apple"),
11526 "Expected val to be unchanged, got \"%s\"\n", val);
11527 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11528
11529 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11530 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11531
11532 /* Patches key exists */
11533 size = MAX_PATH;
11534 lstrcpyA(val, "apple");
11535 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11536 MSIINSTALLCONTEXT_USERUNMANAGED,
11537 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11538 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11539 ok(!lstrcmpA(val, "apple"),
11540 "Expected val to be unchanged, got \"%s\"\n", val);
11541 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11542
11543 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11544 lstrcatA(keypath, prod_squashed);
11545
11546 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11547 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11548
11549 /* current user product key exists */
11550 size = MAX_PATH;
11551 lstrcpyA(val, "apple");
11552 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11553 MSIINSTALLCONTEXT_USERUNMANAGED,
11554 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11555 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11556 ok(!lstrcmpA(val, "apple"),
11557 "Expected val to be unchanged, got \"%s\"\n", val);
11558 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11559
11560 res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
11561 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11562
11563 /* Patches key exists */
11564 size = MAX_PATH;
11565 lstrcpyA(val, "apple");
11566 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11567 MSIINSTALLCONTEXT_USERUNMANAGED,
11568 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11569 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11570 ok(!lstrcmpA(val, "apple"),
11571 "Expected val to be unchanged, got \"%s\"\n", val);
11572 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11573
11574 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11575 (const BYTE *)"transforms", 11);
11576 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11577
11578 /* specific patch value exists */
11579 size = MAX_PATH;
11580 lstrcpyA(val, "apple");
11581 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11582 MSIINSTALLCONTEXT_USERUNMANAGED,
11583 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11584 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11585 ok(!lstrcmpA(val, "apple"),
11586 "Expected val to be unchanged, got \"%s\"\n", val);
11587 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11588
11589 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11590 lstrcatA(keypath, usersid);
11591 lstrcatA(keypath, "\\Patches\\");
11592 lstrcatA(keypath, patch_squashed);
11593
11594 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11595 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11596
11597 /* UserData Patches key exists */
11598 size = MAX_PATH;
11599 lstrcpyA(val, "apple");
11600 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11601 MSIINSTALLCONTEXT_USERUNMANAGED,
11602 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11603 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11604 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11605 ok(size == 0, "Expected 0, got %d\n", size);
11606
11607 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11608 (const BYTE *)"pack", 5);
11609 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11610
11611 /* LocalPatch value exists */
11612 size = MAX_PATH;
11613 lstrcpyA(val, "apple");
11614 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11615 MSIINSTALLCONTEXT_USERUNMANAGED,
11616 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11617 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11618 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11619 ok(size == 4, "Expected 4, got %d\n", size);
11620
11621 size = MAX_PATH;
11622 lstrcpyA(val, "apple");
11623 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11624 MSIINSTALLCONTEXT_USERUNMANAGED,
11625 INSTALLPROPERTY_TRANSFORMS, val, &size);
11626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11627 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11628 ok(size == 10, "Expected 10, got %d\n", size);
11629
11630 RegDeleteValueA(prodpatches, patch_squashed);
11631 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11632 RegCloseKey(prodpatches);
11633 RegDeleteKeyA(prodkey, "");
11634 RegCloseKey(prodkey);
11635
11636 /* UserData is sufficient for all properties
11637 * except INSTALLPROPERTY_TRANSFORMS
11638 */
11639 size = MAX_PATH;
11640 lstrcpyA(val, "apple");
11641 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11642 MSIINSTALLCONTEXT_USERUNMANAGED,
11643 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11645 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11646 ok(size == 4, "Expected 4, got %d\n", size);
11647
11648 /* UserData is sufficient for all properties
11649 * except INSTALLPROPERTY_TRANSFORMS
11650 */
11651 size = MAX_PATH;
11652 lstrcpyA(val, "apple");
11653 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11654 MSIINSTALLCONTEXT_USERUNMANAGED,
11655 INSTALLPROPERTY_TRANSFORMS, val, &size);
11656 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11657 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11658 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11659
11660 RegDeleteValueA(udpatch, "LocalPackage");
11661 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11662 RegCloseKey(udpatch);
11663 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11664 RegCloseKey(hpatch);
11665 delete_key(patches, "", access & KEY_WOW64_64KEY);
11666 RegCloseKey(patches);
11667 delete_key(props, "", access & KEY_WOW64_64KEY);
11668 RegCloseKey(props);
11669 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11670 RegCloseKey(udprod);
11671
11672 /* MSIINSTALLCONTEXT_MACHINE */
11673
11674 size = MAX_PATH;
11675 lstrcpyA(val, "apple");
11676 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11677 MSIINSTALLCONTEXT_MACHINE,
11678 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11679 ok(r == ERROR_UNKNOWN_PRODUCT,
11680 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11681 ok(!lstrcmpA(val, "apple"),
11682 "Expected val to be unchanged, got \"%s\"\n", val);
11683 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11684
11685 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11686 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11687 lstrcatA(keypath, prod_squashed);
11688
11689 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11690 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11691
11692 /* local UserData product key exists */
11693 size = MAX_PATH;
11694 lstrcpyA(val, "apple");
11695 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11696 MSIINSTALLCONTEXT_MACHINE,
11697 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11698 ok(r == ERROR_UNKNOWN_PRODUCT,
11699 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11700 ok(!lstrcmpA(val, "apple"),
11701 "Expected val to be unchanged, got \"%s\"\n", val);
11702 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11703
11704 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11705 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11706
11707 /* InstallProperties key exists */
11708 size = MAX_PATH;
11709 lstrcpyA(val, "apple");
11710 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11711 MSIINSTALLCONTEXT_MACHINE,
11712 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11713 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11714 ok(!lstrcmpA(val, "apple"),
11715 "Expected val to be unchanged, got \"%s\"\n", val);
11716 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11717
11718 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11719 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11720
11721 /* Patches key exists */
11722 size = MAX_PATH;
11723 lstrcpyA(val, "apple");
11724 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11725 MSIINSTALLCONTEXT_MACHINE,
11726 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11727 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11728 ok(!lstrcmpA(val, "apple"),
11729 "Expected val to be unchanged, got \"%s\"\n", val);
11730 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11731
11732 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11733 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11734
11735 /* Patches key exists */
11736 size = MAX_PATH;
11737 lstrcpyA(val, "apple");
11738 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11739 MSIINSTALLCONTEXT_MACHINE,
11740 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11741 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11742 ok(!lstrcmpA(val, "apple"),
11743 "Expected val to be unchanged, got \"%s\"\n", val);
11744 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11745
11746 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11747 lstrcatA(keypath, prod_squashed);
11748
11749 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11750 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11751
11752 /* local product key exists */
11753 size = MAX_PATH;
11754 lstrcpyA(val, "apple");
11755 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11756 MSIINSTALLCONTEXT_MACHINE,
11757 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11758 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11759 ok(!lstrcmpA(val, "apple"),
11760 "Expected val to be unchanged, got \"%s\"\n", val);
11761 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11762
11763 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11764 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11765
11766 /* Patches key exists */
11767 size = MAX_PATH;
11768 lstrcpyA(val, "apple");
11769 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11770 MSIINSTALLCONTEXT_MACHINE,
11771 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11772 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11773 ok(!lstrcmpA(val, "apple"),
11774 "Expected val to be unchanged, got \"%s\"\n", val);
11775 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11776
11777 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11778 (const BYTE *)"transforms", 11);
11779 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11780
11781 /* specific patch value exists */
11782 size = MAX_PATH;
11783 lstrcpyA(val, "apple");
11784 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11785 MSIINSTALLCONTEXT_MACHINE,
11786 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11787 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11788 ok(!lstrcmpA(val, "apple"),
11789 "Expected val to be unchanged, got \"%s\"\n", val);
11790 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11791
11792 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11793 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11794 lstrcatA(keypath, patch_squashed);
11795
11796 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11797 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11798
11799 /* UserData Patches key exists */
11800 size = MAX_PATH;
11801 lstrcpyA(val, "apple");
11802 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11803 MSIINSTALLCONTEXT_MACHINE,
11804 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11805 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11806 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11807 ok(size == 0, "Expected 0, got %d\n", size);
11808
11809 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11810 (const BYTE *)"pack", 5);
11811 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11812
11813 /* LocalPatch value exists */
11814 size = MAX_PATH;
11815 lstrcpyA(val, "apple");
11816 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11817 MSIINSTALLCONTEXT_MACHINE,
11818 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11820 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11821 ok(size == 4, "Expected 4, got %d\n", size);
11822
11823 size = MAX_PATH;
11824 lstrcpyA(val, "apple");
11825 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11826 MSIINSTALLCONTEXT_MACHINE,
11827 INSTALLPROPERTY_TRANSFORMS, val, &size);
11828 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11829 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11830 ok(size == 10, "Expected 10, got %d\n", size);
11831
11832 RegDeleteValueA(prodpatches, patch_squashed);
11833 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11834 RegCloseKey(prodpatches);
11835 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11836 RegCloseKey(prodkey);
11837
11838 /* UserData is sufficient for all properties
11839 * except INSTALLPROPERTY_TRANSFORMS
11840 */
11841 size = MAX_PATH;
11842 lstrcpyA(val, "apple");
11843 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11844 MSIINSTALLCONTEXT_MACHINE,
11845 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11846 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11847 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11848 ok(size == 4, "Expected 4, got %d\n", size);
11849
11850 /* UserData is sufficient for all properties
11851 * except INSTALLPROPERTY_TRANSFORMS
11852 */
11853 size = MAX_PATH;
11854 lstrcpyA(val, "apple");
11855 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11856 MSIINSTALLCONTEXT_MACHINE,
11857 INSTALLPROPERTY_TRANSFORMS, val, &size);
11858 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11859 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11860 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11861
11862 RegDeleteValueA(udpatch, "LocalPackage");
11863 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11864 RegCloseKey(udpatch);
11865 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11866 RegCloseKey(hpatch);
11867 delete_key(patches, "", access & KEY_WOW64_64KEY);
11868 RegCloseKey(patches);
11869 delete_key(props, "", access & KEY_WOW64_64KEY);
11870 RegCloseKey(props);
11871 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11872 RegCloseKey(udprod);
11873 LocalFree(usersid);
11874 }
11875
11876 static void test_MsiGetPatchInfo(void)
11877 {
11878 UINT r;
11879 char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11880 char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11881 WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11882 HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11883 HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11884 DWORD size;
11885 LONG res;
11886 REGSAM access = KEY_ALL_ACCESS;
11887
11888 create_test_guid(patch_code, patch_squashed);
11889 create_test_guid(prod_code, prod_squashed);
11890 MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11891
11892 if (is_wow64)
11893 access |= KEY_WOW64_64KEY;
11894
11895 r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11896 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11897
11898 r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11899 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11900
11901 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11902 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11903
11904 size = 0;
11905 r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11906 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11907
11908 r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11909 ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11910
11911 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11912 lstrcatA(keypath, prod_squashed);
11913
11914 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11915 if (res == ERROR_ACCESS_DENIED)
11916 {
11917 skip("Not enough rights to perform tests\n");
11918 return;
11919 }
11920 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11921
11922 /* product key exists */
11923 size = MAX_PATH;
11924 lstrcpyA(val, "apple");
11925 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11926 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11927 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11928 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11929
11930 res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11931 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11932
11933 /* patches key exists */
11934 size = MAX_PATH;
11935 lstrcpyA(val, "apple");
11936 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11937 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11938 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11939 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11940
11941 res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11942 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11943
11944 /* patch key exists */
11945 size = MAX_PATH;
11946 lstrcpyA(val, "apple");
11947 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11948 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11949 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11950 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11951
11952 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11953 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11954 lstrcatA(keypath, prod_squashed);
11955
11956 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11958
11959 /* UserData product key exists */
11960 size = MAX_PATH;
11961 lstrcpyA(val, "apple");
11962 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11963 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11964 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11965 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11966
11967 res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11968 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11969
11970 /* InstallProperties key exists */
11971 size = MAX_PATH;
11972 lstrcpyA(val, "apple");
11973 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11974 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11975 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11976 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11977
11978 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11979 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11980
11981 /* UserData Patches key exists */
11982 size = MAX_PATH;
11983 lstrcpyA(val, "apple");
11984 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11985 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11986 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11987 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11988
11989 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11990 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11991
11992 res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11993 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11994
11995 /* UserData product patch key exists */
11996 size = MAX_PATH;
11997 lstrcpyA(val, "apple");
11998 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11999 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12000 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12001 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12002
12003 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12004 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
12005 lstrcatA(keypath, patch_squashed);
12006
12007 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
12008 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12009
12010 res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
12011 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12012
12013 /* UserData Patch key exists */
12014 size = 0;
12015 lstrcpyA(val, "apple");
12016 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12017 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
12018 ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
12019 ok(size == 11, "expected 11 got %u\n", size);
12020
12021 size = MAX_PATH;
12022 lstrcpyA(val, "apple");
12023 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12024 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
12025 ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
12026 ok(size == 11, "expected 11 got %u\n", size);
12027
12028 size = 0;
12029 valW[0] = 0;
12030 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
12031 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
12032 ok(!valW[0], "expected 0 got %u\n", valW[0]);
12033 ok(size == 11, "expected 11 got %u\n", size);
12034
12035 size = MAX_PATH;
12036 valW[0] = 0;
12037 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
12038 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
12039 ok(valW[0], "expected > 0 got %u\n", valW[0]);
12040 ok(size == 11, "expected 11 got %u\n", size);
12041
12042 delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
12043 RegCloseKey(hkey_udproductpatch);
12044 delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
12045 RegCloseKey(hkey_udproductpatches);
12046 delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
12047 RegCloseKey(hkey_udpatch);
12048 delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
12049 RegCloseKey(hkey_patches);
12050 delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
12051 RegCloseKey(hkey_product);
12052 delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
12053 RegCloseKey(hkey_patch);
12054 delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
12055 RegCloseKey(hkey_udpatches);
12056 delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
12057 RegCloseKey(hkey_udprops);
12058 delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
12059 RegCloseKey(hkey_udproduct);
12060 }
12061
12062 static void test_MsiEnumProducts(void)
12063 {
12064 UINT r;
12065 int found1, found2, found3;
12066 DWORD index;
12067 char product1[39], product2[39], product3[39], guid[39];
12068 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
12069 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
12070 char *usersid;
12071 HKEY key1, key2, key3;
12072 REGSAM access = KEY_ALL_ACCESS;
12073
12074 create_test_guid(product1, product_squashed1);
12075 create_test_guid(product2, product_squashed2);
12076 create_test_guid(product3, product_squashed3);
12077 usersid = get_user_sid();
12078
12079 if (is_wow64)
12080 access |= KEY_WOW64_64KEY;
12081
12082 strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
12083 strcat(keypath1, product_squashed1);
12084
12085 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
12086 if (r == ERROR_ACCESS_DENIED)
12087 {
12088 skip("Not enough rights to perform tests\n");
12089 LocalFree(usersid);
12090 return;
12091 }
12092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12093
12094 strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
12095 strcat(keypath2, usersid);
12096 strcat(keypath2, "\\Installer\\Products\\");
12097 strcat(keypath2, product_squashed2);
12098
12099 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
12100 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12101
12102 strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
12103 strcat(keypath3, product_squashed3);
12104
12105 r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
12106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12107
12108 index = 0;
12109 r = MsiEnumProductsA(index, guid);
12110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12111
12112 r = MsiEnumProductsA(index, NULL);
12113 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12114
12115 index = 2;
12116 r = MsiEnumProductsA(index, guid);
12117 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12118
12119 index = 0;
12120 r = MsiEnumProductsA(index, guid);
12121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12122
12123 found1 = found2 = found3 = 0;
12124 while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
12125 {
12126 if (!strcmp(product1, guid)) found1 = 1;
12127 if (!strcmp(product2, guid)) found2 = 1;
12128 if (!strcmp(product3, guid)) found3 = 1;
12129 index++;
12130 }
12131 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
12132 ok(found1, "product1 not found\n");
12133 ok(found2, "product2 not found\n");
12134 ok(found3, "product3 not found\n");
12135
12136 delete_key(key1, "", access & KEY_WOW64_64KEY);
12137 delete_key(key2, "", access & KEY_WOW64_64KEY);
12138 RegDeleteKeyA(key3, "");
12139 RegCloseKey(key1);
12140 RegCloseKey(key2);
12141 RegCloseKey(key3);
12142 LocalFree(usersid);
12143 }
12144
12145 static void test_MsiGetFileSignatureInformation(void)
12146 {
12147 HRESULT hr;
12148 const CERT_CONTEXT *cert;
12149 DWORD len;
12150
12151 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
12152 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12153
12154 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
12155 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12156
12157 hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
12158 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12159
12160 hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
12161 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12162
12163 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
12164 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12165
12166 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
12167 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12168
12169 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
12170 todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
12171
12172 create_file( "signature.bin", "signature", sizeof("signature") );
12173
12174 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
12175 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12176
12177 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
12178 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12179
12180 cert = (const CERT_CONTEXT *)0xdeadbeef;
12181 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
12182 todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
12183 ok(cert == NULL, "got %p\n", cert);
12184
12185 DeleteFileA( "signature.bin" );
12186 }
12187
12188 static void test_MsiEnumProductsEx(void)
12189 {
12190 UINT r;
12191 DWORD len, index;
12192 MSIINSTALLCONTEXT context;
12193 char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
12194 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
12195 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
12196 HKEY key1 = NULL, key2 = NULL, key3 = NULL;
12197 REGSAM access = KEY_ALL_ACCESS;
12198 char *usersid = get_user_sid();
12199
12200 if (!pMsiEnumProductsExA)
12201 {
12202 win_skip("MsiEnumProductsExA not implemented\n");
12203 return;
12204 }
12205
12206 create_test_guid( product0, NULL );
12207 create_test_guid( product1, product_squashed1 );
12208 create_test_guid( product2, product_squashed2 );
12209 create_test_guid( product3, product_squashed3 );
12210
12211 if (is_wow64) access |= KEY_WOW64_64KEY;
12212
12213 strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
12214 strcat( keypath1, product_squashed1 );
12215
12216 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12217 if (r == ERROR_ACCESS_DENIED)
12218 {
12219 skip( "insufficient rights\n" );
12220 goto done;
12221 }
12222 ok( r == ERROR_SUCCESS, "got %u\n", r );
12223
12224 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
12225 strcat( keypath2, usersid );
12226 strcat( keypath2, "\\Installer\\Products\\" );
12227 strcat( keypath2, product_squashed2 );
12228
12229 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12230 ok( r == ERROR_SUCCESS, "got %u\n", r );
12231
12232 strcpy( keypath3, usersid );
12233 strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
12234 strcat( keypath3, product_squashed3 );
12235
12236 r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
12237 ok( r == ERROR_SUCCESS, "got %u\n", r );
12238
12239 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
12240 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12241
12242 len = sizeof(sid);
12243 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
12244 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12245 ok( len == sizeof(sid), "got %u\n", len );
12246
12247 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
12248 ok( r == ERROR_SUCCESS, "got %u\n", r );
12249
12250 sid[0] = 0;
12251 len = sizeof(sid);
12252 r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
12253 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
12254 ok( len == sizeof(sid), "got %u\n", len );
12255 ok( !sid[0], "got %s\n", sid );
12256
12257 sid[0] = 0;
12258 len = sizeof(sid);
12259 r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
12260 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
12261 ok( len == sizeof(sid), "got %u\n", len );
12262 ok( !sid[0], "got %s\n", sid );
12263
12264 sid[0] = 0;
12265 len = 0;
12266 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
12267 ok( r == ERROR_MORE_DATA, "got %u\n", r );
12268 ok( len, "length unchanged\n" );
12269 ok( !sid[0], "got %s\n", sid );
12270
12271 guid[0] = 0;
12272 context = 0xdeadbeef;
12273 sid[0] = 0;
12274 len = sizeof(sid);
12275 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
12276 ok( r == ERROR_SUCCESS, "got %u\n", r );
12277 ok( guid[0], "empty guid\n" );
12278 ok( context != 0xdeadbeef, "context unchanged\n" );
12279 ok( !len, "got %u\n", len );
12280 ok( !sid[0], "got %s\n", sid );
12281
12282 guid[0] = 0;
12283 context = 0xdeadbeef;
12284 sid[0] = 0;
12285 len = sizeof(sid);
12286 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
12287 ok( r == ERROR_SUCCESS, "got %u\n", r );
12288 ok( guid[0], "empty guid\n" );
12289 ok( context != 0xdeadbeef, "context unchanged\n" );
12290 ok( !len, "got %u\n", len );
12291 ok( !sid[0], "got %s\n", sid );
12292
12293 guid[0] = 0;
12294 context = 0xdeadbeef;
12295 sid[0] = 0;
12296 len = sizeof(sid);
12297 r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
12298 if (r == ERROR_ACCESS_DENIED)
12299 {
12300 skip( "insufficient rights\n" );
12301 goto done;
12302 }
12303 ok( r == ERROR_SUCCESS, "got %u\n", r );
12304 ok( guid[0], "empty guid\n" );
12305 ok( context != 0xdeadbeef, "context unchanged\n" );
12306 ok( !len, "got %u\n", len );
12307 ok( !sid[0], "got %s\n", sid );
12308
12309 index = 0;
12310 guid[0] = 0;
12311 context = 0xdeadbeef;
12312 sid[0] = 0;
12313 len = sizeof(sid);
12314 while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
12315 {
12316 if (!strcmp( product1, guid ))
12317 {
12318 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
12319 ok( !sid[0], "got \"%s\"\n", sid );
12320 ok( !len, "unexpected length %u\n", len );
12321 }
12322 if (!strcmp( product2, guid ))
12323 {
12324 ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
12325 ok( sid[0], "empty sid\n" );
12326 ok( len == strlen(sid), "unexpected length %u\n", len );
12327 }
12328 if (!strcmp( product3, guid ))
12329 {
12330 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
12331 ok( sid[0], "empty sid\n" );
12332 ok( len == strlen(sid), "unexpected length %u\n", len );
12333 }
12334 index++;
12335 guid[0] = 0;
12336 context = 0xdeadbeef;
12337 sid[0] = 0;
12338 len = sizeof(sid);
12339 }
12340
12341 done:
12342 delete_key( key1, "", access );
12343 delete_key( key2, "", access );
12344 delete_key( key3, "", access );
12345 RegCloseKey( key1 );
12346 RegCloseKey( key2 );
12347 RegCloseKey( key3 );
12348 LocalFree( usersid );
12349 }
12350
12351 static void test_MsiEnumComponents(void)
12352 {
12353 UINT r;
12354 int found1, found2;
12355 DWORD index;
12356 char comp1[39], comp2[39], guid[39];
12357 char comp_squashed1[33], comp_squashed2[33];
12358 char keypath1[MAX_PATH], keypath2[MAX_PATH];
12359 REGSAM access = KEY_ALL_ACCESS;
12360 char *usersid = get_user_sid();
12361 HKEY key1 = NULL, key2 = NULL;
12362
12363 create_test_guid( comp1, comp_squashed1 );
12364 create_test_guid( comp2, comp_squashed2 );
12365
12366 if (is_wow64) access |= KEY_WOW64_64KEY;
12367
12368 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12369 strcat( keypath1, "S-1-5-18\\Components\\" );
12370 strcat( keypath1, comp_squashed1 );
12371
12372 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12373 if (r == ERROR_ACCESS_DENIED)
12374 {
12375 skip( "insufficient rights\n" );
12376 goto done;
12377 }
12378 ok( r == ERROR_SUCCESS, "got %u\n", r );
12379
12380 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12381 strcat( keypath2, usersid );
12382 strcat( keypath2, "\\Components\\" );
12383 strcat( keypath2, comp_squashed2 );
12384
12385 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12386 if (r == ERROR_ACCESS_DENIED)
12387 {
12388 skip( "insufficient rights\n" );
12389 goto done;
12390 }
12391
12392 r = MsiEnumComponentsA( 0, NULL );
12393 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12394
12395 index = 0;
12396 guid[0] = 0;
12397 found1 = found2 = 0;
12398 while (!MsiEnumComponentsA( index, guid ))
12399 {
12400 if (!strcmp( guid, comp1 )) found1 = 1;
12401 if (!strcmp( guid, comp2 )) found2 = 1;
12402 ok( guid[0], "empty guid\n" );
12403 guid[0] = 0;
12404 index++;
12405 }
12406 ok( found1, "comp1 not found\n" );
12407 ok( found2, "comp2 not found\n" );
12408
12409 done:
12410 delete_key( key1, "", access );
12411 delete_key( key2, "", access );
12412 RegCloseKey( key1 );
12413 RegCloseKey( key2 );
12414 LocalFree( usersid );
12415 }
12416
12417 static void test_MsiEnumComponentsEx(void)
12418 {
12419 UINT r;
12420 int found1, found2;
12421 DWORD len, index;
12422 MSIINSTALLCONTEXT context;
12423 char comp1[39], comp2[39], guid[39], sid[128];
12424 char comp_squashed1[33], comp_squashed2[33];
12425 char keypath1[MAX_PATH], keypath2[MAX_PATH];
12426 HKEY key1 = NULL, key2 = NULL;
12427 REGSAM access = KEY_ALL_ACCESS;
12428 char *usersid = get_user_sid();
12429
12430 if (!pMsiEnumComponentsExA)
12431 {
12432 win_skip( "MsiEnumComponentsExA not implemented\n" );
12433 return;
12434 }
12435 create_test_guid( comp1, comp_squashed1 );
12436 create_test_guid( comp2, comp_squashed2 );
12437
12438 if (is_wow64) access |= KEY_WOW64_64KEY;
12439
12440 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12441 strcat( keypath1, "S-1-5-18\\Components\\" );
12442 strcat( keypath1, comp_squashed1 );
12443
12444 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12445 if (r == ERROR_ACCESS_DENIED)
12446 {
12447 skip( "insufficient rights\n" );
12448 goto done;
12449 }
12450 ok( r == ERROR_SUCCESS, "got %u\n", r );
12451
12452 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
12453 strcat( keypath2, usersid );
12454 strcat( keypath2, "\\Components\\" );
12455 strcat( keypath2, comp_squashed2 );
12456
12457 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12458 if (r == ERROR_ACCESS_DENIED)
12459 {
12460 skip( "insufficient rights\n" );
12461 goto done;
12462 }
12463 ok( r == ERROR_SUCCESS, "got %u\n", r );
12464 r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
12465 sizeof("c:\\doesnotexist"));
12466 ok( r == ERROR_SUCCESS, "got %u\n", r );
12467
12468 index = 0;
12469 guid[0] = 0;
12470 context = 0xdeadbeef;
12471 sid[0] = 0;
12472 len = sizeof(sid);
12473 found1 = found2 = 0;
12474 while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
12475 {
12476 if (!strcmp( comp1, guid ))
12477 {
12478 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
12479 ok( !sid[0], "got \"%s\"\n", sid );
12480 ok( !len, "unexpected length %u\n", len );
12481 found1 = 1;
12482 }
12483 if (!strcmp( comp2, guid ))
12484 {
12485 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
12486 ok( sid[0], "empty sid\n" );
12487 ok( len == strlen(sid), "unexpected length %u\n", len );
12488 found2 = 1;
12489 }
12490 index++;
12491 guid[0] = 0;
12492 context = 0xdeadbeef;
12493 sid[0] = 0;
12494 len = sizeof(sid);
12495 }
12496 ok( found1, "comp1 not found\n" );
12497 ok( found2, "comp2 not found\n" );
12498
12499 r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
12500 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12501
12502 r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
12503 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12504
12505 done:
12506 RegDeleteValueA( key2, comp_squashed2 );
12507 delete_key( key1, "", access );
12508 delete_key( key2, "", access );
12509 RegCloseKey( key1 );
12510 RegCloseKey( key2 );
12511 LocalFree( usersid );
12512 }
12513
12514 static void test_MsiConfigureProductEx(void)
12515 {
12516 UINT r;
12517 LONG res;
12518 DWORD type, size;
12519 HKEY props, source;
12520 CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
12521 REGSAM access = KEY_ALL_ACCESS;
12522
12523 if (is_process_limited())
12524 {
12525 skip("process is limited\n");
12526 return;
12527 }
12528
12529 CreateDirectoryA("msitest", NULL);
12530 create_file("msitest\\hydrogen", "hydrogen", 500);
12531 create_file("msitest\\helium", "helium", 500);
12532 create_file("msitest\\lithium", "lithium", 500);
12533
12534 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
12535
12536 if (is_wow64)
12537 access |= KEY_WOW64_64KEY;
12538
12539 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
12540
12541 /* NULL szProduct */
12542 r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
12543 INSTALLSTATE_DEFAULT, "PROPVAR=42");
12544 ok(r == ERROR_INVALID_PARAMETER,
12545 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12546
12547 /* empty szProduct */
12548 r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
12549 INSTALLSTATE_DEFAULT, "PROPVAR=42");
12550 ok(r == ERROR_INVALID_PARAMETER,
12551 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12552
12553 /* garbage szProduct */
12554 r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
12555 INSTALLSTATE_DEFAULT, "PROPVAR=42");
12556 ok(r == ERROR_INVALID_PARAMETER,
12557 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12558
12559 /* guid without brackets */
12560 r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
12561 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
12562 "PROPVAR=42");
12563 ok(r == ERROR_INVALID_PARAMETER,
12564 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12565
12566 /* guid with brackets */
12567 r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
12568 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
12569 "PROPVAR=42");
12570 ok(r == ERROR_UNKNOWN_PRODUCT,
12571 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12572
12573 /* same length as guid, but random */
12574 r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
12575 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
12576 "PROPVAR=42");
12577 ok(r == ERROR_UNKNOWN_PRODUCT,
12578 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12579
12580 /* product not installed yet */
12581 r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
12582 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
12583 "PROPVAR=42");
12584 ok(r == ERROR_UNKNOWN_PRODUCT,
12585 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12586
12587 /* install the product, per-user unmanaged */
12588 r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
12589 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
12590 {
12591 skip("Not enough rights to perform tests\n");
12592 goto error;
12593 }
12594 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12595 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12596 ok(pf_exists("msitest\\helium"), "File not installed\n");
12597 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12598 ok(pf_exists("msitest"), "File not installed\n");
12599
12600 /* product is installed per-user managed, remove it */
12601 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12602 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
12603 "PROPVAR=42");
12604 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12605 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12606 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12607 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12608 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12609
12610 /* product has been removed */
12611 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12612 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
12613 "PROPVAR=42");
12614 ok(r == ERROR_UNKNOWN_PRODUCT,
12615 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
12616
12617 /* install the product, machine */
12618 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
12619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12620 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12621 ok(pf_exists("msitest\\helium"), "File not installed\n");
12622 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12623 ok(pf_exists("msitest"), "File not installed\n");
12624
12625 /* product is installed machine, remove it */
12626 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12627 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
12628 "PROPVAR=42");
12629 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12630 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12631 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12632 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12633 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12634
12635 /* product has been removed */
12636 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12637 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
12638 "PROPVAR=42");
12639 ok(r == ERROR_UNKNOWN_PRODUCT,
12640 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
12641
12642 /* install the product, machine */
12643 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
12644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12645 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12646 ok(pf_exists("msitest\\helium"), "File not installed\n");
12647 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12648 ok(pf_exists("msitest"), "File not installed\n");
12649
12650 DeleteFileA(msifile);
12651
12652 /* msifile is removed */
12653 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12654 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
12655 "PROPVAR=42");
12656 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12657 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12658 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12659 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12660 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12661
12662 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
12663
12664 /* install the product, machine */
12665 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
12666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12667 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12668 ok(pf_exists("msitest\\helium"), "File not installed\n");
12669 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12670 ok(pf_exists("msitest"), "File not installed\n");
12671
12672 DeleteFileA(msifile);
12673
12674 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
12675 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
12676 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
12677
12678 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
12679 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12680
12681 type = REG_SZ;
12682 size = MAX_PATH;
12683 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
12684 (LPBYTE)localpackage, &size);
12685 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12686
12687 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
12688 (const BYTE *)"C:\\idontexist.msi", 18);
12689 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12690
12691 /* LocalPackage is used to find the cached msi package */
12692 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12693 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
12694 "PROPVAR=42");
12695 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
12696 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
12697 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12698 ok(pf_exists("msitest\\helium"), "File not installed\n");
12699 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12700 ok(pf_exists("msitest"), "File not installed\n");
12701
12702 RegCloseKey(props);
12703 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
12704
12705 /* LastUsedSource can be used as a last resort */
12706 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12707 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
12708 "PROPVAR=42");
12709 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12710 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12711 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12712 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12713 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12714 DeleteFileA( localpackage );
12715
12716 /* install the product, machine */
12717 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
12718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12719 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12720 ok(pf_exists("msitest\\helium"), "File not installed\n");
12721 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12722 ok(pf_exists("msitest"), "File not installed\n");
12723
12724 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
12725 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
12726 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
12727
12728 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
12729 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12730
12731 type = REG_SZ;
12732 size = MAX_PATH;
12733 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
12734 (LPBYTE)localpackage, &size);
12735 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12736
12737 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
12738 (const BYTE *)"C:\\idontexist.msi", 18);
12739 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12740
12741 lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
12742 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\SourceList");
12743
12744 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source);
12745 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12746
12747 type = REG_SZ;
12748 size = MAX_PATH;
12749 res = RegQueryValueExA(source, "PackageName", NULL, &type,
12750 (LPBYTE)packagename, &size);
12751 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12752
12753 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
12754 (const BYTE *)"idontexist.msi", 15);
12755 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12756
12757 /* SourceList is altered */
12758 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12759 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
12760 "PROPVAR=42");
12761 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
12762 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
12763 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
12764 ok(pf_exists("msitest\\helium"), "File not installed\n");
12765 ok(pf_exists("msitest\\lithium"), "File not installed\n");
12766 ok(pf_exists("msitest"), "File not installed\n");
12767
12768 /* restore PackageName */
12769 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
12770 (const BYTE *)packagename, lstrlenA(packagename) + 1);
12771 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12772
12773 /* restore LocalPackage */
12774 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
12775 (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
12776 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12777
12778 /* finally remove the product */
12779 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
12780 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
12781 "PROPVAR=42");
12782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12783 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
12784 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
12785 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
12786 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
12787
12788 RegCloseKey(source);
12789 RegCloseKey(props);
12790
12791 error:
12792 DeleteFileA("msitest\\hydrogen");
12793 DeleteFileA("msitest\\helium");
12794 DeleteFileA("msitest\\lithium");
12795 RemoveDirectoryA("msitest");
12796 DeleteFileA(msifile);
12797 }
12798
12799 static void test_MsiSetFeatureAttributes(void)
12800 {
12801 UINT r;
12802 DWORD attrs;
12803 char path[MAX_PATH];
12804 MSIHANDLE package;
12805
12806 if (is_process_limited())
12807 {
12808 skip("process is limited\n");
12809 return;
12810 }
12811 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
12812
12813 strcpy( path, CURR_DIR );
12814 strcat( path, "\\" );
12815 strcat( path, msifile );
12816
12817 r = MsiOpenPackage( path, &package );
12818 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
12819 {
12820 skip("Not enough rights to perform tests\n");
12821 DeleteFileA( msifile );
12822 return;
12823 }
12824 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12825
12826 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
12827 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r);
12828
12829 r = MsiDoAction( package, "CostInitialize" );
12830 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12831
12832 r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
12833 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
12834
12835 r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
12836 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
12837
12838 r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
12839 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
12840
12841 r = MsiSetFeatureAttributesA( package, "One", 0 );
12842 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12843
12844 attrs = 0xdeadbeef;
12845 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
12846 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12847 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
12848 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
12849
12850 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
12851 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12852
12853 attrs = 0;
12854 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
12855 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12856 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
12857 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
12858
12859 r = MsiDoAction( package, "FileCost" );
12860 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12861
12862 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE );
12863 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12864
12865 attrs = 0;
12866 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
12867 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12868 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE,
12869 "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs);
12870
12871 r = MsiDoAction( package, "CostFinalize" );
12872 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12873
12874 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
12875 ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r);
12876
12877 MsiCloseHandle( package );
12878 DeleteFileA( msifile );
12879 }
12880
12881 static void test_MsiGetFeatureInfo(void)
12882 {
12883 UINT r;
12884 MSIHANDLE package;
12885 char title[32], help[32], path[MAX_PATH];
12886 DWORD attrs, title_len, help_len;
12887
12888 if (is_process_limited())
12889 {
12890 skip("process is limited\n");
12891 return;
12892 }
12893 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
12894
12895 strcpy( path, CURR_DIR );
12896 strcat( path, "\\" );
12897 strcat( path, msifile );
12898
12899 r = MsiOpenPackage( path, &package );
12900 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
12901 {
12902 skip("Not enough rights to perform tests\n");
12903 DeleteFileA( msifile );
12904 return;
12905 }
12906 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12907
12908 r = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL );
12909 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12910
12911 r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
12912 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12913
12914 r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
12915 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
12916
12917 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
12918 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12919
12920 r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
12921 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
12922
12923 title_len = help_len = 0;
12924 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
12925 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12926 ok(title_len == 3, "expected 3, got %u\n", title_len);
12927 ok(help_len == 3, "expected 3, got %u\n", help_len);
12928
12929 title[0] = help[0] = 0;
12930 title_len = help_len = 0;
12931 r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
12932 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
12933 ok(title_len == 3, "expected 3, got %u\n", title_len);
12934 ok(help_len == 3, "expected 3, got %u\n", help_len);
12935
12936 attrs = 0;
12937 title[0] = help[0] = 0;
12938 title_len = sizeof(title);
12939 help_len = sizeof(help);
12940 r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
12941 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12942 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
12943 ok(title_len == 3, "expected 3, got %u\n", title_len);
12944 ok(help_len == 3, "expected 3, got %u\n", help_len);
12945 ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
12946 ok(!strcmp(help, "One"), "expected \"One\", got \"%s\"\n", help);
12947
12948 attrs = 0;
12949 title[0] = help[0] = 0;
12950 title_len = sizeof(title);
12951 help_len = sizeof(help);
12952 r = MsiGetFeatureInfoA( package, "Two", &attrs, title, &title_len, help, &help_len );
12953 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
12954 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
12955 ok(!title_len, "expected 0, got %u\n", title_len);
12956 ok(!help_len, "expected 0, got %u\n", help_len);
12957 ok(!title[0], "expected \"\", got \"%s\"\n", title);
12958 ok(!help[0], "expected \"\", got \"%s\"\n", help);
12959
12960 MsiCloseHandle( package );
12961 DeleteFileA( msifile );
12962 }
12963
12964 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
12965 {
12966 return IDOK;
12967 }
12968
12969 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
12970 {
12971 return IDOK;
12972 }
12973
12974 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
12975 {
12976 return IDOK;
12977 }
12978
12979 static void test_MsiSetExternalUI(void)
12980 {
12981 INSTALLUI_HANDLERA ret_a;
12982 INSTALLUI_HANDLERW ret_w;
12983 INSTALLUI_HANDLER_RECORD prev;
12984 UINT error;
12985
12986 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
12987 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
12988
12989 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
12990 ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
12991
12992 /* Not present before Installer 3.1 */
12993 if (!pMsiSetExternalUIRecord) {
12994 win_skip("MsiSetExternalUIRecord is not available\n");
12995 return;
12996 }
12997
12998 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
12999 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13000 ok(prev == NULL, "expected NULL, got %p\n", prev);
13001
13002 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13003 error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
13004 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13005 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
13006
13007 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
13008 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13009
13010 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
13011 ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
13012
13013 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
13014 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13015
13016 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
13017 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13018
13019 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13020 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
13021 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13022 ok(prev == NULL, "expected NULL, got %p\n", prev);
13023
13024 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
13025 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13026
13027 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
13028 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13029
13030 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13031 error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
13032 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13033 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
13034
13035 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
13036 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13037
13038 error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
13039 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13040 }
13041
13042 START_TEST(msi)
13043 {
13044 DWORD len;
13045 char temp_path[MAX_PATH], prev_path[MAX_PATH];
13046
13047 init_functionpointers();
13048
13049 if (pIsWow64Process)
13050 pIsWow64Process(GetCurrentProcess(), &is_wow64);
13051
13052 GetCurrentDirectoryA(MAX_PATH, prev_path);
13053 GetTempPath(MAX_PATH, temp_path);
13054 SetCurrentDirectoryA(temp_path);
13055
13056 lstrcpyA(CURR_DIR, temp_path);
13057 len = lstrlenA(CURR_DIR);
13058
13059 if(len && (CURR_DIR[len - 1] == '\\'))
13060 CURR_DIR[len - 1] = 0;
13061
13062 ok(get_system_dirs(), "failed to retrieve system dirs\n");
13063
13064 test_usefeature();
13065 test_null();
13066 test_getcomponentpath();
13067 test_MsiGetFileHash();
13068
13069 if (!pConvertSidToStringSidA)
13070 win_skip("ConvertSidToStringSidA not implemented\n");
13071 else
13072 {
13073 /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
13074 test_MsiQueryProductState();
13075 test_MsiQueryFeatureState();
13076 test_MsiQueryComponentState();
13077 test_MsiGetComponentPath();
13078 test_MsiGetProductCode();
13079 test_MsiEnumClients();
13080 test_MsiGetProductInfo();
13081 test_MsiGetProductInfoEx();
13082 test_MsiGetUserInfo();
13083 test_MsiOpenProduct();
13084 test_MsiEnumPatchesEx();
13085 test_MsiEnumPatches();
13086 test_MsiGetPatchInfoEx();
13087 test_MsiGetPatchInfo();
13088 test_MsiEnumProducts();
13089 test_MsiEnumProductsEx();
13090 test_MsiEnumComponents();
13091 test_MsiEnumComponentsEx();
13092 }
13093 test_MsiGetFileVersion();
13094 test_MsiGetFileSignatureInformation();
13095 test_MsiConfigureProductEx();
13096 test_MsiSetFeatureAttributes();
13097 test_MsiGetFeatureInfo();
13098 test_MsiSetExternalUI();
13099
13100 SetCurrentDirectoryA(prev_path);
13101 }