Partial merge of the condrv_restructure branch, including:
[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 #define COBJMACROS
23
24 #include <stdio.h>
25 #include <windows.h>
26 #include <msi.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <sddl.h>
30 #include <fci.h>
31
32 #include "wine/test.h"
33
34 static BOOL is_wow64;
35 static const char msifile[] = "winetest.msi";
36 static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','.','m','s','i',0};
37 static char CURR_DIR[MAX_PATH];
38 static char PROG_FILES_DIR[MAX_PATH];
39 static char PROG_FILES_DIR_NATIVE[MAX_PATH];
40 static char COMMON_FILES_DIR[MAX_PATH];
41 static char WINDOWS_DIR[MAX_PATH];
42
43 static BOOL (WINAPI *pCheckTokenMembership)(HANDLE,PSID,PBOOL);
44 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
45 static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
46 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
47 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
48
49 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
50 (LPCSTR, LPCSTR, LPSTR, DWORD*);
51 static UINT (WINAPI *pMsiGetFileHashA)
52 (LPCSTR, DWORD, PMSIFILEHASHINFO);
53 static UINT (WINAPI *pMsiGetProductInfoExA)
54 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
55 static UINT (WINAPI *pMsiOpenPackageExA)
56 (LPCSTR, DWORD, MSIHANDLE*);
57 static UINT (WINAPI *pMsiOpenPackageExW)
58 (LPCWSTR, DWORD, MSIHANDLE*);
59 static UINT (WINAPI *pMsiEnumPatchesExA)
60 (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
61 MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
62 static UINT (WINAPI *pMsiQueryComponentStateA)
63 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
64 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
65 (LPCSTR, LPCSTR ,DWORD, DWORD);
66 static UINT (WINAPI *pMsiGetPatchInfoExA)
67 (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
68 static UINT (WINAPI *pMsiEnumProductsExA)
69 (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
70 static UINT (WINAPI *pMsiEnumComponentsExA)
71 (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
72 static UINT (WINAPI *pMsiSetExternalUIRecord)
73 (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
74 static UINT (WINAPI *pMsiSourceListGetInfoA)
75 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
76
77 static void init_functionpointers(void)
78 {
79 HMODULE hmsi = GetModuleHandleA("msi.dll");
80 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
81 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
82
83 #define GET_PROC(dll, func) \
84 p ## func = (void *)GetProcAddress(dll, #func); \
85 if(!p ## func) \
86 trace("GetProcAddress(%s) failed\n", #func);
87
88 GET_PROC(hmsi, MsiGetComponentPathA)
89 GET_PROC(hmsi, MsiGetFileHashA)
90 GET_PROC(hmsi, MsiGetProductInfoExA)
91 GET_PROC(hmsi, MsiOpenPackageExA)
92 GET_PROC(hmsi, MsiOpenPackageExW)
93 GET_PROC(hmsi, MsiEnumPatchesExA)
94 GET_PROC(hmsi, MsiQueryComponentStateA)
95 GET_PROC(hmsi, MsiSetExternalUIRecord)
96 GET_PROC(hmsi, MsiUseFeatureExA)
97 GET_PROC(hmsi, MsiGetPatchInfoExA)
98 GET_PROC(hmsi, MsiEnumProductsExA)
99 GET_PROC(hmsi, MsiEnumComponentsExA)
100 GET_PROC(hmsi, MsiSourceListGetInfoA)
101
102 GET_PROC(hadvapi32, CheckTokenMembership);
103 GET_PROC(hadvapi32, ConvertSidToStringSidA)
104 GET_PROC(hadvapi32, OpenProcessToken);
105 GET_PROC(hadvapi32, RegDeleteKeyExA)
106 GET_PROC(hkernel32, IsWow64Process)
107
108 #undef GET_PROC
109 }
110
111 static BOOL get_system_dirs(void)
112 {
113 HKEY hkey;
114 DWORD type, size;
115
116 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
117 return FALSE;
118
119 size = MAX_PATH;
120 if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
121 RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
122 {
123 RegCloseKey(hkey);
124 return FALSE;
125 }
126 size = MAX_PATH;
127 if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
128 RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
129 {
130 RegCloseKey(hkey);
131 return FALSE;
132 }
133 size = MAX_PATH;
134 if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR_NATIVE, &size))
135 {
136 RegCloseKey(hkey);
137 return FALSE;
138 }
139 RegCloseKey(hkey);
140 if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH)) return FALSE;
141 return TRUE;
142 }
143
144 static BOOL file_exists(const char *file)
145 {
146 return GetFileAttributesA(file) != INVALID_FILE_ATTRIBUTES;
147 }
148
149 static BOOL pf_exists(const char *file)
150 {
151 char path[MAX_PATH];
152
153 lstrcpyA(path, PROG_FILES_DIR);
154 lstrcatA(path, "\\");
155 lstrcatA(path, file);
156 return file_exists(path);
157 }
158
159 static BOOL delete_pf(const char *rel_path, BOOL is_file)
160 {
161 char path[MAX_PATH];
162
163 lstrcpyA(path, PROG_FILES_DIR);
164 lstrcatA(path, "\\");
165 lstrcatA(path, rel_path);
166
167 if (is_file)
168 return DeleteFileA(path);
169 else
170 return RemoveDirectoryA(path);
171 }
172
173 static BOOL is_process_limited(void)
174 {
175 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
176 PSID Group;
177 BOOL IsInGroup;
178 HANDLE token;
179
180 if (!pCheckTokenMembership || !pOpenProcessToken) return FALSE;
181
182 if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
183 DOMAIN_ALIAS_RID_ADMINS,
184 0, 0, 0, 0, 0, 0, &Group) ||
185 !pCheckTokenMembership(NULL, Group, &IsInGroup))
186 {
187 trace("Could not check if the current user is an administrator\n");
188 return FALSE;
189 }
190 if (!IsInGroup)
191 {
192 /* Only administrators have enough privileges for these tests */
193 return TRUE;
194 }
195
196 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
197 {
198 BOOL ret;
199 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
200 DWORD size;
201
202 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
203 CloseHandle(token);
204 return (ret && type == TokenElevationTypeLimited);
205 }
206 return FALSE;
207 }
208
209 /* cabinet definitions */
210
211 /* make the max size large so there is only one cab file */
212 #define MEDIA_SIZE 0x7FFFFFFF
213 #define FOLDER_THRESHOLD 900000
214
215 /* the FCI callbacks */
216
217 static void * CDECL mem_alloc(ULONG cb)
218 {
219 return HeapAlloc(GetProcessHeap(), 0, cb);
220 }
221
222 static void CDECL mem_free(void *memory)
223 {
224 HeapFree(GetProcessHeap(), 0, memory);
225 }
226
227 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
228 {
229 sprintf(pccab->szCab, pv, pccab->iCab);
230 return TRUE;
231 }
232
233 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
234 {
235 return 0;
236 }
237
238 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
239 BOOL fContinuation, void *pv)
240 {
241 return 0;
242 }
243
244 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
245 {
246 HANDLE handle;
247 DWORD dwAccess = 0;
248 DWORD dwShareMode = 0;
249 DWORD dwCreateDisposition = OPEN_EXISTING;
250
251 dwAccess = GENERIC_READ | GENERIC_WRITE;
252 /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
253 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
254
255 if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
256 dwCreateDisposition = OPEN_EXISTING;
257 else
258 dwCreateDisposition = CREATE_NEW;
259
260 handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
261 dwCreateDisposition, 0, NULL);
262
263 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
264
265 return (INT_PTR)handle;
266 }
267
268 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
269 {
270 HANDLE handle = (HANDLE)hf;
271 DWORD dwRead;
272 BOOL res;
273
274 res = ReadFile(handle, memory, cb, &dwRead, NULL);
275 ok(res, "Failed to ReadFile\n");
276
277 return dwRead;
278 }
279
280 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
281 {
282 HANDLE handle = (HANDLE)hf;
283 DWORD dwWritten;
284 BOOL res;
285
286 res = WriteFile(handle, memory, cb, &dwWritten, NULL);
287 ok(res, "Failed to WriteFile\n");
288
289 return dwWritten;
290 }
291
292 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
293 {
294 HANDLE handle = (HANDLE)hf;
295 ok(CloseHandle(handle), "Failed to CloseHandle\n");
296
297 return 0;
298 }
299
300 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
301 {
302 HANDLE handle = (HANDLE)hf;
303 DWORD ret;
304
305 ret = SetFilePointer(handle, dist, NULL, seektype);
306 ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
307
308 return ret;
309 }
310
311 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
312 {
313 BOOL ret = DeleteFileA(pszFile);
314 ok(ret, "Failed to DeleteFile %s\n", pszFile);
315
316 return 0;
317 }
318
319 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
320 {
321 LPSTR tempname;
322
323 tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
324 GetTempFileNameA(".", "xx", 0, tempname);
325
326 if (tempname && (strlen(tempname) < (unsigned)cbTempName))
327 {
328 lstrcpyA(pszTempName, tempname);
329 HeapFree(GetProcessHeap(), 0, tempname);
330 return TRUE;
331 }
332
333 HeapFree(GetProcessHeap(), 0, tempname);
334
335 return FALSE;
336 }
337
338 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
339 USHORT *pattribs, int *err, void *pv)
340 {
341 BY_HANDLE_FILE_INFORMATION finfo;
342 FILETIME filetime;
343 HANDLE handle;
344 DWORD attrs;
345 BOOL res;
346
347 handle = CreateFileA(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
348 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
349 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
350
351 res = GetFileInformationByHandle(handle, &finfo);
352 ok(res, "Expected GetFileInformationByHandle to succeed\n");
353
354 FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
355 FileTimeToDosDateTime(&filetime, pdate, ptime);
356
357 attrs = GetFileAttributesA(pszName);
358 ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
359
360 return (INT_PTR)handle;
361 }
362
363 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
364 {
365 char path[MAX_PATH];
366 char filename[MAX_PATH];
367
368 lstrcpyA(path, CURR_DIR);
369 lstrcatA(path, "\\");
370 lstrcatA(path, file);
371
372 lstrcpyA(filename, file);
373
374 return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
375 progress, get_open_info, compress);
376 }
377
378 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
379 {
380 ZeroMemory(pCabParams, sizeof(CCAB));
381
382 pCabParams->cb = max_size;
383 pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
384 pCabParams->setID = 0xbeef;
385 pCabParams->iCab = 1;
386 lstrcpyA(pCabParams->szCabPath, CURR_DIR);
387 lstrcatA(pCabParams->szCabPath, "\\");
388 lstrcpyA(pCabParams->szCab, name);
389 }
390
391 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
392 {
393 CCAB cabParams;
394 LPCSTR ptr;
395 HFCI hfci;
396 ERF erf;
397 BOOL res;
398
399 set_cab_parameters(&cabParams, name, max_size);
400
401 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
402 fci_read, fci_write, fci_close, fci_seek, fci_delete,
403 get_temp_file, &cabParams, NULL);
404
405 ok(hfci != NULL, "Failed to create an FCI context\n");
406
407 ptr = files;
408 while (*ptr)
409 {
410 res = add_file(hfci, ptr, tcompTYPE_MSZIP);
411 ok(res, "Failed to add file: %s\n", ptr);
412 ptr += lstrlenA(ptr) + 1;
413 }
414
415 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
416 ok(res, "Failed to flush the cabinet\n");
417
418 res = FCIDestroy(hfci);
419 ok(res, "Failed to destroy the cabinet\n");
420 }
421
422 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
423 {
424 WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
425 IStorage *stg;
426 IStream *stm;
427 HRESULT hr;
428 HANDLE handle;
429
430 MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
431 hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
432 if (FAILED(hr))
433 return FALSE;
434
435 MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
436 hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
437 if (FAILED(hr))
438 {
439 IStorage_Release(stg);
440 return FALSE;
441 }
442
443 handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
444 if (handle != INVALID_HANDLE_VALUE)
445 {
446 DWORD count;
447 char buffer[1024];
448 if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
449 IStream_Write(stm, buffer, count, &count);
450 CloseHandle(handle);
451 }
452
453 IStream_Release(stm);
454 IStorage_Release(stg);
455
456 return TRUE;
457 }
458
459 static void delete_cab_files(void)
460 {
461 SHFILEOPSTRUCTA shfl;
462 CHAR path[MAX_PATH+10];
463
464 lstrcpyA(path, CURR_DIR);
465 lstrcatA(path, "\\*.cab");
466 path[strlen(path) + 1] = '\0';
467
468 shfl.hwnd = NULL;
469 shfl.wFunc = FO_DELETE;
470 shfl.pFrom = path;
471 shfl.pTo = NULL;
472 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
473
474 SHFileOperationA(&shfl);
475 }
476
477 /* msi database data */
478
479 static const char directory_dat[] =
480 "Directory\tDirectory_Parent\tDefaultDir\n"
481 "s72\tS72\tl255\n"
482 "Directory\tDirectory\n"
483 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
484 "ProgramFilesFolder\tTARGETDIR\t.\n"
485 "TARGETDIR\t\tSourceDir";
486
487 static const char component_dat[] =
488 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
489 "s72\tS38\ts72\ti2\tS255\tS72\n"
490 "Component\tComponent\n"
491 "One\t{8F5BAEEF-DD92-40AC-9397-BE3CF9F97C81}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n";
492
493 static const char feature_dat[] =
494 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
495 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
496 "Feature\tFeature\n"
497 "One\t\tOne\tOne\t1\t3\tMSITESTDIR\t0\n"
498 "Two\t\t\t\t2\t1\tTARGETDIR\t0\n";
499
500 static const char feature_comp_dat[] =
501 "Feature_\tComponent_\n"
502 "s38\ts72\n"
503 "FeatureComponents\tFeature_\tComponent_\n"
504 "One\tOne\n";
505
506 static const char file_dat[] =
507 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
508 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
509 "File\tFile\n"
510 "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n";
511
512 static const char install_exec_seq_dat[] =
513 "Action\tCondition\tSequence\n"
514 "s72\tS255\tI2\n"
515 "InstallExecuteSequence\tAction\n"
516 "ValidateProductID\t\t700\n"
517 "CostInitialize\t\t800\n"
518 "FileCost\t\t900\n"
519 "CostFinalize\t\t1000\n"
520 "InstallValidate\t\t1400\n"
521 "InstallInitialize\t\t1500\n"
522 "ProcessComponents\t\t1600\n"
523 "UnpublishFeatures\t\t1800\n"
524 "RemoveFiles\t\t3500\n"
525 "InstallFiles\t\t4000\n"
526 "RegisterProduct\t\t6100\n"
527 "PublishFeatures\t\t6300\n"
528 "PublishProduct\t\t6400\n"
529 "InstallFinalize\t\t6600";
530
531 static const char media_dat[] =
532 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
533 "i2\ti4\tL64\tS255\tS32\tS72\n"
534 "Media\tDiskId\n"
535 "1\t1\t\t\tDISK1\t\n";
536
537 static const char property_dat[] =
538 "Property\tValue\n"
539 "s72\tl0\n"
540 "Property\tProperty\n"
541 "INSTALLLEVEL\t3\n"
542 "Manufacturer\tWine\n"
543 "ProductCode\t{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}\n"
544 "ProductName\tMSITEST\n"
545 "ProductVersion\t1.1.1\n"
546 "UpgradeCode\t{9574448F-9B86-4E07-B6F6-8D199DA12127}\n"
547 "MSIFASTINSTALL\t1\n";
548
549 static const char mcp_component_dat[] =
550 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
551 "s72\tS38\ts72\ti2\tS255\tS72\n"
552 "Component\tComponent\n"
553 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
554 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
555 "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
556
557 static const char mcp_feature_dat[] =
558 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
559 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
560 "Feature\tFeature\n"
561 "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
562 "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
563 "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
564
565 static const char mcp_feature_comp_dat[] =
566 "Feature_\tComponent_\n"
567 "s38\ts72\n"
568 "FeatureComponents\tFeature_\tComponent_\n"
569 "hydroxyl\thydrogen\n"
570 "heliox\thelium\n"
571 "lithia\tlithium";
572
573 static const char mcp_file_dat[] =
574 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
575 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
576 "File\tFile\n"
577 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
578 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
579 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
580
581 static const char lus_component_dat[] =
582 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
583 "s72\tS38\ts72\ti2\tS255\tS72\n"
584 "Component\tComponent\n"
585 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
586
587 static const char lus_feature_dat[] =
588 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
589 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
590 "Feature\tFeature\n"
591 "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
592 "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
593
594 static const char lus_file_dat[] =
595 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
596 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
597 "File\tFile\n"
598 "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
599
600 static const char lus_feature_comp_dat[] =
601 "Feature_\tComponent_\n"
602 "s38\ts72\n"
603 "FeatureComponents\tFeature_\tComponent_\n"
604 "feature\tmaximus\n"
605 "montecristo\tmaximus";
606
607 static const char lus_install_exec_seq_dat[] =
608 "Action\tCondition\tSequence\n"
609 "s72\tS255\tI2\n"
610 "InstallExecuteSequence\tAction\n"
611 "ValidateProductID\t\t700\n"
612 "CostInitialize\t\t800\n"
613 "FileCost\t\t900\n"
614 "CostFinalize\t\t1000\n"
615 "InstallValidate\t\t1400\n"
616 "InstallInitialize\t\t1500\n"
617 "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
618 "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
619 "RemoveFiles\t\t3500\n"
620 "InstallFiles\t\t4000\n"
621 "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
622 "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
623 "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
624 "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
625 "InstallFinalize\t\t6600";
626
627 static const char lus0_media_dat[] =
628 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
629 "i2\ti4\tL64\tS255\tS32\tS72\n"
630 "Media\tDiskId\n"
631 "1\t1\t\t\tDISK1\t\n";
632
633 static const char lus1_media_dat[] =
634 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
635 "i2\ti4\tL64\tS255\tS32\tS72\n"
636 "Media\tDiskId\n"
637 "1\t1\t\ttest1.cab\tDISK1\t\n";
638
639 static const char lus2_media_dat[] =
640 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
641 "i2\ti4\tL64\tS255\tS32\tS72\n"
642 "Media\tDiskId\n"
643 "1\t1\t\t#test1.cab\tDISK1\t\n";
644
645 static const char spf_custom_action_dat[] =
646 "Action\tType\tSource\tTarget\tISComments\n"
647 "s72\ti2\tS64\tS0\tS255\n"
648 "CustomAction\tAction\n"
649 "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
650
651 static const char spf_install_exec_seq_dat[] =
652 "Action\tCondition\tSequence\n"
653 "s72\tS255\tI2\n"
654 "InstallExecuteSequence\tAction\n"
655 "CostFinalize\t\t1000\n"
656 "CostInitialize\t\t800\n"
657 "FileCost\t\t900\n"
658 "SetFolderProp\t\t950\n"
659 "InstallFiles\t\t4000\n"
660 "InstallServices\t\t5000\n"
661 "InstallFinalize\t\t6600\n"
662 "InstallInitialize\t\t1500\n"
663 "InstallValidate\t\t1400\n"
664 "LaunchConditions\t\t100";
665
666 static const char spf_install_ui_seq_dat[] =
667 "Action\tCondition\tSequence\n"
668 "s72\tS255\tI2\n"
669 "InstallUISequence\tAction\n"
670 "CostInitialize\t\t800\n"
671 "FileCost\t\t900\n"
672 "CostFinalize\t\t1000\n"
673 "ExecuteAction\t\t1100\n";
674
675 static const char sd_file_dat[] =
676 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
677 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
678 "File\tFile\n"
679 "sourcedir.txt\tsourcedir\tsourcedir.txt\t1000\t\t\t8192\t1\n";
680
681 static const char sd_feature_dat[] =
682 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
683 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
684 "Feature\tFeature\n"
685 "sourcedir\t\t\tsourcedir feature\t1\t2\tMSITESTDIR\t0\n";
686
687 static const char sd_feature_comp_dat[] =
688 "Feature_\tComponent_\n"
689 "s38\ts72\n"
690 "FeatureComponents\tFeature_\tComponent_\n"
691 "sourcedir\tsourcedir\n";
692
693 static const char sd_component_dat[] =
694 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
695 "s72\tS38\ts72\ti2\tS255\tS72\n"
696 "Component\tComponent\n"
697 "sourcedir\t{DD422F92-3ED8-49B5-A0B7-F266F98357DF}\tMSITESTDIR\t0\t\tsourcedir.txt\n";
698
699 static const char sd_install_ui_seq_dat[] =
700 "Action\tCondition\tSequence\n"
701 "s72\tS255\tI2\n"
702 "InstallUISequence\tAction\n"
703 "TestSourceDirProp1\tnot SourceDir and not SOURCEDIR and not Installed\t99\n"
704 "AppSearch\t\t100\n"
705 "TestSourceDirProp2\tnot SourceDir and not SOURCEDIR and not Installed\t101\n"
706 "LaunchConditions\tnot Installed \t110\n"
707 "TestSourceDirProp3\tnot SourceDir and not SOURCEDIR and not Installed\t111\n"
708 "FindRelatedProducts\t\t120\n"
709 "TestSourceDirProp4\tnot SourceDir and not SOURCEDIR and not Installed\t121\n"
710 "CCPSearch\t\t130\n"
711 "TestSourceDirProp5\tnot SourceDir and not SOURCEDIR and not Installed\t131\n"
712 "RMCCPSearch\t\t140\n"
713 "TestSourceDirProp6\tnot SourceDir and not SOURCEDIR and not Installed\t141\n"
714 "ValidateProductID\t\t150\n"
715 "TestSourceDirProp7\tnot SourceDir and not SOURCEDIR and not Installed\t151\n"
716 "CostInitialize\t\t800\n"
717 "TestSourceDirProp8\tnot SourceDir and not SOURCEDIR and not Installed\t801\n"
718 "FileCost\t\t900\n"
719 "TestSourceDirProp9\tnot SourceDir and not SOURCEDIR and not Installed\t901\n"
720 "IsolateComponents\t\t1000\n"
721 "TestSourceDirProp10\tnot SourceDir and not SOURCEDIR and not Installed\t1001\n"
722 "CostFinalize\t\t1100\n"
723 "TestSourceDirProp11\tnot SourceDir and not SOURCEDIR and not Installed\t1101\n"
724 "MigrateFeatureStates\t\t1200\n"
725 "TestSourceDirProp12\tnot SourceDir and not SOURCEDIR and not Installed\t1201\n"
726 "ExecuteAction\t\t1300\n"
727 "TestSourceDirProp13\tnot SourceDir and not SOURCEDIR and not Installed\t1301\n";
728
729 static const char sd_install_exec_seq_dat[] =
730 "Action\tCondition\tSequence\n"
731 "s72\tS255\tI2\n"
732 "InstallExecuteSequence\tAction\n"
733 "TestSourceDirProp14\tSourceDir and SOURCEDIR and not Installed\t99\n"
734 "LaunchConditions\t\t100\n"
735 "TestSourceDirProp15\tSourceDir and SOURCEDIR and not Installed\t101\n"
736 "ValidateProductID\t\t700\n"
737 "TestSourceDirProp16\tSourceDir and SOURCEDIR and not Installed\t701\n"
738 "CostInitialize\t\t800\n"
739 "TestSourceDirProp17\tSourceDir and SOURCEDIR and not Installed\t801\n"
740 "ResolveSource\tResolveSource and not Installed\t850\n"
741 "TestSourceDirProp18\tResolveSource and not SourceDir and not SOURCEDIR and not Installed\t851\n"
742 "TestSourceDirProp19\tnot ResolveSource and SourceDir and SOURCEDIR and not Installed\t852\n"
743 "FileCost\t\t900\n"
744 "TestSourceDirProp20\tSourceDir and SOURCEDIR and not Installed\t901\n"
745 "IsolateComponents\t\t1000\n"
746 "TestSourceDirProp21\tSourceDir and SOURCEDIR and not Installed\t1001\n"
747 "CostFinalize\t\t1100\n"
748 "TestSourceDirProp22\tSourceDir and SOURCEDIR and not Installed\t1101\n"
749 "MigrateFeatureStates\t\t1200\n"
750 "TestSourceDirProp23\tSourceDir and SOURCEDIR and not Installed\t1201\n"
751 "InstallValidate\t\t1400\n"
752 "TestSourceDirProp24\tSourceDir and SOURCEDIR and not Installed\t1401\n"
753 "InstallInitialize\t\t1500\n"
754 "TestSourceDirProp25\tSourceDir and SOURCEDIR and not Installed\t1501\n"
755 "ProcessComponents\t\t1600\n"
756 "TestSourceDirProp26\tnot SourceDir and not SOURCEDIR and not Installed\t1601\n"
757 "UnpublishFeatures\t\t1800\n"
758 "TestSourceDirProp27\tnot SourceDir and not SOURCEDIR and not Installed\t1801\n"
759 "RemoveFiles\t\t3500\n"
760 "TestSourceDirProp28\tnot SourceDir and not SOURCEDIR and not Installed\t3501\n"
761 "InstallFiles\t\t4000\n"
762 "TestSourceDirProp29\tnot SourceDir and not SOURCEDIR and not Installed\t4001\n"
763 "RegisterUser\t\t6000\n"
764 "TestSourceDirProp30\tnot SourceDir and not SOURCEDIR and not Installed\t6001\n"
765 "RegisterProduct\t\t6100\n"
766 "TestSourceDirProp31\tnot SourceDir and not SOURCEDIR and not Installed\t6101\n"
767 "PublishFeatures\t\t6300\n"
768 "TestSourceDirProp32\tnot SourceDir and not SOURCEDIR and not Installed\t6301\n"
769 "PublishProduct\t\t6400\n"
770 "TestSourceDirProp33\tnot SourceDir and not SOURCEDIR and not Installed\t6401\n"
771 "InstallExecute\t\t6500\n"
772 "TestSourceDirProp34\tnot SourceDir and not SOURCEDIR and not Installed\t6501\n"
773 "InstallFinalize\t\t6600\n"
774 "TestSourceDirProp35\tnot SourceDir and not SOURCEDIR and not Installed\t6601\n";
775
776 static const char sd_custom_action_dat[] =
777 "Action\tType\tSource\tTarget\tISComments\n"
778 "s72\ti2\tS64\tS0\tS255\n"
779 "CustomAction\tAction\n"
780 "TestSourceDirProp1\t19\t\tTest 1 failed\t\n"
781 "TestSourceDirProp2\t19\t\tTest 2 failed\t\n"
782 "TestSourceDirProp3\t19\t\tTest 3 failed\t\n"
783 "TestSourceDirProp4\t19\t\tTest 4 failed\t\n"
784 "TestSourceDirProp5\t19\t\tTest 5 failed\t\n"
785 "TestSourceDirProp6\t19\t\tTest 6 failed\t\n"
786 "TestSourceDirProp7\t19\t\tTest 7 failed\t\n"
787 "TestSourceDirProp8\t19\t\tTest 8 failed\t\n"
788 "TestSourceDirProp9\t19\t\tTest 9 failed\t\n"
789 "TestSourceDirProp10\t19\t\tTest 10 failed\t\n"
790 "TestSourceDirProp11\t19\t\tTest 11 failed\t\n"
791 "TestSourceDirProp12\t19\t\tTest 12 failed\t\n"
792 "TestSourceDirProp13\t19\t\tTest 13 failed\t\n"
793 "TestSourceDirProp14\t19\t\tTest 14 failed\t\n"
794 "TestSourceDirProp15\t19\t\tTest 15 failed\t\n"
795 "TestSourceDirProp16\t19\t\tTest 16 failed\t\n"
796 "TestSourceDirProp17\t19\t\tTest 17 failed\t\n"
797 "TestSourceDirProp18\t19\t\tTest 18 failed\t\n"
798 "TestSourceDirProp19\t19\t\tTest 19 failed\t\n"
799 "TestSourceDirProp20\t19\t\tTest 20 failed\t\n"
800 "TestSourceDirProp21\t19\t\tTest 21 failed\t\n"
801 "TestSourceDirProp22\t19\t\tTest 22 failed\t\n"
802 "TestSourceDirProp23\t19\t\tTest 23 failed\t\n"
803 "TestSourceDirProp24\t19\t\tTest 24 failed\t\n"
804 "TestSourceDirProp25\t19\t\tTest 25 failed\t\n"
805 "TestSourceDirProp26\t19\t\tTest 26 failed\t\n"
806 "TestSourceDirProp27\t19\t\tTest 27 failed\t\n"
807 "TestSourceDirProp28\t19\t\tTest 28 failed\t\n"
808 "TestSourceDirProp29\t19\t\tTest 29 failed\t\n"
809 "TestSourceDirProp30\t19\t\tTest 30 failed\t\n"
810 "TestSourceDirProp31\t19\t\tTest 31 failed\t\n"
811 "TestSourceDirProp32\t19\t\tTest 32 failed\t\n"
812 "TestSourceDirProp33\t19\t\tTest 33 failed\t\n"
813 "TestSourceDirProp34\t19\t\tTest 34 failed\t\n"
814 "TestSourceDirProp35\t19\t\tTest 35 failed\t\n";
815
816 static const char ci_install_exec_seq_dat[] =
817 "Action\tCondition\tSequence\n"
818 "s72\tS255\tI2\n"
819 "InstallExecuteSequence\tAction\n"
820 "CostFinalize\t\t1000\n"
821 "CostInitialize\t\t800\n"
822 "FileCost\t\t900\n"
823 "InstallFiles\t\t4000\n"
824 "InstallServices\t\t5000\n"
825 "InstallFinalize\t\t6600\n"
826 "InstallInitialize\t\t1500\n"
827 "RunInstall\t\t1600\n"
828 "InstallValidate\t\t1400\n"
829 "LaunchConditions\t\t100";
830
831 static const char ci_custom_action_dat[] =
832 "Action\tType\tSource\tTarget\tISComments\n"
833 "s72\ti2\tS64\tS0\tS255\n"
834 "CustomAction\tAction\n"
835 "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
836
837 static const char ci_component_dat[] =
838 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
839 "s72\tS38\ts72\ti2\tS255\tS72\n"
840 "Component\tComponent\n"
841 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
842
843 static const char ci2_component_dat[] =
844 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
845 "s72\tS38\ts72\ti2\tS255\tS72\n"
846 "Component\tComponent\n"
847 "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
848
849 static const char ci2_feature_comp_dat[] =
850 "Feature_\tComponent_\n"
851 "s38\ts72\n"
852 "FeatureComponents\tFeature_\tComponent_\n"
853 "feature\taugustus";
854
855 static const char ci2_file_dat[] =
856 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
857 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
858 "File\tFile\n"
859 "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
860
861 static const char cl_custom_action_dat[] =
862 "Action\tType\tSource\tTarget\tISComments\n"
863 "s72\ti2\tS64\tS0\tS255\n"
864 "CustomAction\tAction\n"
865 "TestCommandlineProp\t19\t\tTest1\t\n";
866
867 static const char cl_install_exec_seq_dat[] =
868 "Action\tCondition\tSequence\n"
869 "s72\tS255\tI2\n"
870 "InstallExecuteSequence\tAction\n"
871 "LaunchConditions\t\t100\n"
872 "ValidateProductID\t\t700\n"
873 "CostInitialize\t\t800\n"
874 "FileCost\t\t900\n"
875 "CostFinalize\t\t1000\n"
876 "TestCommandlineProp\tP=\"one\"\t1100\n"
877 "InstallInitialize\t\t1500\n"
878 "ProcessComponents\t\t1600\n"
879 "InstallValidate\t\t1400\n"
880 "InstallFinalize\t\t5000\n";
881
882 typedef struct _msi_table
883 {
884 const CHAR *filename;
885 const CHAR *data;
886 int size;
887 } msi_table;
888
889 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
890
891 static const msi_table tables[] =
892 {
893 ADD_TABLE(directory),
894 ADD_TABLE(component),
895 ADD_TABLE(feature),
896 ADD_TABLE(feature_comp),
897 ADD_TABLE(file),
898 ADD_TABLE(install_exec_seq),
899 ADD_TABLE(media),
900 ADD_TABLE(property),
901 };
902
903 static const msi_table mcp_tables[] =
904 {
905 ADD_TABLE(directory),
906 ADD_TABLE(mcp_component),
907 ADD_TABLE(mcp_feature),
908 ADD_TABLE(mcp_feature_comp),
909 ADD_TABLE(mcp_file),
910 ADD_TABLE(install_exec_seq),
911 ADD_TABLE(media),
912 ADD_TABLE(property)
913 };
914
915 static const msi_table lus0_tables[] =
916 {
917 ADD_TABLE(lus_component),
918 ADD_TABLE(directory),
919 ADD_TABLE(lus_feature),
920 ADD_TABLE(lus_feature_comp),
921 ADD_TABLE(lus_file),
922 ADD_TABLE(lus_install_exec_seq),
923 ADD_TABLE(lus0_media),
924 ADD_TABLE(property)
925 };
926
927 static const msi_table lus1_tables[] =
928 {
929 ADD_TABLE(lus_component),
930 ADD_TABLE(directory),
931 ADD_TABLE(lus_feature),
932 ADD_TABLE(lus_feature_comp),
933 ADD_TABLE(lus_file),
934 ADD_TABLE(lus_install_exec_seq),
935 ADD_TABLE(lus1_media),
936 ADD_TABLE(property)
937 };
938
939 static const msi_table lus2_tables[] =
940 {
941 ADD_TABLE(lus_component),
942 ADD_TABLE(directory),
943 ADD_TABLE(lus_feature),
944 ADD_TABLE(lus_feature_comp),
945 ADD_TABLE(lus_file),
946 ADD_TABLE(lus_install_exec_seq),
947 ADD_TABLE(lus2_media),
948 ADD_TABLE(property)
949 };
950
951 static const msi_table spf_tables[] =
952 {
953 ADD_TABLE(lus_component),
954 ADD_TABLE(directory),
955 ADD_TABLE(lus_feature),
956 ADD_TABLE(lus_feature_comp),
957 ADD_TABLE(lus_file),
958 ADD_TABLE(lus0_media),
959 ADD_TABLE(property),
960 ADD_TABLE(spf_custom_action),
961 ADD_TABLE(spf_install_exec_seq),
962 ADD_TABLE(spf_install_ui_seq)
963 };
964
965 static const msi_table sd_tables[] =
966 {
967 ADD_TABLE(directory),
968 ADD_TABLE(sd_component),
969 ADD_TABLE(sd_feature),
970 ADD_TABLE(sd_feature_comp),
971 ADD_TABLE(sd_file),
972 ADD_TABLE(sd_install_exec_seq),
973 ADD_TABLE(sd_install_ui_seq),
974 ADD_TABLE(sd_custom_action),
975 ADD_TABLE(media),
976 ADD_TABLE(property)
977 };
978
979 static const msi_table ci_tables[] =
980 {
981 ADD_TABLE(ci_component),
982 ADD_TABLE(directory),
983 ADD_TABLE(lus_feature),
984 ADD_TABLE(lus_feature_comp),
985 ADD_TABLE(lus_file),
986 ADD_TABLE(ci_install_exec_seq),
987 ADD_TABLE(lus0_media),
988 ADD_TABLE(property),
989 ADD_TABLE(ci_custom_action),
990 };
991
992 static const msi_table ci2_tables[] =
993 {
994 ADD_TABLE(ci2_component),
995 ADD_TABLE(directory),
996 ADD_TABLE(lus_feature),
997 ADD_TABLE(ci2_feature_comp),
998 ADD_TABLE(ci2_file),
999 ADD_TABLE(install_exec_seq),
1000 ADD_TABLE(lus0_media),
1001 ADD_TABLE(property),
1002 };
1003
1004 static const msi_table cl_tables[] =
1005 {
1006 ADD_TABLE(component),
1007 ADD_TABLE(directory),
1008 ADD_TABLE(feature),
1009 ADD_TABLE(feature_comp),
1010 ADD_TABLE(file),
1011 ADD_TABLE(cl_custom_action),
1012 ADD_TABLE(cl_install_exec_seq),
1013 ADD_TABLE(media),
1014 ADD_TABLE(property)
1015 };
1016
1017 static void write_file(const CHAR *filename, const char *data, int data_size)
1018 {
1019 DWORD size;
1020
1021 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
1022 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1023 WriteFile(hf, data, data_size, &size, NULL);
1024 CloseHandle(hf);
1025 }
1026
1027 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
1028 {
1029 MSIHANDLE summary;
1030 UINT r;
1031
1032 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1033 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1034
1035 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
1036 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1037
1038 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1039 "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
1040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1041
1042 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
1043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1044
1045 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
1046 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1047
1048 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1050
1051 /* write the summary changes back to the stream */
1052 r = MsiSummaryInfoPersist(summary);
1053 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1054
1055 MsiCloseHandle(summary);
1056 }
1057
1058 #define create_database(name, tables, num_tables) \
1059 create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
1060
1061 #define create_database_template(name, tables, num_tables, version, template) \
1062 create_database_wordcount(name, tables, num_tables, version, 0, template);
1063
1064 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
1065 int num_tables, INT version, INT wordcount,
1066 const char *template)
1067 {
1068 MSIHANDLE db;
1069 UINT r;
1070 WCHAR *nameW;
1071 int j, len;
1072
1073 len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
1074 if (!(nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return;
1075 MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
1076
1077 r = MsiOpenDatabaseW(nameW, MSIDBOPEN_CREATE, &db);
1078 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1079
1080 /* import the tables into the database */
1081 for (j = 0; j < num_tables; j++)
1082 {
1083 const msi_table *table = &tables[j];
1084
1085 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1086
1087 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1088 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1089
1090 DeleteFileA(table->filename);
1091 }
1092
1093 write_msi_summary_info(db, version, wordcount, template);
1094
1095 r = MsiDatabaseCommit(db);
1096 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1097
1098 MsiCloseHandle(db);
1099 HeapFree( GetProcessHeap(), 0, nameW );
1100 }
1101
1102 static UINT run_query(MSIHANDLE hdb, const char *query)
1103 {
1104 MSIHANDLE hview = 0;
1105 UINT r;
1106
1107 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1108 if (r != ERROR_SUCCESS)
1109 return r;
1110
1111 r = MsiViewExecute(hview, 0);
1112 if (r == ERROR_SUCCESS)
1113 r = MsiViewClose(hview);
1114 MsiCloseHandle(hview);
1115 return r;
1116 }
1117
1118 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
1119 {
1120 UINT res;
1121 MSIHANDLE suminfo;
1122
1123 /* build summary info */
1124 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
1125 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
1126
1127 res = MsiSummaryInfoSetPropertyA(suminfo, 2, VT_LPSTR, 0, NULL,
1128 "Installation Database");
1129 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1130
1131 res = MsiSummaryInfoSetPropertyA(suminfo, 3, VT_LPSTR, 0, NULL,
1132 "Installation Database");
1133 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1134
1135 res = MsiSummaryInfoSetPropertyA(suminfo, 4, VT_LPSTR, 0, NULL,
1136 "Wine Hackers");
1137 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1138
1139 res = MsiSummaryInfoSetPropertyA(suminfo, 7, VT_LPSTR, 0, NULL,
1140 ";1033");
1141 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1142
1143 res = MsiSummaryInfoSetPropertyA(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1144 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
1145 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1146
1147 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
1148 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1149
1150 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
1151 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1152
1153 res = MsiSummaryInfoPersist(suminfo);
1154 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
1155
1156 res = MsiCloseHandle(suminfo);
1157 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
1158
1159 return res;
1160 }
1161
1162 static MSIHANDLE create_package_db(LPSTR prodcode)
1163 {
1164 MSIHANDLE hdb = 0;
1165 CHAR query[MAX_PATH];
1166 UINT res;
1167
1168 DeleteFileA(msifile);
1169
1170 /* create an empty database */
1171 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
1172 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1173 if (res != ERROR_SUCCESS)
1174 return hdb;
1175
1176 res = MsiDatabaseCommit(hdb);
1177 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1178
1179 set_summary_info(hdb, prodcode);
1180
1181 res = run_query(hdb,
1182 "CREATE TABLE `Directory` ( "
1183 "`Directory` CHAR(255) NOT NULL, "
1184 "`Directory_Parent` CHAR(255), "
1185 "`DefaultDir` CHAR(255) NOT NULL "
1186 "PRIMARY KEY `Directory`)");
1187 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1188
1189 res = run_query(hdb,
1190 "CREATE TABLE `Property` ( "
1191 "`Property` CHAR(72) NOT NULL, "
1192 "`Value` CHAR(255) "
1193 "PRIMARY KEY `Property`)");
1194 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1195
1196 sprintf(query, "INSERT INTO `Property` "
1197 "(`Property`, `Value`) "
1198 "VALUES( 'ProductCode', '%s' )", prodcode);
1199 res = run_query(hdb, query);
1200 ok(res == ERROR_SUCCESS , "Failed\n");
1201
1202 res = MsiDatabaseCommit(hdb);
1203 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1204
1205 return hdb;
1206 }
1207
1208 static void test_usefeature(void)
1209 {
1210 INSTALLSTATE r;
1211
1212 if (!pMsiUseFeatureExA)
1213 {
1214 win_skip("MsiUseFeatureExA not implemented\n");
1215 return;
1216 }
1217
1218 r = MsiQueryFeatureStateA(NULL, NULL);
1219 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1220
1221 r = MsiQueryFeatureStateA("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
1222 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1223
1224 r = pMsiUseFeatureExA(NULL,NULL,0,0);
1225 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1226
1227 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
1228 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1229
1230 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1231 NULL, -2, 0 );
1232 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1233
1234 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
1235 "WORDVIEWFiles", -2, 0 );
1236 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1237
1238 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
1239 "WORDVIEWFiles", -2, 0 );
1240 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1241
1242 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1243 "WORDVIEWFiles", -2, 1 );
1244 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1245 }
1246
1247 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
1248 {
1249 if (pRegDeleteKeyExA)
1250 return pRegDeleteKeyExA( key, subkey, access, 0 );
1251 return RegDeleteKeyA( key, subkey );
1252 }
1253
1254 static void test_null(void)
1255 {
1256 MSIHANDLE hpkg;
1257 UINT r;
1258 HKEY hkey;
1259 DWORD dwType, cbData;
1260 LPBYTE lpData = NULL;
1261 INSTALLSTATE state;
1262 REGSAM access = KEY_ALL_ACCESS;
1263
1264 if (is_wow64)
1265 access |= KEY_WOW64_64KEY;
1266
1267 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
1268 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1269
1270 state = MsiQueryProductStateW(NULL);
1271 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
1272
1273 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
1274 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1275
1276 r = MsiConfigureFeatureW(NULL, NULL, 0);
1277 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1278
1279 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
1280 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1281
1282 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
1283 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1284
1285 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
1286 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
1287
1288 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
1289 * necessary registry values */
1290
1291 /* empty product string */
1292 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
1293 if (r == ERROR_ACCESS_DENIED)
1294 {
1295 skip("Not enough rights to perform tests\n");
1296 return;
1297 }
1298 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1299
1300 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1301 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
1302 if ( r == ERROR_SUCCESS )
1303 {
1304 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
1305 if (!lpData)
1306 skip("Out of memory\n");
1307 else
1308 {
1309 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1310 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1311 }
1312 }
1313
1314 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1315 if (r == ERROR_ACCESS_DENIED)
1316 {
1317 skip("Not enough rights to perform tests\n");
1318 HeapFree(GetProcessHeap(), 0, lpData);
1319 RegCloseKey(hkey);
1320 return;
1321 }
1322 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1323
1324 r = MsiGetProductInfoA("", "", NULL, NULL);
1325 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1326
1327 if (lpData)
1328 {
1329 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
1330 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1331
1332 HeapFree(GetProcessHeap(), 0, lpData);
1333 }
1334 else
1335 {
1336 r = RegDeleteValueA(hkey, NULL);
1337 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1338 }
1339
1340 r = RegCloseKey(hkey);
1341 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1342
1343 /* empty attribute */
1344 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1345 0, NULL, 0, access, NULL, &hkey, NULL);
1346 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1347
1348 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1349 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1350
1351 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
1352 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
1353
1354 r = RegCloseKey(hkey);
1355 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1356
1357 r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1358 access & KEY_WOW64_64KEY);
1359 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1360 }
1361
1362 static void test_getcomponentpath(void)
1363 {
1364 INSTALLSTATE r;
1365 char buffer[0x100];
1366 DWORD sz;
1367
1368 if(!pMsiGetComponentPathA)
1369 return;
1370
1371 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
1372 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1373
1374 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
1375 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1376
1377 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
1378 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1379
1380 sz = sizeof buffer;
1381 buffer[0]=0;
1382 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
1383 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1384
1385 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
1386 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
1387 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1388
1389 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1390 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
1391 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1392
1393 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1394 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
1395 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1396
1397 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
1398 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
1399 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1400 }
1401
1402 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
1403 {
1404 HANDLE file;
1405 DWORD written;
1406
1407 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1408 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1409 WriteFile(file, data, strlen(data), &written, NULL);
1410
1411 if (size)
1412 {
1413 SetFilePointer(file, size, NULL, FILE_BEGIN);
1414 SetEndOfFile(file);
1415 }
1416
1417 CloseHandle(file);
1418 }
1419
1420 static void create_test_files(void)
1421 {
1422 CreateDirectoryA("msitest", NULL);
1423 create_file("msitest\\one.txt", "msitest\\one.txt", 100);
1424 CreateDirectoryA("msitest\\first", NULL);
1425 create_file("msitest\\first\\two.txt", "msitest\\first\\two.txt", 100);
1426 CreateDirectoryA("msitest\\second", NULL);
1427 create_file("msitest\\second\\three.txt", "msitest\\second\\three.txt", 100);
1428
1429 create_file("four.txt", "four.txt", 100);
1430 create_file("five.txt", "five.txt", 100);
1431 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1432
1433 create_file("msitest\\filename", "msitest\\filename", 100);
1434 create_file("msitest\\service.exe", "msitest\\service.exe", 100);
1435
1436 DeleteFileA("four.txt");
1437 DeleteFileA("five.txt");
1438 }
1439
1440 static void delete_test_files(void)
1441 {
1442 DeleteFileA("msitest.msi");
1443 DeleteFileA("msitest.cab");
1444 DeleteFileA("msitest\\second\\three.txt");
1445 DeleteFileA("msitest\\first\\two.txt");
1446 DeleteFileA("msitest\\one.txt");
1447 DeleteFileA("msitest\\service.exe");
1448 DeleteFileA("msitest\\filename");
1449 RemoveDirectoryA("msitest\\second");
1450 RemoveDirectoryA("msitest\\first");
1451 RemoveDirectoryA("msitest");
1452 }
1453
1454 #define HASHSIZE sizeof(MSIFILEHASHINFO)
1455
1456 static const struct
1457 {
1458 LPCSTR data;
1459 DWORD size;
1460 MSIFILEHASHINFO hash;
1461 } hash_data[] =
1462 {
1463 { "", 0,
1464 { HASHSIZE,
1465 { 0, 0, 0, 0 },
1466 },
1467 },
1468
1469 { "abc", 0,
1470 { HASHSIZE,
1471 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
1472 },
1473 },
1474
1475 { "C:\\Program Files\\msitest\\caesar\n", 0,
1476 { HASHSIZE,
1477 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
1478 },
1479 },
1480
1481 { "C:\\Program Files\\msitest\\caesar\n", 500,
1482 { HASHSIZE,
1483 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
1484 },
1485 },
1486 };
1487
1488 static void test_MsiGetFileHash(void)
1489 {
1490 const char name[] = "msitest.bin";
1491 UINT r;
1492 MSIFILEHASHINFO hash;
1493 DWORD i;
1494
1495 if (!pMsiGetFileHashA)
1496 {
1497 win_skip("MsiGetFileHash not implemented\n");
1498 return;
1499 }
1500
1501 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1502
1503 /* szFilePath is NULL */
1504 r = pMsiGetFileHashA(NULL, 0, &hash);
1505 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1506
1507 /* szFilePath is empty */
1508 r = pMsiGetFileHashA("", 0, &hash);
1509 ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
1510 "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
1511
1512 /* szFilePath is nonexistent */
1513 r = pMsiGetFileHashA(name, 0, &hash);
1514 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
1515
1516 /* dwOptions is non-zero */
1517 r = pMsiGetFileHashA(name, 1, &hash);
1518 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1519
1520 /* pHash.dwFileHashInfoSize is not correct */
1521 hash.dwFileHashInfoSize = 0;
1522 r = pMsiGetFileHashA(name, 0, &hash);
1523 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1524
1525 /* pHash is NULL */
1526 r = pMsiGetFileHashA(name, 0, NULL);
1527 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1528
1529 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
1530 {
1531 int ret;
1532
1533 create_file(name, hash_data[i].data, hash_data[i].size);
1534
1535 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
1536 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1537
1538 r = pMsiGetFileHashA(name, 0, &hash);
1539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1540
1541 ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
1542 ok(!ret, "Hash incorrect\n");
1543
1544 DeleteFileA(name);
1545 }
1546 }
1547
1548 /* copied from dlls/msi/registry.c */
1549 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
1550 {
1551 DWORD i,n=1;
1552 GUID guid;
1553
1554 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
1555 return FALSE;
1556
1557 for(i=0; i<8; i++)
1558 out[7-i] = in[n++];
1559 n++;
1560 for(i=0; i<4; i++)
1561 out[11-i] = in[n++];
1562 n++;
1563 for(i=0; i<4; i++)
1564 out[15-i] = in[n++];
1565 n++;
1566 for(i=0; i<2; i++)
1567 {
1568 out[17+i*2] = in[n++];
1569 out[16+i*2] = in[n++];
1570 }
1571 n++;
1572 for( ; i<8; i++)
1573 {
1574 out[17+i*2] = in[n++];
1575 out[16+i*2] = in[n++];
1576 }
1577 out[32]=0;
1578 return TRUE;
1579 }
1580
1581 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
1582 {
1583 WCHAR guidW[MAX_PATH];
1584 WCHAR squashedW[MAX_PATH];
1585 GUID guid;
1586 HRESULT hr;
1587 int size;
1588
1589 hr = CoCreateGuid(&guid);
1590 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1591
1592 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1593 ok(size == 39, "Expected 39, got %d\n", hr);
1594
1595 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
1596 if (squashed)
1597 {
1598 squash_guid(guidW, squashedW);
1599 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1600 }
1601 }
1602
1603 static char *get_user_sid(void)
1604 {
1605 HANDLE token;
1606 DWORD size = 0;
1607 TOKEN_USER *user;
1608 char *usersid = NULL;
1609
1610 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1611 GetTokenInformation(token, TokenUser, NULL, size, &size);
1612
1613 user = HeapAlloc(GetProcessHeap(), 0, size);
1614 GetTokenInformation(token, TokenUser, user, size, &size);
1615 pConvertSidToStringSidA(user->User.Sid, &usersid);
1616 HeapFree(GetProcessHeap(), 0, user);
1617
1618 CloseHandle(token);
1619 return usersid;
1620 }
1621
1622 static void test_MsiQueryProductState(void)
1623 {
1624 CHAR prodcode[MAX_PATH];
1625 CHAR prod_squashed[MAX_PATH];
1626 CHAR keypath[MAX_PATH*2];
1627 LPSTR usersid;
1628 INSTALLSTATE state;
1629 LONG res;
1630 HKEY userkey, localkey, props;
1631 HKEY prodkey;
1632 DWORD data, error;
1633 REGSAM access = KEY_ALL_ACCESS;
1634
1635 create_test_guid(prodcode, prod_squashed);
1636 usersid = get_user_sid();
1637
1638 if (is_wow64)
1639 access |= KEY_WOW64_64KEY;
1640
1641 /* NULL prodcode */
1642 SetLastError(0xdeadbeef);
1643 state = MsiQueryProductStateA(NULL);
1644 error = GetLastError();
1645 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1646 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1647
1648 /* empty prodcode */
1649 SetLastError(0xdeadbeef);
1650 state = MsiQueryProductStateA("");
1651 error = GetLastError();
1652 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1653 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1654
1655 /* garbage prodcode */
1656 SetLastError(0xdeadbeef);
1657 state = MsiQueryProductStateA("garbage");
1658 error = GetLastError();
1659 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1660 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1661
1662 /* guid without brackets */
1663 SetLastError(0xdeadbeef);
1664 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
1665 error = GetLastError();
1666 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1667 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1668
1669 /* guid with brackets */
1670 SetLastError(0xdeadbeef);
1671 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
1672 error = GetLastError();
1673 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1674 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1675 "expected ERROR_SUCCESS, got %u\n", error);
1676
1677 /* same length as guid, but random */
1678 SetLastError(0xdeadbeef);
1679 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
1680 error = GetLastError();
1681 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1682 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1683
1684 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1685
1686 SetLastError(0xdeadbeef);
1687 state = MsiQueryProductStateA(prodcode);
1688 error = GetLastError();
1689 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1690 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1691 "expected ERROR_SUCCESS, got %u\n", error);
1692
1693 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1694 lstrcatA(keypath, prod_squashed);
1695
1696 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1698
1699 /* user product key exists */
1700 SetLastError(0xdeadbeef);
1701 state = MsiQueryProductStateA(prodcode);
1702 error = GetLastError();
1703 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1704 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1705 "expected ERROR_SUCCESS, got %u\n", error);
1706
1707 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
1708 lstrcatA(keypath, prodcode);
1709
1710 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1711 if (res == ERROR_ACCESS_DENIED)
1712 {
1713 skip("Not enough rights to perform tests\n");
1714 RegDeleteKeyA(userkey, "");
1715 RegCloseKey(userkey);
1716 LocalFree(usersid);
1717 return;
1718 }
1719 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1720
1721 /* local uninstall key exists */
1722 SetLastError(0xdeadbeef);
1723 state = MsiQueryProductStateA(prodcode);
1724 error = GetLastError();
1725 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1726 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1727 "expected ERROR_SUCCESS, got %u\n", error);
1728
1729 data = 1;
1730 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1731 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1732
1733 /* WindowsInstaller value exists */
1734 SetLastError(0xdeadbeef);
1735 state = MsiQueryProductStateA(prodcode);
1736 error = GetLastError();
1737 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1738 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1739 "expected ERROR_SUCCESS, got %u\n", error);
1740
1741 RegDeleteValueA(localkey, "WindowsInstaller");
1742 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1743
1744 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1745 lstrcatA(keypath, usersid);
1746 lstrcatA(keypath, "\\Products\\");
1747 lstrcatA(keypath, prod_squashed);
1748
1749 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1750 if (res == ERROR_ACCESS_DENIED)
1751 {
1752 skip("Not enough rights to perform tests\n");
1753 RegDeleteKeyA(userkey, "");
1754 RegCloseKey(userkey);
1755 LocalFree(usersid);
1756 return;
1757 }
1758 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1759
1760 /* local product key exists */
1761 SetLastError(0xdeadbeef);
1762 state = MsiQueryProductStateA(prodcode);
1763 error = GetLastError();
1764 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1765 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1766 "expected ERROR_SUCCESS, got %u\n", error);
1767
1768 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1769 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1770
1771 /* install properties key exists */
1772 SetLastError(0xdeadbeef);
1773 state = MsiQueryProductStateA(prodcode);
1774 error = GetLastError();
1775 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1776 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1777 "expected ERROR_SUCCESS, got %u\n", error);
1778
1779 data = 1;
1780 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1781 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1782
1783 /* WindowsInstaller value exists */
1784 SetLastError(0xdeadbeef);
1785 state = MsiQueryProductStateA(prodcode);
1786 error = GetLastError();
1787 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1788 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1789 "expected ERROR_SUCCESS, got %u\n", error);
1790
1791 data = 2;
1792 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1793 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1794
1795 /* WindowsInstaller value is not 1 */
1796 SetLastError(0xdeadbeef);
1797 state = MsiQueryProductStateA(prodcode);
1798 error = GetLastError();
1799 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1800 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1801 "expected ERROR_SUCCESS, got %u\n", error);
1802
1803 RegDeleteKeyA(userkey, "");
1804
1805 /* user product key does not exist */
1806 SetLastError(0xdeadbeef);
1807 state = MsiQueryProductStateA(prodcode);
1808 error = GetLastError();
1809 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1810 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1811 "expected ERROR_SUCCESS, got %u\n", error);
1812
1813 RegDeleteValueA(props, "WindowsInstaller");
1814 delete_key(props, "", access & KEY_WOW64_64KEY);
1815 RegCloseKey(props);
1816 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1817 RegCloseKey(localkey);
1818 RegDeleteKeyA(userkey, "");
1819 RegCloseKey(userkey);
1820
1821 /* MSIINSTALLCONTEXT_USERMANAGED */
1822
1823 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1824 lstrcatA(keypath, usersid);
1825 lstrcatA(keypath, "\\Installer\\Products\\");
1826 lstrcatA(keypath, prod_squashed);
1827
1828 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1829 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1830
1831 state = MsiQueryProductStateA(prodcode);
1832 ok(state == INSTALLSTATE_ADVERTISED,
1833 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1834
1835 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1836 lstrcatA(keypath, usersid);
1837 lstrcatA(keypath, "\\Products\\");
1838 lstrcatA(keypath, prod_squashed);
1839
1840 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1841 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1842
1843 state = MsiQueryProductStateA(prodcode);
1844 ok(state == INSTALLSTATE_ADVERTISED,
1845 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1846
1847 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1848 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1849
1850 state = MsiQueryProductStateA(prodcode);
1851 ok(state == INSTALLSTATE_ADVERTISED,
1852 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1853
1854 data = 1;
1855 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1857
1858 /* WindowsInstaller value exists */
1859 state = MsiQueryProductStateA(prodcode);
1860 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1861
1862 RegDeleteValueA(props, "WindowsInstaller");
1863 delete_key(props, "", access & KEY_WOW64_64KEY);
1864 RegCloseKey(props);
1865 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1866 RegCloseKey(localkey);
1867 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1868 RegCloseKey(prodkey);
1869
1870 /* MSIINSTALLCONTEXT_MACHINE */
1871
1872 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1873 lstrcatA(keypath, prod_squashed);
1874
1875 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1876 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1877
1878 state = MsiQueryProductStateA(prodcode);
1879 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1880
1881 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1882 lstrcatA(keypath, "S-1-5-18\\Products\\");
1883 lstrcatA(keypath, prod_squashed);
1884
1885 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1886 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1887
1888 state = MsiQueryProductStateA(prodcode);
1889 ok(state == INSTALLSTATE_ADVERTISED,
1890 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1891
1892 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1893 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1894
1895 state = MsiQueryProductStateA(prodcode);
1896 ok(state == INSTALLSTATE_ADVERTISED,
1897 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1898
1899 data = 1;
1900 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1901 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1902
1903 /* WindowsInstaller value exists */
1904 state = MsiQueryProductStateA(prodcode);
1905 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1906
1907 RegDeleteValueA(props, "WindowsInstaller");
1908 delete_key(props, "", access & KEY_WOW64_64KEY);
1909 RegCloseKey(props);
1910 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1911 RegCloseKey(localkey);
1912 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1913 RegCloseKey(prodkey);
1914
1915 LocalFree(usersid);
1916 }
1917
1918 static const char table_enc85[] =
1919 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
1920 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
1921 "yz{}~";
1922
1923 /*
1924 * Encodes a base85 guid given a GUID pointer
1925 * Caller should provide a 21 character buffer for the encoded string.
1926 */
1927 static void encode_base85_guid( GUID *guid, LPWSTR str )
1928 {
1929 unsigned int x, *p, i;
1930
1931 p = (unsigned int*) guid;
1932 for( i=0; i<4; i++ )
1933 {
1934 x = p[i];
1935 *str++ = table_enc85[x%85];
1936 x = x/85;
1937 *str++ = table_enc85[x%85];
1938 x = x/85;
1939 *str++ = table_enc85[x%85];
1940 x = x/85;
1941 *str++ = table_enc85[x%85];
1942 x = x/85;
1943 *str++ = table_enc85[x%85];
1944 }
1945 *str = 0;
1946 }
1947
1948 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
1949 {
1950 WCHAR guidW[MAX_PATH];
1951 WCHAR base85W[MAX_PATH];
1952 WCHAR squashedW[MAX_PATH];
1953 GUID guid;
1954 HRESULT hr;
1955 int size;
1956
1957 hr = CoCreateGuid(&guid);
1958 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1959
1960 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1961 ok(size == 39, "Expected 39, got %d\n", hr);
1962
1963 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1964 encode_base85_guid(&guid, base85W);
1965 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1966 squash_guid(guidW, squashedW);
1967 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1968 }
1969
1970 static void test_MsiQueryFeatureState(void)
1971 {
1972 HKEY userkey, localkey, compkey, compkey2;
1973 CHAR prodcode[MAX_PATH];
1974 CHAR prod_squashed[MAX_PATH];
1975 CHAR component[MAX_PATH];
1976 CHAR comp_base85[MAX_PATH];
1977 CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
1978 CHAR keypath[MAX_PATH*2];
1979 INSTALLSTATE state;
1980 LPSTR usersid;
1981 LONG res;
1982 REGSAM access = KEY_ALL_ACCESS;
1983 DWORD error;
1984
1985 create_test_guid(prodcode, prod_squashed);
1986 compose_base85_guid(component, comp_base85, comp_squashed);
1987 compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
1988 usersid = get_user_sid();
1989
1990 if (is_wow64)
1991 access |= KEY_WOW64_64KEY;
1992
1993 /* NULL prodcode */
1994 SetLastError(0xdeadbeef);
1995 state = MsiQueryFeatureStateA(NULL, "feature");
1996 error = GetLastError();
1997 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1998 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1999
2000 /* empty prodcode */
2001 SetLastError(0xdeadbeef);
2002 state = MsiQueryFeatureStateA("", "feature");
2003 error = GetLastError();
2004 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2005 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2006
2007 /* garbage prodcode */
2008 SetLastError(0xdeadbeef);
2009 state = MsiQueryFeatureStateA("garbage", "feature");
2010 error = GetLastError();
2011 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2012 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2013
2014 /* guid without brackets */
2015 SetLastError(0xdeadbeef);
2016 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
2017 error = GetLastError();
2018 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2019 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2020
2021 /* guid with brackets */
2022 SetLastError(0xdeadbeef);
2023 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
2024 error = GetLastError();
2025 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2026 ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
2027 "expected ERROR_SUCCESS, got %u\n", error);
2028
2029 /* same length as guid, but random */
2030 SetLastError(0xdeadbeef);
2031 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
2032 error = GetLastError();
2033 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2034 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2035
2036 /* NULL szFeature */
2037 SetLastError(0xdeadbeef);
2038 state = MsiQueryFeatureStateA(prodcode, NULL);
2039 error = GetLastError();
2040 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2041 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2042
2043 /* empty szFeature */
2044 SetLastError(0xdeadbeef);
2045 state = MsiQueryFeatureStateA(prodcode, "");
2046 error = GetLastError();
2047 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2048 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2049 "expected ERROR_SUCCESS, got %u\n", error);
2050
2051 /* feature key does not exist yet */
2052 SetLastError(0xdeadbeef);
2053 state = MsiQueryFeatureStateA(prodcode, "feature");
2054 error = GetLastError();
2055 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2056 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2057 "expected ERROR_SUCCESS, got %u\n", error);
2058
2059 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2060
2061 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
2062 lstrcatA(keypath, prod_squashed);
2063
2064 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2065 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2066
2067 /* feature key exists */
2068 SetLastError(0xdeadbeef);
2069 state = MsiQueryFeatureStateA(prodcode, "feature");
2070 error = GetLastError();
2071 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2072 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2073 "expected ERROR_SUCCESS, got %u\n", error);
2074
2075 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
2076 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2077
2078 /* feature value exists */
2079 SetLastError(0xdeadbeef);
2080 state = MsiQueryFeatureStateA(prodcode, "feature");
2081 error = GetLastError();
2082 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2083 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2084 "expected ERROR_SUCCESS, got %u\n", error);
2085
2086 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2087 lstrcatA(keypath, usersid);
2088 lstrcatA(keypath, "\\Products\\");
2089 lstrcatA(keypath, prod_squashed);
2090 lstrcatA(keypath, "\\Features");
2091
2092 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2093 if (res == ERROR_ACCESS_DENIED)
2094 {
2095 skip("Not enough rights to perform tests\n");
2096 RegDeleteKeyA(userkey, "");
2097 RegCloseKey(userkey);
2098 LocalFree(usersid);
2099 return;
2100 }
2101 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2102
2103 /* userdata features key exists */
2104 SetLastError(0xdeadbeef);
2105 state = MsiQueryFeatureStateA(prodcode, "feature");
2106 error = GetLastError();
2107 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2108 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2109 "expected ERROR_SUCCESS, got %u\n", error);
2110
2111 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2112 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2113
2114 SetLastError(0xdeadbeef);
2115 state = MsiQueryFeatureStateA(prodcode, "feature");
2116 error = GetLastError();
2117 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2118 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2119 "expected ERROR_SUCCESS, got %u\n", error);
2120
2121 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2122 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2123
2124 SetLastError(0xdeadbeef);
2125 state = MsiQueryFeatureStateA(prodcode, "feature");
2126 error = GetLastError();
2127 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2128 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2129 "expected ERROR_SUCCESS, got %u\n", error);
2130
2131 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2132 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2133
2134 SetLastError(0xdeadbeef);
2135 state = MsiQueryFeatureStateA(prodcode, "feature");
2136 error = GetLastError();
2137 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2138 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2139 "expected ERROR_SUCCESS, got %u\n", error);
2140
2141 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2142 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2143
2144 SetLastError(0xdeadbeef);
2145 state = MsiQueryFeatureStateA(prodcode, "feature");
2146 error = GetLastError();
2147 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2148 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2149 "expected ERROR_SUCCESS, got %u\n", error);
2150
2151 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2152 lstrcatA(keypath, usersid);
2153 lstrcatA(keypath, "\\Components\\");
2154 lstrcatA(keypath, comp_squashed);
2155
2156 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2157 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2158
2159 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2160 lstrcatA(keypath, usersid);
2161 lstrcatA(keypath, "\\Components\\");
2162 lstrcatA(keypath, comp_squashed2);
2163
2164 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2165 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2166
2167 SetLastError(0xdeadbeef);
2168 state = MsiQueryFeatureStateA(prodcode, "feature");
2169 error = GetLastError();
2170 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2171 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2172 "expected ERROR_SUCCESS, got %u\n", error);
2173
2174 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2175 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2176
2177 SetLastError(0xdeadbeef);
2178 state = MsiQueryFeatureStateA(prodcode, "feature");
2179 error = GetLastError();
2180 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2181 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2182 "expected ERROR_SUCCESS, got %u\n", error);
2183
2184 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2185 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2186
2187 SetLastError(0xdeadbeef);
2188 state = MsiQueryFeatureStateA(prodcode, "feature");
2189 error = GetLastError();
2190 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2191 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2192 "expected ERROR_SUCCESS, got %u\n", error);
2193
2194 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2195 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2196
2197 /* INSTALLSTATE_LOCAL */
2198 SetLastError(0xdeadbeef);
2199 state = MsiQueryFeatureStateA(prodcode, "feature");
2200 error = GetLastError();
2201 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2202 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2203 "expected ERROR_SUCCESS, got %u\n", error);
2204
2205 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2206 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2207
2208 /* INSTALLSTATE_SOURCE */
2209 SetLastError(0xdeadbeef);
2210 state = MsiQueryFeatureStateA(prodcode, "feature");
2211 error = GetLastError();
2212 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2213 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2214 "expected ERROR_SUCCESS, got %u\n", error);
2215
2216 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2217 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2218
2219 /* bad INSTALLSTATE_SOURCE */
2220 SetLastError(0xdeadbeef);
2221 state = MsiQueryFeatureStateA(prodcode, "feature");
2222 error = GetLastError();
2223 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2224 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2225 "expected ERROR_SUCCESS, got %u\n", error);
2226
2227 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2228 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2229
2230 /* INSTALLSTATE_SOURCE */
2231 SetLastError(0xdeadbeef);
2232 state = MsiQueryFeatureStateA(prodcode, "feature");
2233 error = GetLastError();
2234 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2235 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2236 "expected ERROR_SUCCESS, got %u\n", error);
2237
2238 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2239 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2240
2241 /* bad INSTALLSTATE_SOURCE */
2242 SetLastError(0xdeadbeef);
2243 state = MsiQueryFeatureStateA(prodcode, "feature");
2244 error = GetLastError();
2245 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2246 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2247 "expected ERROR_SUCCESS, got %u\n", error);
2248
2249 RegDeleteValueA(compkey, prod_squashed);
2250 RegDeleteValueA(compkey2, prod_squashed);
2251 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2252 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2253 RegDeleteValueA(localkey, "feature");
2254 RegDeleteValueA(userkey, "feature");
2255 RegDeleteKeyA(userkey, "");
2256 RegCloseKey(compkey);
2257 RegCloseKey(compkey2);
2258 RegCloseKey(localkey);
2259 RegCloseKey(userkey);
2260
2261 /* MSIINSTALLCONTEXT_USERMANAGED */
2262
2263 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2264 lstrcatA(keypath, usersid);
2265 lstrcatA(keypath, "\\Installer\\Features\\");
2266 lstrcatA(keypath, prod_squashed);
2267
2268 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2269 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2270
2271 /* feature key exists */
2272 state = MsiQueryFeatureStateA(prodcode, "feature");
2273 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2274
2275 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2276 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2277
2278 /* feature value exists */
2279 state = MsiQueryFeatureStateA(prodcode, "feature");
2280 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2281
2282 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2283 lstrcatA(keypath, usersid);
2284 lstrcatA(keypath, "\\Products\\");
2285 lstrcatA(keypath, prod_squashed);
2286 lstrcatA(keypath, "\\Features");
2287
2288 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2289 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2290
2291 /* userdata features key exists */
2292 state = MsiQueryFeatureStateA(prodcode, "feature");
2293 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2294
2295 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2297
2298 state = MsiQueryFeatureStateA(prodcode, "feature");
2299 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2300
2301 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2302 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2303
2304 state = MsiQueryFeatureStateA(prodcode, "feature");
2305 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2306
2307 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2308 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2309
2310 state = MsiQueryFeatureStateA(prodcode, "feature");
2311 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2312
2313 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2314 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2315
2316 state = MsiQueryFeatureStateA(prodcode, "feature");
2317 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2318
2319 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2320 lstrcatA(keypath, usersid);
2321 lstrcatA(keypath, "\\Components\\");
2322 lstrcatA(keypath, comp_squashed);
2323
2324 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2325 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2326
2327 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2328 lstrcatA(keypath, usersid);
2329 lstrcatA(keypath, "\\Components\\");
2330 lstrcatA(keypath, comp_squashed2);
2331
2332 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2333 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2334
2335 state = MsiQueryFeatureStateA(prodcode, "feature");
2336 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2337
2338 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2339 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2340
2341 state = MsiQueryFeatureStateA(prodcode, "feature");
2342 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2343
2344 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2345 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2346
2347 state = MsiQueryFeatureStateA(prodcode, "feature");
2348 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2349
2350 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2351 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2352
2353 state = MsiQueryFeatureStateA(prodcode, "feature");
2354 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2355
2356 RegDeleteValueA(compkey, prod_squashed);
2357 RegDeleteValueA(compkey2, prod_squashed);
2358 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2359 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2360 RegDeleteValueA(localkey, "feature");
2361 RegDeleteValueA(userkey, "feature");
2362 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2363 RegCloseKey(compkey);
2364 RegCloseKey(compkey2);
2365 RegCloseKey(localkey);
2366 RegCloseKey(userkey);
2367
2368 /* MSIINSTALLCONTEXT_MACHINE */
2369
2370 lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
2371 lstrcatA(keypath, prod_squashed);
2372
2373 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2375
2376 /* feature key exists */
2377 state = MsiQueryFeatureStateA(prodcode, "feature");
2378 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2379
2380 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2381 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2382
2383 /* feature value exists */
2384 state = MsiQueryFeatureStateA(prodcode, "feature");
2385 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2386
2387 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2388 lstrcatA(keypath, "S-1-5-18\\Products\\");
2389 lstrcatA(keypath, prod_squashed);
2390 lstrcatA(keypath, "\\Features");
2391
2392 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2393 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2394
2395 /* userdata features key exists */
2396 state = MsiQueryFeatureStateA(prodcode, "feature");
2397 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2398
2399 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2401
2402 state = MsiQueryFeatureStateA(prodcode, "feature");
2403 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2404
2405 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2406 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2407
2408 state = MsiQueryFeatureStateA(prodcode, "feature");
2409 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2410
2411 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2412 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2413
2414 state = MsiQueryFeatureStateA(prodcode, "feature");
2415 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2416
2417 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2418 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2419
2420 state = MsiQueryFeatureStateA(prodcode, "feature");
2421 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2422
2423 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2424 lstrcatA(keypath, "S-1-5-18\\Components\\");
2425 lstrcatA(keypath, comp_squashed);
2426
2427 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2428 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2429
2430 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2431 lstrcatA(keypath, "S-1-5-18\\Components\\");
2432 lstrcatA(keypath, comp_squashed2);
2433
2434 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2435 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2436
2437 state = MsiQueryFeatureStateA(prodcode, "feature");
2438 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2439
2440 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2442
2443 state = MsiQueryFeatureStateA(prodcode, "feature");
2444 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2445
2446 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2447 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2448
2449 state = MsiQueryFeatureStateA(prodcode, "feature");
2450 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2451
2452 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2453 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2454
2455 state = MsiQueryFeatureStateA(prodcode, "feature");
2456 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2457
2458 RegDeleteValueA(compkey, prod_squashed);
2459 RegDeleteValueA(compkey2, prod_squashed);
2460 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2461 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2462 RegDeleteValueA(localkey, "feature");
2463 RegDeleteValueA(userkey, "feature");
2464 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2465 RegCloseKey(compkey);
2466 RegCloseKey(compkey2);
2467 RegCloseKey(localkey);
2468 RegCloseKey(userkey);
2469 LocalFree(usersid);
2470 }
2471
2472 static void test_MsiQueryComponentState(void)
2473 {
2474 HKEY compkey, prodkey;
2475 CHAR prodcode[MAX_PATH];
2476 CHAR prod_squashed[MAX_PATH];
2477 CHAR component[MAX_PATH];
2478 CHAR comp_base85[MAX_PATH];
2479 CHAR comp_squashed[MAX_PATH];
2480 CHAR keypath[MAX_PATH];
2481 INSTALLSTATE state;
2482 LPSTR usersid;
2483 LONG res;
2484 UINT r;
2485 REGSAM access = KEY_ALL_ACCESS;
2486 DWORD error;
2487
2488 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
2489
2490 if (!pMsiQueryComponentStateA)
2491 {
2492 win_skip("MsiQueryComponentStateA not implemented\n");
2493 return;
2494 }
2495
2496 create_test_guid(prodcode, prod_squashed);
2497 compose_base85_guid(component, comp_base85, comp_squashed);
2498 usersid = get_user_sid();
2499
2500 if (is_wow64)
2501 access |= KEY_WOW64_64KEY;
2502
2503 /* NULL szProductCode */
2504 state = MAGIC_ERROR;
2505 SetLastError(0xdeadbeef);
2506 r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2507 error = GetLastError();
2508 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2509 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2510 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2511
2512 /* empty szProductCode */
2513 state = MAGIC_ERROR;
2514 SetLastError(0xdeadbeef);
2515 r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2516 error = GetLastError();
2517 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2518 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2519 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2520
2521 /* random szProductCode */
2522 state = MAGIC_ERROR;
2523 SetLastError(0xdeadbeef);
2524 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2525 error = GetLastError();
2526 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2527 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2528 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2529
2530 /* GUID-length szProductCode */
2531 state = MAGIC_ERROR;
2532 SetLastError(0xdeadbeef);
2533 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2534 error = GetLastError();
2535 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2536 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2537 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2538
2539 /* GUID-length with brackets */
2540 state = MAGIC_ERROR;
2541 SetLastError(0xdeadbeef);
2542 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2543 error = GetLastError();
2544 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2545 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2546 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2547
2548 /* actual GUID */
2549 state = MAGIC_ERROR;
2550 SetLastError(0xdeadbeef);
2551 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2552 error = GetLastError();
2553 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2554 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2555 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2556
2557 state = MAGIC_ERROR;
2558 SetLastError(0xdeadbeef);
2559 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2560 error = GetLastError();
2561 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2562 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2563 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2564
2565 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2566 lstrcatA(keypath, prod_squashed);
2567
2568 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2569 if (res == ERROR_ACCESS_DENIED)
2570 {
2571 skip("Not enough rights to perform tests\n");
2572 LocalFree(usersid);
2573 return;
2574 }
2575 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2576
2577 state = MAGIC_ERROR;
2578 SetLastError(0xdeadbeef);
2579 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2580 error = GetLastError();
2581 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2582 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2583 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2584
2585 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2586 RegCloseKey(prodkey);
2587
2588 /* create local system product key */
2589 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
2590 lstrcatA(keypath, prod_squashed);
2591 lstrcatA(keypath, "\\InstallProperties");
2592
2593 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2594 if (res == ERROR_ACCESS_DENIED)
2595 {
2596 skip("Not enough rights to perform tests\n");
2597 LocalFree(usersid);
2598 return;
2599 }
2600 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2601
2602 /* local system product key exists */
2603 state = MAGIC_ERROR;
2604 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2605 error = GetLastError();
2606 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2607 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2608 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2609
2610 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2611 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2612
2613 /* LocalPackage value exists */
2614 state = MAGIC_ERROR;
2615 SetLastError(0xdeadbeef);
2616 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2617 error = GetLastError();
2618 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2619 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2620 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2621
2622 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
2623 lstrcatA(keypath, comp_squashed);
2624
2625 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2626 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2627
2628 /* component key exists */
2629 state = MAGIC_ERROR;
2630 SetLastError(0xdeadbeef);
2631 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2632 error = GetLastError();
2633 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2634 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2635 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2636
2637 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2638 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2639
2640 /* component\product exists */
2641 state = MAGIC_ERROR;
2642 SetLastError(0xdeadbeef);
2643 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2645 error = GetLastError();
2646 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2647 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2648 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2649
2650 /* NULL component, product exists */
2651 state = MAGIC_ERROR;
2652 SetLastError(0xdeadbeef);
2653 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
2654 error = GetLastError();
2655 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2656 ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
2657 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2658
2659 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2660 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2661
2662 /* INSTALLSTATE_LOCAL */
2663 state = MAGIC_ERROR;
2664 SetLastError(0xdeadbeef);
2665 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2666 error = GetLastError();
2667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2668 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2669 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2670
2671 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2672 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2673
2674 /* INSTALLSTATE_SOURCE */
2675 state = MAGIC_ERROR;
2676 SetLastError(0xdeadbeef);
2677 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2678 error = GetLastError();
2679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2680 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2681 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2682
2683 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2685
2686 /* bad INSTALLSTATE_SOURCE */
2687 state = MAGIC_ERROR;
2688 SetLastError(0xdeadbeef);
2689 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2690 error = GetLastError();
2691 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2692 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2693 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2694
2695 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2696 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2697
2698 /* INSTALLSTATE_SOURCE */
2699 state = MAGIC_ERROR;
2700 SetLastError(0xdeadbeef);
2701 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2702 error = GetLastError();
2703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2704 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2705 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2706
2707 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
2708 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2709
2710 /* registry component */
2711 state = MAGIC_ERROR;
2712 SetLastError(0xdeadbeef);
2713 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2714 error = GetLastError();
2715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2716 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2717 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2718
2719 RegDeleteValueA(prodkey, "LocalPackage");
2720 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2721 RegDeleteValueA(compkey, prod_squashed);
2722 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2723 RegCloseKey(prodkey);
2724 RegCloseKey(compkey);
2725
2726 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2727
2728 state = MAGIC_ERROR;
2729 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2730 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2731 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2732
2733 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2734 lstrcatA(keypath, prod_squashed);
2735
2736 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2737 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2738
2739 state = MAGIC_ERROR;
2740 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2741 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2742 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2743
2744 RegDeleteKeyA(prodkey, "");
2745 RegCloseKey(prodkey);
2746
2747 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2748 lstrcatA(keypath, usersid);
2749 lstrcatA(keypath, "\\Products\\");
2750 lstrcatA(keypath, prod_squashed);
2751 lstrcatA(keypath, "\\InstallProperties");
2752
2753 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2754 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2755
2756 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2757 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2758
2759 RegCloseKey(prodkey);
2760
2761 state = MAGIC_ERROR;
2762 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2763 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2764 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2765
2766 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2767 lstrcatA(keypath, usersid);
2768 lstrcatA(keypath, "\\Components\\");
2769 lstrcatA(keypath, comp_squashed);
2770
2771 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2772 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2773
2774 /* component key exists */
2775 state = MAGIC_ERROR;
2776 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2777 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2778 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2779
2780 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2781 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2782
2783 /* component\product exists */
2784 state = MAGIC_ERROR;
2785 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2787 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2788 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2789
2790 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2791 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2792
2793 state = MAGIC_ERROR;
2794 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2795 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2796 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2797
2798 /* MSIINSTALLCONTEXT_USERMANAGED */
2799
2800 state = MAGIC_ERROR;
2801 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2802 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2803 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2804
2805 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2806 lstrcatA(keypath, prod_squashed);
2807
2808 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2809 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2810
2811 state = MAGIC_ERROR;
2812 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2813 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2814 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2815
2816 RegDeleteKeyA(prodkey, "");
2817 RegCloseKey(prodkey);
2818
2819 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2820 lstrcatA(keypath, usersid);
2821 lstrcatA(keypath, "\\Installer\\Products\\");
2822 lstrcatA(keypath, prod_squashed);
2823
2824 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2825 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2826
2827 state = MAGIC_ERROR;
2828 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2829 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2830 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2831
2832 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2833 RegCloseKey(prodkey);
2834
2835 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2836 lstrcatA(keypath, usersid);
2837 lstrcatA(keypath, "\\Products\\");
2838 lstrcatA(keypath, prod_squashed);
2839 lstrcatA(keypath, "\\InstallProperties");
2840
2841 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2842 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2843
2844 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2845 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2846
2847 state = MAGIC_ERROR;
2848 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2850 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2851
2852 RegDeleteValueA(prodkey, "LocalPackage");
2853 RegDeleteValueA(prodkey, "ManagedLocalPackage");
2854 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2855 RegDeleteValueA(compkey, prod_squashed);
2856 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2857 RegCloseKey(prodkey);
2858 RegCloseKey(compkey);
2859 LocalFree(usersid);
2860 }
2861
2862 static void test_MsiGetComponentPath(void)
2863 {
2864 HKEY compkey, prodkey, installprop;
2865 CHAR prodcode[MAX_PATH];
2866 CHAR prod_squashed[MAX_PATH];
2867 CHAR component[MAX_PATH];
2868 CHAR comp_base85[MAX_PATH];
2869 CHAR comp_squashed[MAX_PATH];
2870 CHAR keypath[MAX_PATH];
2871 CHAR path[MAX_PATH];
2872 INSTALLSTATE state;
2873 LPSTR usersid;
2874 DWORD size, val;
2875 REGSAM access = KEY_ALL_ACCESS;
2876 LONG res;
2877
2878 create_test_guid(prodcode, prod_squashed);
2879 compose_base85_guid(component, comp_base85, comp_squashed);
2880 usersid = get_user_sid();
2881
2882 if (is_wow64)
2883 access |= KEY_WOW64_64KEY;
2884
2885 /* NULL szProduct */
2886 size = MAX_PATH;
2887 state = MsiGetComponentPathA(NULL, component, path, &size);
2888 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2889 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2890
2891 /* NULL szComponent */
2892 size = MAX_PATH;
2893 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
2894 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2895 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2896
2897 size = MAX_PATH;
2898 state = MsiLocateComponentA(NULL, path, &size);
2899 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2900 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2901
2902 /* NULL lpPathBuf */
2903 size = MAX_PATH;
2904 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
2905 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2906 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2907
2908 size = MAX_PATH;
2909 state = MsiLocateComponentA(component, NULL, &size);
2910 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2911 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2912
2913 /* NULL pcchBuf */
2914 size = MAX_PATH;
2915 state = MsiGetComponentPathA(prodcode, component, path, NULL);
2916 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2917 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2918
2919 size = MAX_PATH;
2920 state = MsiLocateComponentA(component, path, NULL);
2921 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2922 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2923
2924 /* all params valid */
2925 size = MAX_PATH;
2926 state = MsiGetComponentPathA(prodcode, component, path, &size);
2927 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2928 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2929
2930 size = MAX_PATH;
2931 state = MsiLocateComponentA(component, path, &size);
2932 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2933 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2934
2935 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2936 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2937 lstrcatA(keypath, comp_squashed);
2938
2939 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2940 if (res == ERROR_ACCESS_DENIED)
2941 {
2942 skip("Not enough rights to perform tests\n");
2943 LocalFree(usersid);
2944 return;
2945 }
2946 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2947
2948 /* local system component key exists */
2949 size = MAX_PATH;
2950 state = MsiGetComponentPathA(prodcode, component, path, &size);
2951 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2952 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2953
2954 size = MAX_PATH;
2955 state = MsiLocateComponentA(component, path, &size);
2956 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2957 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2958
2959 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2960 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2961
2962 /* product value exists */
2963 path[0] = 0;
2964 size = MAX_PATH;
2965 state = MsiGetComponentPathA(prodcode, component, path, &size);
2966 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2967 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2968 ok(size == 10, "Expected 10, got %d\n", size);
2969
2970 path[0] = 0;
2971 size = MAX_PATH;
2972 state = MsiLocateComponentA(component, path, &size);
2973 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2974 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2975 ok(size == 10, "Expected 10, got %d\n", size);
2976
2977 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2978 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2979 lstrcatA(keypath, prod_squashed);
2980 lstrcatA(keypath, "\\InstallProperties");
2981
2982 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2983 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2984
2985 val = 1;
2986 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2987 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2988
2989 /* install properties key exists */
2990 path[0] = 0;
2991 size = MAX_PATH;
2992 state = MsiGetComponentPathA(prodcode, component, path, &size);
2993 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2994 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2995 ok(size == 10, "Expected 10, got %d\n", size);
2996
2997 path[0] = 0;
2998 size = MAX_PATH;
2999 state = MsiLocateComponentA(component, path, &size);
3000 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3001 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3002 ok(size == 10, "Expected 10, got %d\n", size);
3003
3004 create_file("C:\\imapath", "C:\\imapath", 11);
3005
3006 /* file exists */
3007 path[0] = 0;
3008 size = MAX_PATH;
3009 state = MsiGetComponentPathA(prodcode, component, path, &size);
3010 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3011 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3012 ok(size == 10, "Expected 10, got %d\n", size);
3013
3014 path[0] = 0;
3015 size = MAX_PATH;
3016 state = MsiLocateComponentA(component, path, &size);
3017 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3018 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3019 ok(size == 10, "Expected 10, got %d\n", size);
3020
3021 RegDeleteValueA(compkey, prod_squashed);
3022 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3023 RegDeleteValueA(installprop, "WindowsInstaller");
3024 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3025 RegCloseKey(compkey);
3026 RegCloseKey(installprop);
3027 DeleteFileA("C:\\imapath");
3028
3029 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3030 lstrcatA(keypath, "Installer\\UserData\\");
3031 lstrcatA(keypath, usersid);
3032 lstrcatA(keypath, "\\Components\\");
3033 lstrcatA(keypath, comp_squashed);
3034
3035 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3036 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3037
3038 /* user managed component key exists */
3039 size = MAX_PATH;
3040 state = MsiGetComponentPathA(prodcode, component, path, &size);
3041 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3042 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3043
3044 size = MAX_PATH;
3045 state = MsiLocateComponentA(component, path, &size);
3046 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3047 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3048
3049 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3050 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3051
3052 /* product value exists */
3053 path[0] = 0;
3054 size = MAX_PATH;
3055 state = MsiGetComponentPathA(prodcode, component, path, &size);
3056 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3057 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3058 ok(size == 10, "Expected 10, got %d\n", size);
3059
3060 path[0] = 0;
3061 size = MAX_PATH;
3062 state = MsiLocateComponentA(component, path, &size);
3063 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3064 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3065 ok(size == 10, "Expected 10, got %d\n", size);
3066
3067 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3068 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3069 lstrcatA(keypath, prod_squashed);
3070 lstrcatA(keypath, "\\InstallProperties");
3071
3072 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3073 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3074
3075 val = 1;
3076 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3077 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3078
3079 /* install properties key exists */
3080 path[0] = 0;
3081 size = MAX_PATH;
3082 state = MsiGetComponentPathA(prodcode, component, path, &size);
3083 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3084 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3085 ok(size == 10, "Expected 10, got %d\n", size);
3086
3087 path[0] = 0;
3088 size = MAX_PATH;
3089 state = MsiLocateComponentA(component, path, &size);
3090 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3091 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3092 ok(size == 10, "Expected 10, got %d\n", size);
3093
3094 create_file("C:\\imapath", "C:\\imapath", 11);
3095
3096 /* file exists */
3097 path[0] = 0;
3098 size = MAX_PATH;
3099 state = MsiGetComponentPathA(prodcode, component, path, &size);
3100 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3101 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3102 ok(size == 10, "Expected 10, got %d\n", size);
3103
3104 path[0] = 0;
3105 size = MAX_PATH;
3106 state = MsiLocateComponentA(component, path, &size);
3107 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3108 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3109 ok(size == 10, "Expected 10, got %d\n", size);
3110
3111 RegDeleteValueA(compkey, prod_squashed);
3112 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3113 RegDeleteValueA(installprop, "WindowsInstaller");
3114 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3115 RegCloseKey(compkey);
3116 RegCloseKey(installprop);
3117 DeleteFileA("C:\\imapath");
3118
3119 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3120 lstrcatA(keypath, "Installer\\Managed\\");
3121 lstrcatA(keypath, usersid);
3122 lstrcatA(keypath, "\\Installer\\Products\\");
3123 lstrcatA(keypath, prod_squashed);
3124
3125 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3126 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3127
3128 /* user managed product key exists */
3129 size = MAX_PATH;
3130 state = MsiGetComponentPathA(prodcode, component, path, &size);
3131 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3132 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3133
3134 size = MAX_PATH;
3135 state = MsiLocateComponentA(component, path, &size);
3136 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3137 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3138
3139 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3140 lstrcatA(keypath, "Installer\\UserData\\");
3141 lstrcatA(keypath, usersid);
3142 lstrcatA(keypath, "\\Components\\");
3143 lstrcatA(keypath, comp_squashed);
3144
3145 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3146 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3147
3148 /* user managed component key exists */
3149 size = MAX_PATH;
3150 state = MsiGetComponentPathA(prodcode, component, path, &size);
3151 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3152 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3153
3154 size = MAX_PATH;
3155 state = MsiLocateComponentA(component, path, &size);
3156 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3157 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3158
3159 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3160 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3161
3162 /* product value exists */
3163 path[0] = 0;
3164 size = MAX_PATH;
3165 state = MsiGetComponentPathA(prodcode, component, path, &size);
3166 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3167 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3168 ok(size == 10, "Expected 10, got %d\n", size);
3169
3170 path[0] = 0;
3171 size = MAX_PATH;
3172 state = MsiLocateComponentA(component, path, &size);
3173 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3174 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3175 ok(size == 10, "Expected 10, got %d\n", size);
3176
3177 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3178 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3179 lstrcatA(keypath, prod_squashed);
3180 lstrcatA(keypath, "\\InstallProperties");
3181
3182 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3183 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3184
3185 val = 1;
3186 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3187 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3188
3189 /* install properties key exists */
3190 path[0] = 0;
3191 size = MAX_PATH;
3192 state = MsiGetComponentPathA(prodcode, component, path, &size);
3193 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3194 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3195 ok(size == 10, "Expected 10, got %d\n", size);
3196
3197 path[0] = 0;
3198 size = MAX_PATH;
3199 state = MsiLocateComponentA(component, path, &size);
3200 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3201 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3202 ok(size == 10, "Expected 10, got %d\n", size);
3203
3204 create_file("C:\\imapath", "C:\\imapath", 11);
3205
3206 /* file exists */
3207 path[0] = 0;
3208 size = MAX_PATH;
3209 state = MsiGetComponentPathA(prodcode, component, path, &size);
3210 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3211 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3212 ok(size == 10, "Expected 10, got %d\n", size);
3213
3214 path[0] = 0;
3215 size = MAX_PATH;
3216 state = MsiLocateComponentA(component, path, &size);
3217 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3218 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3219 ok(size == 10, "Expected 10, got %d\n", size);
3220
3221 RegDeleteValueA(compkey, prod_squashed);
3222 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3223 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3224 RegDeleteValueA(installprop, "WindowsInstaller");
3225 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3226 RegCloseKey(prodkey);
3227 RegCloseKey(compkey);
3228 RegCloseKey(installprop);
3229 DeleteFileA("C:\\imapath");
3230
3231 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3232 lstrcatA(keypath, prod_squashed);
3233
3234 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3235 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3236
3237 /* user unmanaged product key exists */
3238 size = MAX_PATH;
3239 state = MsiGetComponentPathA(prodcode, component, path, &size);
3240 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3241 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3242
3243 size = MAX_PATH;
3244 state = MsiLocateComponentA(component, path, &size);
3245 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3246 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3247
3248 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3249 lstrcatA(keypath, "Installer\\UserData\\");
3250 lstrcatA(keypath, usersid);
3251 lstrcatA(keypath, "\\Components\\");
3252 lstrcatA(keypath, comp_squashed);
3253
3254 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3255 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3256
3257 /* user unmanaged component key exists */
3258 size = MAX_PATH;
3259 state = MsiGetComponentPathA(prodcode, component, path, &size);
3260 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3261 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3262
3263 size = MAX_PATH;
3264 state = MsiLocateComponentA(component, path, &size);
3265 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3266 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3267
3268 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3269 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3270
3271 /* product value exists */
3272 path[0] = 0;
3273 size = MAX_PATH;
3274 state = MsiGetComponentPathA(prodcode, component, path, &size);
3275 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3276 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3277 ok(size == 10, "Expected 10, got %d\n", size);
3278
3279 path[0] = 0;
3280 size = MAX_PATH;
3281 state = MsiLocateComponentA(component, path, &size);
3282 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3283 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3284 ok(size == 10, "Expected 10, got %d\n", size);
3285
3286 create_file("C:\\imapath", "C:\\imapath", 11);
3287
3288 /* file exists */
3289 path[0] = 0;
3290 size = MAX_PATH;
3291 state = MsiGetComponentPathA(prodcode, component, path, &size);
3292 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3293 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3294 ok(size == 10, "Expected 10, got %d\n", size);
3295
3296 path[0] = 0;
3297 size = MAX_PATH;
3298 state = MsiLocateComponentA(component, path, &size);
3299 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3300 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3301 ok(size == 10, "Expected 10, got %d\n", size);
3302
3303 RegDeleteValueA(compkey, prod_squashed);
3304 RegDeleteKeyA(prodkey, "");
3305 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3306 RegCloseKey(prodkey);
3307 RegCloseKey(compkey);
3308 DeleteFileA("C:\\imapath");
3309
3310 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3311 lstrcatA(keypath, prod_squashed);
3312
3313 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3314 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3315
3316 /* local classes product key exists */
3317 size = MAX_PATH;
3318 state = MsiGetComponentPathA(prodcode, component, path, &size);
3319 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3320 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3321
3322 size = MAX_PATH;
3323 state = MsiLocateComponentA(component, path, &size);
3324 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3325 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3326
3327 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3328 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3329 lstrcatA(keypath, comp_squashed);
3330
3331 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3332 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3333
3334 /* local user component key exists */
3335 size = MAX_PATH;
3336 state = MsiGetComponentPathA(prodcode, component, path, &size);
3337 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3338 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3339
3340 size = MAX_PATH;
3341 state = MsiLocateComponentA(component, path, &size);
3342 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3343 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3344
3345 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3346 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3347
3348 /* product value exists */
3349 path[0] = 0;
3350 size = MAX_PATH;
3351 state = MsiGetComponentPathA(prodcode, component, path, &size);
3352 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3353 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3354 ok(size == 10, "Expected 10, got %d\n", size);
3355
3356 path[0] = 0;
3357 size = MAX_PATH;
3358 state = MsiLocateComponentA(component, path, &size);
3359 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3360 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3361 ok(size == 10, "Expected 10, got %d\n", size);
3362
3363 create_file("C:\\imapath", "C:\\imapath", 11);
3364
3365 /* file exists */
3366 path[0] = 0;
3367 size = MAX_PATH;
3368 state = MsiGetComponentPathA(prodcode, component, path, &size);
3369 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3370 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3371 ok(size == 10, "Expected 10, got %d\n", size);
3372
3373 path[0] = 0;
3374 size = MAX_PATH;
3375 state = MsiLocateComponentA(component, path, &size);
3376 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3377 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3378 ok(size == 10, "Expected 10, got %d\n", size);
3379
3380 RegDeleteValueA(compkey, prod_squashed);
3381 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3382 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3383 RegCloseKey(prodkey);
3384 RegCloseKey(compkey);
3385 DeleteFileA("C:\\imapath");
3386 LocalFree(usersid);
3387 }
3388
3389 static void test_MsiGetProductCode(void)
3390 {
3391 HKEY compkey, prodkey;
3392 CHAR prodcode[MAX_PATH];
3393 CHAR prod_squashed[MAX_PATH];
3394 CHAR prodcode2[MAX_PATH];
3395 CHAR prod2_squashed[MAX_PATH];
3396 CHAR component[MAX_PATH];
3397 CHAR comp_base85[MAX_PATH];
3398 CHAR comp_squashed[MAX_PATH];
3399 CHAR keypath[MAX_PATH];
3400 CHAR product[MAX_PATH];
3401 LPSTR usersid;
3402 LONG res;
3403 UINT r;
3404 REGSAM access = KEY_ALL_ACCESS;
3405
3406 create_test_guid(prodcode, prod_squashed);
3407 create_test_guid(prodcode2, prod2_squashed);
3408 compose_base85_guid(component, comp_base85, comp_squashed);
3409 usersid = get_user_sid();
3410
3411 if (is_wow64)
3412 access |= KEY_WOW64_64KEY;
3413
3414 /* szComponent is NULL */
3415 lstrcpyA(product, "prod");
3416 r = MsiGetProductCodeA(NULL, product);
3417 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3418 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3419
3420 /* szComponent is empty */
3421 lstrcpyA(product, "prod");
3422 r = MsiGetProductCodeA("", product);
3423 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3424 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3425
3426 /* garbage szComponent */
3427 lstrcpyA(product, "prod");
3428 r = MsiGetProductCodeA("garbage", product);
3429 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3430 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3431
3432 /* guid without brackets */
3433 lstrcpyA(product, "prod");
3434 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
3435 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3436 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3437
3438 /* guid with brackets */
3439 lstrcpyA(product, "prod");
3440 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
3441 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3442 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3443
3444 /* same length as guid, but random */
3445 lstrcpyA(product, "prod");
3446 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
3447 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3448 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3449
3450 /* all params correct, szComponent not published */
3451 lstrcpyA(product, "prod");
3452 r = MsiGetProductCodeA(component, product);
3453 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3454 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3455
3456 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3457 lstrcatA(keypath, "Installer\\UserData\\");
3458 lstrcatA(keypath, usersid);
3459 lstrcatA(keypath, "\\Components\\");
3460 lstrcatA(keypath, comp_squashed);
3461
3462 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3463 if (res == ERROR_ACCESS_DENIED)
3464 {
3465 skip("Not enough rights to perform tests\n");
3466 LocalFree(usersid);
3467 return;
3468 }
3469 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3470
3471 /* user unmanaged component key exists */
3472 lstrcpyA(product, "prod");
3473 r = MsiGetProductCodeA(component, product);
3474 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3475 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3476
3477 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3478 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3479
3480 /* product value exists */
3481 lstrcpyA(product, "prod");
3482 r = MsiGetProductCodeA(component, product);
3483 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3484 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3485
3486 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3487 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3488
3489 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3490 lstrcatA(keypath, "Installer\\Managed\\");
3491 lstrcatA(keypath, usersid);
3492 lstrcatA(keypath, "\\Installer\\Products\\");
3493 lstrcatA(keypath, prod_squashed);
3494
3495 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3496 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3497
3498 /* user managed product key of first product exists */
3499 lstrcpyA(product, "prod");
3500 r = MsiGetProductCodeA(component, product);
3501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3502 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3503
3504 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3505 RegCloseKey(prodkey);
3506
3507 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3508 lstrcatA(keypath, prod_squashed);
3509
3510 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3511 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3512
3513 /* user unmanaged product key exists */
3514 lstrcpyA(product, "prod");
3515 r = MsiGetProductCodeA(component, product);
3516 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3517 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3518
3519 RegDeleteKeyA(prodkey, "");
3520 RegCloseKey(prodkey);
3521
3522 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3523 lstrcatA(keypath, prod_squashed);
3524
3525 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3526 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3527
3528 /* local classes product key exists */
3529 lstrcpyA(product, "prod");
3530 r = MsiGetProductCodeA(component, product);
3531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3532 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3533
3534 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3535 RegCloseKey(prodkey);
3536
3537 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3538 lstrcatA(keypath, "Installer\\Managed\\");
3539 lstrcatA(keypath, usersid);
3540 lstrcatA(keypath, "\\Installer\\Products\\");
3541 lstrcatA(keypath, prod2_squashed);
3542
3543 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3544 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3545
3546 /* user managed product key of second product exists */
3547 lstrcpyA(product, "prod");
3548 r = MsiGetProductCodeA(component, product);
3549 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3550 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3551
3552 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3553 RegCloseKey(prodkey);
3554 RegDeleteValueA(compkey, prod_squashed);
3555 RegDeleteValueA(compkey, prod2_squashed);
3556 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3557 RegCloseKey(compkey);
3558
3559 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3560 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3561 lstrcatA(keypath, comp_squashed);
3562
3563 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3564 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3565
3566 /* local user component key exists */
3567 lstrcpyA(product, "prod");
3568 r = MsiGetProductCodeA(component, product);
3569 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3570 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3571
3572 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3573 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3574
3575 /* product value exists */
3576 lstrcpyA(product, "prod");
3577 r = MsiGetProductCodeA(component, product);
3578 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3579 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3580
3581 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3582 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3583
3584 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3585 lstrcatA(keypath, "Installer\\Managed\\");
3586 lstrcatA(keypath, usersid);
3587 lstrcatA(keypath, "\\Installer\\Products\\");
3588 lstrcatA(keypath, prod_squashed);
3589
3590 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3591 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3592
3593 /* user managed product key of first product exists */
3594 lstrcpyA(product, "prod");
3595 r = MsiGetProductCodeA(component, product);
3596 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3597 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3598
3599 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3600 RegCloseKey(prodkey);
3601
3602 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3603 lstrcatA(keypath, prod_squashed);
3604
3605 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3606 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3607
3608 /* user unmanaged product key exists */
3609 lstrcpyA(product, "prod");
3610 r = MsiGetProductCodeA(component, product);
3611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3612 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3613
3614 RegDeleteKeyA(prodkey, "");
3615 RegCloseKey(prodkey);
3616
3617 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3618 lstrcatA(keypath, prod_squashed);
3619
3620 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3621 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3622
3623 /* local classes product key exists */
3624 lstrcpyA(product, "prod");
3625 r = MsiGetProductCodeA(component, product);
3626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3627 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3628
3629 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3630 RegCloseKey(prodkey);
3631
3632 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3633 lstrcatA(keypath, "Installer\\Managed\\");
3634 lstrcatA(keypath, usersid);
3635 lstrcatA(keypath, "\\Installer\\Products\\");
3636 lstrcatA(keypath, prod2_squashed);
3637
3638 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3639 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3640
3641 /* user managed product key of second product exists */
3642 lstrcpyA(product, "prod");
3643 r = MsiGetProductCodeA(component, product);
3644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3645 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3646
3647 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3648 RegCloseKey(prodkey);
3649 RegDeleteValueA(compkey, prod_squashed);
3650 RegDeleteValueA(compkey, prod2_squashed);
3651 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3652 RegCloseKey(compkey);
3653 LocalFree(usersid);
3654 }
3655
3656 static void test_MsiEnumClients(void)
3657 {
3658 HKEY compkey;
3659 CHAR prodcode[MAX_PATH];
3660 CHAR prod_squashed[MAX_PATH];
3661 CHAR prodcode2[MAX_PATH];
3662 CHAR prod2_squashed[MAX_PATH];
3663 CHAR component[MAX_PATH];
3664 CHAR comp_base85[MAX_PATH];
3665 CHAR comp_squashed[MAX_PATH];
3666 CHAR product[MAX_PATH];
3667 CHAR keypath[MAX_PATH];
3668 LPSTR usersid;
3669 LONG res;
3670 UINT r;
3671 REGSAM access = KEY_ALL_ACCESS;
3672
3673 create_test_guid(prodcode, prod_squashed);
3674 create_test_guid(prodcode2, prod2_squashed);
3675 compose_base85_guid(component, comp_base85, comp_squashed);
3676 usersid = get_user_sid();
3677
3678 if (is_wow64)
3679 access |= KEY_WOW64_64KEY;
3680
3681 /* NULL szComponent */
3682 product[0] = '\0';
3683 r = MsiEnumClientsA(NULL, 0, product);
3684 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3685 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3686
3687 /* empty szComponent */
3688 product[0] = '\0';
3689 r = MsiEnumClientsA("", 0, product);
3690 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3691 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3692
3693 /* NULL lpProductBuf */
3694 r = MsiEnumClientsA(component, 0, NULL);
3695 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3696
3697 /* all params correct, component missing */
3698 product[0] = '\0';
3699 r = MsiEnumClientsA(component, 0, product);
3700 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3701 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3702
3703 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3704 lstrcatA(keypath, "Installer\\UserData\\");
3705 lstrcatA(keypath, usersid);
3706 lstrcatA(keypath, "\\Components\\");
3707 lstrcatA(keypath, comp_squashed);
3708
3709 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3710 if (res == ERROR_ACCESS_DENIED)
3711 {
3712 skip("Not enough rights to perform tests\n");
3713 LocalFree(usersid);
3714 return;
3715 }
3716 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3717
3718 /* user unmanaged component key exists */
3719 product[0] = '\0';
3720 r = MsiEnumClientsA(component, 0, product);
3721 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3722 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3723
3724 /* index > 0, no products exist */
3725 product[0] = '\0';
3726 r = MsiEnumClientsA(component, 1, product);
3727 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3728 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3729
3730 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3731 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3732
3733 /* product value exists */
3734 r = MsiEnumClientsA(component, 0, product);
3735 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3736 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3737
3738 /* try index 0 again */
3739 product[0] = '\0';
3740 r = MsiEnumClientsA(component, 0, product);
3741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3742 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3743
3744 /* try index 1, second product value does not exist */
3745 product[0] = '\0';
3746 r = MsiEnumClientsA(component, 1, product);
3747 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3748 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3749
3750 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3751 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3752
3753 /* try index 1, second product value does exist */
3754 product[0] = '\0';
3755 r = MsiEnumClientsA(component, 1, product);
3756 todo_wine
3757 {
3758 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3759 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3760 }
3761
3762 /* start the enumeration over */
3763 product[0] = '\0';
3764 r = MsiEnumClientsA(component, 0, product);
3765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3766 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3767 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3768
3769 /* correctly query second product */
3770 product[0] = '\0';
3771 r = MsiEnumClientsA(component, 1, product);
3772 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3773 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3774 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3775
3776 RegDeleteValueA(compkey, prod_squashed);
3777 RegDeleteValueA(compkey, prod2_squashed);
3778 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3779 RegCloseKey(compkey);
3780
3781 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3782 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3783 lstrcatA(keypath, comp_squashed);
3784
3785 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3787
3788 /* user local component key exists */
3789 product[0] = '\0';
3790 r = MsiEnumClientsA(component, 0, product);
3791 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3792 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3793
3794 /* index > 0, no products exist */
3795 product[0] = '\0';
3796 r = MsiEnumClientsA(component, 1, product);
3797 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3798 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3799
3800 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3802
3803 /* product value exists */
3804 product[0] = '\0';
3805 r = MsiEnumClientsA(component, 0, product);
3806 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3807 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3808
3809 /* try index 0 again */
3810 product[0] = '\0';
3811 r = MsiEnumClientsA(component, 0, product);
3812 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3813
3814 /* try index 1, second product value does not exist */
3815 product[0] = '\0';
3816 r = MsiEnumClientsA(component, 1, product);
3817 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3818 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3819
3820 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3821 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3822
3823 /* try index 1, second product value does exist */
3824 product[0] = '\0';
3825 r = MsiEnumClientsA(component, 1, product);
3826 todo_wine
3827 {
3828 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3829 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3830 }
3831
3832 /* start the enumeration over */
3833 product[0] = '\0';
3834 r = MsiEnumClientsA(component, 0, product);
3835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3836 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3837 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3838
3839 /* correctly query second product */
3840 product[0] = '\0';
3841 r = MsiEnumClientsA(component, 1, product);
3842 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3843 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3844 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3845
3846 RegDeleteValueA(compkey, prod_squashed);
3847 RegDeleteValueA(compkey, prod2_squashed);
3848 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3849 RegCloseKey(compkey);
3850 LocalFree(usersid);
3851 }
3852
3853 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
3854 LPSTR *langcheck, LPDWORD langchecksz)
3855 {
3856 LPSTR version;
3857 VS_FIXEDFILEINFO *ffi;
3858 DWORD size = GetFileVersionInfoSizeA(path, NULL);
3859 USHORT *lang;
3860
3861 version = HeapAlloc(GetProcessHeap(), 0, size);
3862 GetFileVersionInfoA(path, 0, size, version);
3863
3864 VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
3865 *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3866 sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
3867 LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
3868 LOWORD(ffi->dwFileVersionLS));
3869 *verchecksz = lstrlenA(*vercheck);
3870
3871 VerQueryValueA(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
3872 *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3873 sprintf(*langcheck, "%d", *lang);
3874 *langchecksz = lstrlenA(*langcheck);
3875
3876 HeapFree(GetProcessHeap(), 0, version);
3877 }
3878
3879 static void test_MsiGetFileVersion(void)
3880 {
3881 UINT r;
3882 DWORD versz, langsz;
3883 char version[MAX_PATH];
3884 char lang[MAX_PATH];
3885 char path[MAX_PATH];
3886 LPSTR vercheck, langcheck;
3887 DWORD verchecksz, langchecksz;
3888
3889 /* NULL szFilePath */
3890 r = MsiGetFileVersionA(NULL, NULL, NULL, NULL, NULL);
3891 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3892
3893 versz = MAX_PATH;
3894 langsz = MAX_PATH;
3895 lstrcpyA(version, "version");
3896 lstrcpyA(lang, "lang");
3897 r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
3898 ok(r == ERROR_INVALID_PARAMETER,
3899 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3900 ok(!lstrcmpA(version, "version"),
3901 "Expected version to be unchanged, got %s\n", version);
3902 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3903 ok(!lstrcmpA(lang, "lang"),
3904 "Expected lang to be unchanged, got %s\n", lang);
3905 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3906
3907 /* empty szFilePath */
3908 r = MsiGetFileVersionA("", NULL, NULL, NULL, NULL);
3909 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3910
3911 versz = MAX_PATH;
3912 langsz = MAX_PATH;
3913 lstrcpyA(version, "version");
3914 lstrcpyA(lang, "lang");
3915 r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
3916 ok(r == ERROR_FILE_NOT_FOUND,
3917 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3918 ok(!lstrcmpA(version, "version"),
3919 "Expected version to be unchanged, got %s\n", version);
3920 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3921 ok(!lstrcmpA(lang, "lang"),
3922 "Expected lang to be unchanged, got %s\n", lang);
3923 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3924
3925 /* nonexistent szFilePath */
3926 versz = MAX_PATH;
3927 langsz = MAX_PATH;
3928 lstrcpyA(version, "version");
3929 lstrcpyA(lang, "lang");
3930 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3931 ok(r == ERROR_FILE_NOT_FOUND,
3932 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3933 ok(!lstrcmpA(version, "version"),
3934 "Expected version to be unchanged, got %s\n", version);
3935 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3936 ok(!lstrcmpA(lang, "lang"),
3937 "Expected lang to be unchanged, got %s\n", lang);
3938 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3939
3940 /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
3941 versz = MAX_PATH;
3942 langsz = MAX_PATH;
3943 lstrcpyA(version, "version");
3944 lstrcpyA(lang, "lang");
3945 r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
3946 ok(r == ERROR_INVALID_PARAMETER,
3947 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3948 ok(!lstrcmpA(version, "version"),
3949 "Expected version to be unchanged, got %s\n", version);
3950 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3951 ok(!lstrcmpA(lang, "lang"),
3952 "Expected lang to be unchanged, got %s\n", lang);
3953 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3954
3955 /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
3956 versz = MAX_PATH;
3957 langsz = MAX_PATH;
3958 lstrcpyA(version, "version");
3959 lstrcpyA(lang, "lang");
3960 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
3961 ok(r == ERROR_INVALID_PARAMETER,
3962 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3963 ok(!lstrcmpA(version, "version"),
3964 "Expected version to be unchanged, got %s\n", version);
3965 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3966 ok(!lstrcmpA(lang, "lang"),
3967 "Expected lang to be unchanged, got %s\n", lang);
3968 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3969
3970 /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
3971 versz = 0;
3972 langsz = MAX_PATH;
3973 lstrcpyA(version, "version");
3974 lstrcpyA(lang, "lang");
3975 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3976 ok(r == ERROR_FILE_NOT_FOUND,
3977 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3978 ok(!lstrcmpA(version, "version"),
3979 "Expected version to be unchanged, got %s\n", version);
3980 ok(versz == 0, "Expected 0, got %d\n", versz);
3981 ok(!lstrcmpA(lang, "lang"),
3982 "Expected lang to be unchanged, got %s\n", lang);
3983 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3984
3985 /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
3986 versz = MAX_PATH;
3987 langsz = 0;
3988 lstrcpyA(version, "version");
3989 lstrcpyA(lang, "lang");
3990 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3991 ok(r == ERROR_FILE_NOT_FOUND,
3992 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3993 ok(!lstrcmpA(version, "version"),
3994 "Expected version to be unchanged, got %s\n", version);
3995 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3996 ok(!lstrcmpA(lang, "lang"),
3997 "Expected lang to be unchanged, got %s\n", lang);
3998 ok(langsz == 0, "Expected 0, got %d\n", langsz);
3999
4000 /* nonexistent szFilePath, rest NULL */
4001 r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
4002 ok(r == ERROR_FILE_NOT_FOUND,
4003 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4004
4005 create_file("ver.txt", "ver.txt", 20);
4006
4007 /* file exists, no version information */
4008 r = MsiGetFileVersionA("ver.txt", NULL, NULL, NULL, NULL);
4009 ok(r == ERROR_FILE_INVALID, "Expected ERROR_FILE_INVALID, got %d\n", r);
4010
4011 versz = MAX_PATH;
4012 langsz = MAX_PATH;
4013 lstrcpyA(version, "version");
4014 lstrcpyA(lang, "lang");
4015 r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
4016 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4017 ok(!lstrcmpA(version, "version"),
4018 "Expected version to be unchanged, got %s\n", version);
4019 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4020 ok(!lstrcmpA(lang, "lang"),
4021 "Expected lang to be unchanged, got %s\n", lang);
4022 ok(r == ERROR_FILE_INVALID,
4023 "Expected ERROR_FILE_INVALID, got %d\n", r);
4024
4025 DeleteFileA("ver.txt");
4026
4027 /* relative path, has version information */
4028 versz = MAX_PATH;
4029 langsz = MAX_PATH;
4030 lstrcpyA(version, "version");
4031 lstrcpyA(lang, "lang");
4032 r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
4033 todo_wine
4034 {
4035 ok(r == ERROR_FILE_NOT_FOUND,
4036 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4037 ok(!lstrcmpA(version, "version"),
4038 "Expected version to be unchanged, got %s\n", version);
4039 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4040 ok(!lstrcmpA(lang, "lang"),
4041 "Expected lang to be unchanged, got %s\n", lang);
4042 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4043 }
4044
4045 GetSystemDirectoryA(path, MAX_PATH);
4046 lstrcatA(path, "\\kernel32.dll");
4047
4048 get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
4049
4050 /* absolute path, has version information */
4051 versz = MAX_PATH;
4052 langsz = MAX_PATH;
4053 lstrcpyA(version, "version");
4054 lstrcpyA(lang, "lang");
4055 r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
4056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4057 if (langchecksz && !langsz)
4058 {
4059 win_skip("broken MsiGetFileVersionA detected\n");
4060 HeapFree(GetProcessHeap(), 0, vercheck);
4061 HeapFree(GetProcessHeap(), 0, langcheck);
4062 return;
4063 }
4064 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4065 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4066 ok(!lstrcmpA(version, vercheck),
4067 "Expected %s, got %s\n", vercheck, version);
4068
4069 /* only check version */
4070 versz = MAX_PATH;
4071 lstrcpyA(version, "version");
4072 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4074 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4075 ok(!lstrcmpA(version, vercheck),
4076 "Expected %s, got %s\n", vercheck, version);
4077
4078 /* only check language */
4079 langsz = MAX_PATH;
4080 lstrcpyA(lang, "lang");
4081 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4083 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4084
4085 /* check neither version nor language */
4086 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4087 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4088
4089 /* get pcchVersionBuf */
4090 versz = MAX_PATH;
4091 r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
4092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4093 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4094
4095 /* get pcchLangBuf */
4096 langsz = MAX_PATH;
4097 r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
4098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4099 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4100
4101 /* pcchVersionBuf not big enough */
4102 versz = 5;
4103 lstrcpyA(version, "version");
4104 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4105 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4106 ok(!strncmp(version, vercheck, 4),
4107 "Expected first 4 characters of \"%s\", got \"%s\"\n", vercheck, version);
4108 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4109
4110 /* pcchLangBuf not big enough */
4111 langsz = 3;
4112 lstrcpyA(lang, "lang");
4113 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4114 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4115 ok(!strncmp(lang, langcheck, 2),
4116 "Expected first character of \"%s\", got \"%s\"\n", langcheck, lang);
4117 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4118
4119 /* pcchVersionBuf big enough, pcchLangBuf not big enough */
4120 versz = MAX_PATH;
4121 langsz = 0;
4122 lstrcpyA(version, "version");
4123 r = MsiGetFileVersionA(path, version, &versz, NULL, &langsz);
4124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4125 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4126 ok(!lstrcmpA(version, vercheck), "Expected \"%s\", got \"%s\"\n", vercheck, version);
4127 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4128
4129 /* pcchVersionBuf not big enough, pcchLangBuf big enough */
4130 versz = 5;
4131 langsz = MAX_PATH;
4132 lstrcpyA(lang, "lang");
4133 r = MsiGetFileVersionA(path, NULL, &versz, lang, &langsz);
4134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4135 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4136 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4137 ok(lstrcmpA(lang, "lang"), "lang buffer not modified\n");
4138
4139 /* NULL pcchVersionBuf and pcchLangBuf */
4140 r = MsiGetFileVersionA(path, version, NULL, lang, NULL);
4141 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4142
4143 /* All NULL except szFilePath */
4144 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4145 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4146
4147 HeapFree(GetProcessHeap(), 0, vercheck);
4148 HeapFree(GetProcessHeap(), 0, langcheck);
4149 }
4150
4151 static void test_MsiGetProductInfo(void)
4152 {
4153 UINT r;
4154 LONG res;
4155 HKEY propkey, source;
4156 HKEY prodkey, localkey;
4157 CHAR prodcode[MAX_PATH];
4158 CHAR prod_squashed[MAX_PATH];
4159 CHAR packcode[MAX_PATH];
4160 CHAR pack_squashed[MAX_PATH];
4161 CHAR buf[MAX_PATH];
4162 CHAR keypath[MAX_PATH];
4163 LPSTR usersid;
4164 DWORD sz, val = 42;
4165 REGSAM access = KEY_ALL_ACCESS;
4166
4167 create_test_guid(prodcode, prod_squashed);
4168 create_test_guid(packcode, pack_squashed);
4169 usersid = get_user_sid();
4170
4171 if (is_wow64)
4172 access |= KEY_WOW64_64KEY;
4173
4174 /* NULL szProduct */
4175 sz = MAX_PATH;
4176 lstrcpyA(buf, "apple");
4177 r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4178 ok(r == ERROR_INVALID_PARAMETER,
4179 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4180 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4181 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4182
4183 /* empty szProduct */
4184 sz = MAX_PATH;
4185 lstrcpyA(buf, "apple");
4186 r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4187 ok(r == ERROR_INVALID_PARAMETER,
4188 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4189 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4190 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4191
4192 /* garbage szProduct */
4193 sz = MAX_PATH;
4194 lstrcpyA(buf, "apple");
4195 r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4196 ok(r == ERROR_INVALID_PARAMETER,
4197 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4198 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4199 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4200
4201 /* guid without brackets */
4202 sz = MAX_PATH;
4203 lstrcpyA(buf, "apple");
4204 r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
4205 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4206 ok(r == ERROR_INVALID_PARAMETER,
4207 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4208 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4209 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4210
4211 /* guid with brackets */
4212 sz = MAX_PATH;
4213 lstrcpyA(buf, "apple");
4214 r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
4215 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4216 ok(r == ERROR_UNKNOWN_PRODUCT,
4217 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4218 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4219 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4220
4221 /* same length as guid, but random */
4222 sz = MAX_PATH;
4223 lstrcpyA(buf, "apple");
4224 r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
4225 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4226 ok(r == ERROR_INVALID_PARAMETER,
4227 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4228 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4229 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4230
4231 /* not installed, NULL szAttribute */
4232 sz = MAX_PATH;
4233 lstrcpyA(buf, "apple");
4234 r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
4235 ok(r == ERROR_INVALID_PARAMETER,
4236 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4237 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4238 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4239
4240 /* not installed, NULL lpValueBuf */
4241 sz = MAX_PATH;
4242 lstrcpyA(buf, "apple");
4243 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4244 ok(r == ERROR_UNKNOWN_PRODUCT,
4245 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4246 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4247 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4248
4249 /* not installed, NULL pcchValueBuf */
4250 sz = MAX_PATH;
4251 lstrcpyA(buf, "apple");
4252 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, NULL);
4253 ok(r == ERROR_INVALID_PARAMETER,
4254 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4255 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4256 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4257
4258 /* created guid cannot possibly be an installed product code */
4259 sz = MAX_PATH;
4260 lstrcpyA(buf, "apple");
4261 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4262 ok(r == ERROR_UNKNOWN_PRODUCT,
4263 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4264 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4265 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4266
4267 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4268 lstrcatA(keypath, usersid);
4269 lstrcatA(keypath, "\\Installer\\Products\\");
4270 lstrcatA(keypath, prod_squashed);
4271
4272 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4273 if (res == ERROR_ACCESS_DENIED)
4274 {
4275 skip("Not enough rights to perform tests\n");
4276 LocalFree(usersid);
4277 return;
4278 }
4279 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4280
4281 /* managed product code exists */
4282 sz = MAX_PATH;
4283 lstrcpyA(buf, "apple");
4284 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4285 ok(r == ERROR_UNKNOWN_PROPERTY,
4286 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4287 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4288 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4289
4290 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4291 RegCloseKey(prodkey);
4292
4293 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4294 lstrcatA(keypath, usersid);
4295 lstrcatA(keypath, "\\Products\\");
4296 lstrcatA(keypath, prod_squashed);
4297
4298 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4299 if (res == ERROR_ACCESS_DENIED)
4300 {
4301 skip("Not enough rights to perform tests\n");
4302 LocalFree(usersid);
4303 return;
4304 }
4305 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4306
4307 /* local user product code exists */
4308 sz = MAX_PATH;
4309 lstrcpyA(buf, "apple");
4310 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4311 ok(r == ERROR_UNKNOWN_PRODUCT,
4312 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4313 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4314 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4315
4316 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4317 lstrcatA(keypath, usersid);
4318 lstrcatA(keypath, "\\Installer\\Products\\");
4319 lstrcatA(keypath, prod_squashed);
4320
4321 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4322 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4323
4324 /* both local and managed product code exist */
4325 sz = MAX_PATH;
4326 lstrcpyA(buf, "apple");
4327 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4328 ok(r == ERROR_UNKNOWN_PROPERTY,
4329 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4330 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4331 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4332
4333 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4334 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4335
4336 /* InstallProperties key exists */
4337 sz = MAX_PATH;
4338 lstrcpyA(buf, "apple");
4339 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4341 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4342 ok(sz == 0, "Expected 0, got %d\n", sz);
4343
4344 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4345 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4346
4347 /* HelpLink value exists */
4348 sz = MAX_PATH;
4349 lstrcpyA(buf, "apple");
4350 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4351 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4352 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4353 ok(sz == 4, "Expected 4, got %d\n", sz);
4354
4355 /* pcchBuf is NULL */
4356 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, NULL);
4357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4358
4359 /* lpValueBuf is NULL */
4360 sz = MAX_PATH;
4361 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4363 ok(sz == 4, "Expected 4, got %d\n", sz);
4364
4365 /* lpValueBuf is NULL, pcchValueBuf is too small */
4366 sz = 2;
4367 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4369 ok(sz == 4, "Expected 4, got %d\n", sz);
4370
4371 /* lpValueBuf is non-NULL, pcchValueBuf is too small */
4372 sz = 2;
4373 lstrcpyA(buf, "apple");
4374 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4375 ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
4376 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4377 ok(sz == 4, "Expected 4, got %d\n", sz);
4378
4379 /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
4380 sz = 4;
4381 lstrcpyA(buf, "apple");
4382 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4383 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4384 ok(!lstrcmpA(buf, "apple"),
4385 "Expected buf to remain unchanged, got \"%s\"\n", buf);
4386 ok(sz == 4, "Expected 4, got %d\n", sz);
4387
4388 res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
4389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4390
4391 /* random property not supported by MSI, value exists */
4392 sz = MAX_PATH;
4393 lstrcpyA(buf, "apple");
4394 r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
4395 ok(r == ERROR_UNKNOWN_PROPERTY,
4396 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4397 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4398 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4399
4400 RegDeleteValueA(propkey, "IMadeThis");
4401 RegDeleteValueA(propkey, "HelpLink");
4402 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4403 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4404 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4405 RegCloseKey(propkey);
4406 RegCloseKey(localkey);
4407 RegCloseKey(prodkey);
4408
4409 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4410 lstrcatA(keypath, prod_squashed);
4411
4412 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4414
4415 /* user product key exists */
4416 sz = MAX_PATH;
4417 lstrcpyA(buf, "apple");
4418 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4419 ok(r == ERROR_UNKNOWN_PROPERTY,
4420 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4421 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4422 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4423
4424 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4425 lstrcatA(keypath, usersid);
4426 lstrcatA(keypath, "\\Products\\");
4427 lstrcatA(keypath, prod_squashed);
4428
4429 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4430 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4431
4432 /* local user product key exists */
4433 sz = MAX_PATH;
4434 lstrcpyA(buf, "apple");
4435 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4436 ok(r == ERROR_UNKNOWN_PROPERTY,
4437 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4438 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4439 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4440
4441 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4442 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4443
4444 /* InstallProperties key exists */
4445 sz = MAX_PATH;
4446 lstrcpyA(buf, "apple");
4447 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, 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, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4453 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4454
4455 /* HelpLink value exists */
4456 sz = MAX_PATH;
4457 lstrcpyA(buf, "apple");
4458 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4459 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4460 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4461 ok(sz == 4, "Expected 4, got %d\n", sz);
4462
4463 RegDeleteValueA(propkey, "HelpLink");
4464 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4465 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4466 RegDeleteKeyA(prodkey, "");
4467 RegCloseKey(propkey);
4468 RegCloseKey(localkey);
4469 RegCloseKey(prodkey);
4470
4471 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
4472 lstrcatA(keypath, prod_squashed);
4473
4474 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4475 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4476
4477 /* classes product key exists */
4478 sz = MAX_PATH;
4479 lstrcpyA(buf, "apple");
4480 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4481 ok(r == ERROR_UNKNOWN_PROPERTY,
4482 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4483 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4484 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4485
4486 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4487 lstrcatA(keypath, usersid);
4488 lstrcatA(keypath, "\\Products\\");
4489 lstrcatA(keypath, prod_squashed);
4490
4491 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4492 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4493
4494 /* local user product key exists */
4495 sz = MAX_PATH;
4496 lstrcpyA(buf, "apple");
4497 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4498 ok(r == ERROR_UNKNOWN_PROPERTY,
4499 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4500 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4501 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4502
4503 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4504 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4505
4506 /* InstallProperties key exists */
4507 sz = MAX_PATH;
4508 lstrcpyA(buf, "apple");
4509 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4510 ok(r == ERROR_UNKNOWN_PROPERTY,
4511 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4512 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4513 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4514
4515 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4516 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4517 RegCloseKey(propkey);
4518 RegCloseKey(localkey);
4519
4520 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4521 lstrcatA(keypath, "S-1-5-18\\\\Products\\");
4522 lstrcatA(keypath, prod_squashed);
4523
4524 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4526
4527 /* Local System product key exists */
4528 sz = MAX_PATH;
4529 lstrcpyA(buf, "apple");
4530 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4531 ok(r == ERROR_UNKNOWN_PROPERTY,
4532 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4533 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4534 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4535
4536 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4537 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4538
4539 /* InstallProperties key exists */
4540 sz = MAX_PATH;
4541 lstrcpyA(buf, "apple");
4542 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4544 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4545 ok(sz == 0, "Expected 0, got %d\n", sz);
4546
4547 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4548 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4549
4550 /* HelpLink value exists */
4551 sz = MAX_PATH;
4552 lstrcpyA(buf, "apple");
4553 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4555 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4556 ok(sz == 4, "Expected 4, got %d\n", sz);
4557
4558 res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
4559 (const BYTE *)&val, sizeof(DWORD));
4560 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4561
4562 /* HelpLink type is REG_DWORD */
4563 sz = MAX_PATH;
4564 lstrcpyA(buf, "apple");
4565 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4567 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4568 ok(sz == 2, "Expected 2, got %d\n", sz);
4569
4570 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4571 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4572
4573 /* DisplayName value exists */
4574 sz = MAX_PATH;
4575 lstrcpyA(buf, "apple");
4576 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
4577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4578 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4579 ok(sz == 4, "Expected 4, got %d\n", sz);
4580
4581 res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
4582 (const BYTE *)&val, sizeof(DWORD));
4583 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4584
4585 /* DisplayName type is REG_DWORD */
4586 sz = MAX_PATH;
4587 lstrcpyA(buf, "apple");
4588 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
4589 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4590 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4591 ok(sz == 2, "Expected 2, got %d\n", sz);
4592
4593 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
4594 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4595
4596 /* DisplayVersion value exists */
4597 sz = MAX_PATH;
4598 lstrcpyA(buf, "apple");
4599 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
4600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4601 ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
4602 ok(sz == 5, "Expected 5, got %d\n", sz);
4603
4604 res = RegSetValueExA(propkey, "DisplayVersion", 0,
4605 REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
4606 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4607
4608 /* DisplayVersion type is REG_DWORD */
4609 sz = MAX_PATH;
4610 lstrcpyA(buf, "apple");
4611 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
4612 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4613 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4614 ok(sz == 2, "Expected 2, got %d\n", sz);
4615
4616 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
4617 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4618
4619 /* HelpTelephone value exists */
4620 sz = MAX_PATH;
4621 lstrcpyA(buf, "apple");
4622 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
4623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4624 ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
4625 ok(sz == 4, "Expected 4, got %d\n", sz);
4626
4627 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
4628 (const BYTE *)&val, sizeof(DWORD));
4629 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4630
4631 /* HelpTelephone type is REG_DWORD */
4632 sz = MAX_PATH;
4633 lstrcpyA(buf, "apple");
4634 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
4635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4636 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4637 ok(sz == 2, "Expected 2, got %d\n", sz);
4638
4639 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4640 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4641
4642 /* InstallLocation value exists */
4643 sz = MAX_PATH;
4644 lstrcpyA(buf, "apple");
4645 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
4646 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4647 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4648 ok(sz == 3, "Expected 3, got %d\n", sz);
4649
4650 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
4651 (const BYTE *)&val, sizeof(DWORD));
4652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4653
4654 /* InstallLocation type is REG_DWORD */
4655 sz = MAX_PATH;
4656 lstrcpyA(buf, "apple");
4657 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
4658 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4659 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4660 ok(sz == 2, "Expected 2, got %d\n", sz);
4661
4662 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4664
4665 /* InstallSource value exists */
4666 sz = MAX_PATH;
4667 lstrcpyA(buf, "apple");
4668 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
4669 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4670 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4671 ok(sz == 6, "Expected 6, got %d\n", sz);
4672
4673 res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
4674 (const BYTE *)&val, sizeof(DWORD));
4675 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4676
4677 /* InstallSource type is REG_DWORD */
4678 sz = MAX_PATH;
4679 lstrcpyA(buf, "apple");
4680 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
4681 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4682 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4683 ok(sz == 2, "Expected 2, got %d\n", sz);
4684
4685 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4686 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4687
4688 /* InstallDate value exists */
4689 sz = MAX_PATH;
4690 lstrcpyA(buf, "apple");
4691 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
4692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4693 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4694 ok(sz == 4, "Expected 4, got %d\n", sz);
4695
4696 res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
4697 (const BYTE *)&val, sizeof(DWORD));
4698 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4699
4700 /* InstallDate type is REG_DWORD */
4701 sz = MAX_PATH;
4702 lstrcpyA(buf, "apple");
4703 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
4704 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4705 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4706 ok(sz == 2, "Expected 2, got %d\n", sz);
4707
4708 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4709 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4710
4711 /* Publisher value exists */
4712 sz = MAX_PATH;
4713 lstrcpyA(buf, "apple");
4714 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHERA, buf, &sz);
4715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4716 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4717 ok(sz == 3, "Expected 3, got %d\n", sz);
4718
4719 res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
4720 (const BYTE *)&val, sizeof(DWORD));
4721 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4722
4723 /* Publisher type is REG_DWORD */
4724 sz = MAX_PATH;
4725 lstrcpyA(buf, "apple");
4726 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHERA, buf, &sz);
4727 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4728 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4729 ok(sz == 2, "Expected 2, got %d\n", sz);
4730
4731 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
4732 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4733
4734 /* LocalPackage value exists */
4735 sz = MAX_PATH;
4736 lstrcpyA(buf, "apple");
4737 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
4738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4739 ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
4740 ok(sz == 4, "Expected 4, got %d\n", sz);
4741
4742 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
4743 (const BYTE *)&val, sizeof(DWORD));
4744 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4745
4746 /* LocalPackage type is REG_DWORD */
4747 sz = MAX_PATH;
4748 lstrcpyA(buf, "apple");
4749 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
4750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4751 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4752 ok(sz == 2, "Expected 2, got %d\n", sz);
4753
4754 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4755 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4756
4757 /* UrlInfoAbout value exists */
4758 sz = MAX_PATH;
4759 lstrcpyA(buf, "apple");
4760 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
4761 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4762 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4763 ok(sz == 5, "Expected 5, got %d\n", sz);
4764
4765 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
4766 (const BYTE *)&val, sizeof(DWORD));
4767 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4768
4769 /* UrlInfoAbout type is REG_DWORD */
4770 sz = MAX_PATH;
4771 lstrcpyA(buf, "apple");
4772 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
4773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4774 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4775 ok(sz == 2, "Expected 2, got %d\n", sz);
4776
4777 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
4778 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4779
4780 /* UrlUpdateInfo value exists */
4781 sz = MAX_PATH;
4782 lstrcpyA(buf, "apple");
4783 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
4784 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4785 ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
4786 ok(sz == 4, "Expected 4, got %d\n", sz);
4787
4788 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
4789 (const BYTE *)&val, sizeof(DWORD));
4790 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4791
4792 /* UrlUpdateInfo type is REG_DWORD */
4793 sz = MAX_PATH;
4794 lstrcpyA(buf, "apple");
4795 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
4796 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4797 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4798 ok(sz == 2, "Expected 2, got %d\n", sz);
4799
4800 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
4801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4802
4803 /* VersionMinor value exists */
4804 sz = MAX_PATH;
4805 lstrcpyA(buf, "apple");
4806 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
4807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4808 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4809 ok(sz == 1, "Expected 1, got %d\n", sz);
4810
4811 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
4812 (const BYTE *)&val, sizeof(DWORD));
4813 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4814
4815 /* VersionMinor type is REG_DWORD */
4816 sz = MAX_PATH;
4817 lstrcpyA(buf, "apple");
4818 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
4819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4820 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4821 ok(sz == 2, "Expected 2, got %d\n", sz);
4822
4823 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
4824 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4825
4826 /* VersionMajor value exists */
4827 sz = MAX_PATH;
4828 lstrcpyA(buf, "apple");
4829 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
4830 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4831 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4832 ok(sz == 1, "Expected 1, got %d\n", sz);
4833
4834 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
4835 (const BYTE *)&val, sizeof(DWORD));
4836 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4837
4838 /* VersionMajor type is REG_DWORD */
4839 sz = MAX_PATH;
4840 lstrcpyA(buf, "apple");
4841 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
4842 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4843 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4844 ok(sz == 2, "Expected 2, got %d\n", sz);
4845
4846 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4847 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4848
4849 /* ProductID value exists */
4850 sz = MAX_PATH;
4851 lstrcpyA(buf, "apple");
4852 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
4853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4854 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4855 ok(sz == 2, "Expected 2, got %d\n", sz);
4856
4857 res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
4858 (const BYTE *)&val, sizeof(DWORD));
4859 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4860
4861 /* ProductID type is REG_DWORD */
4862 sz = MAX_PATH;
4863 lstrcpyA(buf, "apple");
4864 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
4865 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4866 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4867 ok(sz == 2, "Expected 2, got %d\n", sz);
4868
4869 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4870 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4871
4872 /* RegCompany value exists */
4873 sz = MAX_PATH;
4874 lstrcpyA(buf, "apple");
4875 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
4876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4877 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4878 ok(sz == 4, "Expected 4, got %d\n", sz);
4879
4880 res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
4881 (const BYTE *)&val, sizeof(DWORD));
4882 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4883
4884 /* RegCompany type is REG_DWORD */
4885 sz = MAX_PATH;
4886 lstrcpyA(buf, "apple");
4887 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
4888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4889 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4890 ok(sz == 2, "Expected 2, got %d\n", sz);
4891
4892 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
4893 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4894
4895 /* RegOwner value exists */
4896 sz = MAX_PATH;
4897 lstrcpyA(buf, "apple");
4898 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNERA, buf, &sz);
4899 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4900 ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
4901 ok(sz == 3, "Expected 3, got %d\n", sz);
4902
4903 res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
4904 (const BYTE *)&val, sizeof(DWORD));
4905 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4906
4907 /* RegOwner type is REG_DWORD */
4908 sz = MAX_PATH;
4909 lstrcpyA(buf, "apple");
4910 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNERA, buf, &sz);
4911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4912 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4913 ok(sz == 2, "Expected 2, got %d\n", sz);
4914
4915 res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
4916 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4917
4918 /* InstanceType value exists */
4919 sz = MAX_PATH;
4920 lstrcpyA(buf, "apple");
4921 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
4922 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4923 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4924 ok(sz == 0, "Expected 0, got %d\n", sz);
4925
4926 res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
4927 (const BYTE *)&val, sizeof(DWORD));
4928 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4929
4930 /* InstanceType type is REG_DWORD */
4931 sz = MAX_PATH;
4932 lstrcpyA(buf, "apple");
4933 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
4934 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4935 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4936 ok(sz == 0, "Expected 0, got %d\n", sz);
4937
4938 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
4939 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4940
4941 /* InstanceType value exists */
4942 sz = MAX_PATH;
4943 lstrcpyA(buf, "apple");
4944 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
4945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4946 ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
4947 ok(sz == 4, "Expected 4, got %d\n", sz);
4948
4949 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
4950 (const BYTE *)&val, sizeof(DWORD));
4951 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4952
4953 /* InstanceType type is REG_DWORD */
4954 sz = MAX_PATH;
4955 lstrcpyA(buf, "apple");
4956 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
4957 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4958 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4959 ok(sz == 2, "Expected 2, got %d\n", sz);
4960
4961 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
4962 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4963
4964 /* Transforms value exists */
4965 sz = MAX_PATH;
4966 lstrcpyA(buf, "apple");
4967 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
4968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4969 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4970 ok(sz == 0, "Expected 0, got %d\n", sz);
4971
4972 res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
4973 (const BYTE *)&val, sizeof(DWORD));
4974 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4975
4976 /* Transforms type is REG_DWORD */
4977 sz = MAX_PATH;
4978 lstrcpyA(buf, "apple");
4979 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
4980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4981 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4982 ok(sz == 0, "Expected 0, got %d\n", sz);
4983
4984 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
4985 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4986
4987 /* Transforms value exists */
4988 sz = MAX_PATH;
4989 lstrcpyA(buf, "apple");
4990 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
4991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4992 ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
4993 ok(sz == 6, "Expected 6, got %d\n", sz);
4994
4995 res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
4996 (const BYTE *)&val, sizeof(DWORD));
4997 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4998
4999 /* Transforms type is REG_DWORD */
5000 sz = MAX_PATH;
5001 lstrcpyA(buf, "apple");
5002 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5004 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5005 ok(sz == 2, "Expected 2, got %d\n", sz);
5006
5007 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5008 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5009
5010 /* Language value exists */
5011 sz = MAX_PATH;
5012 lstrcpyA(buf, "apple");
5013 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5015 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5016 ok(sz == 0, "Expected 0, got %d\n", sz);
5017
5018 res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
5019 (const BYTE *)&val, sizeof(DWORD));
5020 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5021
5022 /* Language type is REG_DWORD */
5023 sz = MAX_PATH;
5024 lstrcpyA(buf, "apple");
5025 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5026 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5027 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5028 ok(sz == 0, "Expected 0, got %d\n", sz);
5029
5030 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5031 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5032
5033 /* Language value exists */
5034 sz = MAX_PATH;
5035 lstrcpyA(buf, "apple");
5036 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5038 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5039 ok(sz == 4, "Expected 4, got %d\n", sz);
5040
5041 res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
5042 (const BYTE *)&val, sizeof(DWORD));
5043 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5044
5045 /* Language type is REG_DWORD */
5046 sz = MAX_PATH;
5047 lstrcpyA(buf, "apple");
5048 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5050 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5051 ok(sz == 2, "Expected 2, got %d\n", sz);
5052
5053 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5055
5056 /* ProductName value exists */
5057 sz = MAX_PATH;
5058 lstrcpyA(buf, "apple");
5059 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5061 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5062 ok(sz == 0, "Expected 0, got %d\n", sz);
5063
5064 res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
5065 (const BYTE *)&val, sizeof(DWORD));
5066 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5067
5068 /* ProductName type is REG_DWORD */
5069 sz = MAX_PATH;
5070 lstrcpyA(buf, "apple");
5071 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5073 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5074 ok(sz == 0, "Expected 0, got %d\n", sz);
5075
5076 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5077 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5078
5079 /* ProductName value exists */
5080 sz = MAX_PATH;
5081 lstrcpyA(buf, "apple");
5082 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5084 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5085 ok(sz == 4, "Expected 4, got %d\n", sz);
5086
5087 res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
5088 (const BYTE *)&val, sizeof(DWORD));
5089 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5090
5091 /* ProductName type is REG_DWORD */
5092 sz = MAX_PATH;
5093 lstrcpyA(buf, "apple");
5094 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5096 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5097 ok(sz == 2, "Expected 2, got %d\n", sz);
5098
5099 res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5100 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5101
5102 /* Assignment value exists */
5103 sz = MAX_PATH;
5104 lstrcpyA(buf, "apple");
5105 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5106 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5107 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5108 ok(sz == 0, "Expected 0, got %d\n", sz);
5109
5110 res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
5111 (const BYTE *)&val, sizeof(DWORD));
5112 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5113
5114 /* Assignment type is REG_DWORD */
5115 sz = MAX_PATH;
5116 lstrcpyA(buf, "apple");
5117 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5118 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5119 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5120 ok(sz == 0, "Expected 0, got %d\n", sz);
5121
5122 res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5123 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5124
5125 /* Assignment value exists */
5126 sz = MAX_PATH;
5127 lstrcpyA(buf, "apple");
5128 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5130 ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
5131 ok(sz == 2, "Expected 2, got %d\n", sz);
5132
5133 res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
5134 (const BYTE *)&val, sizeof(DWORD));
5135 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5136
5137 /* Assignment type is REG_DWORD */
5138 sz = MAX_PATH;
5139 lstrcpyA(buf, "apple");
5140 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5142 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5143 ok(sz == 2, "Expected 2, got %d\n", sz);
5144
5145 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5146 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5147
5148 /* PackageCode value exists */
5149 sz = MAX_PATH;
5150 lstrcpyA(buf, "apple");
5151 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5152 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5153 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5154 ok(sz == 0, "Expected 0, got %d\n", sz);
5155
5156 res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
5157 (const BYTE *)&val, sizeof(DWORD));
5158 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5159
5160 /* PackageCode type is REG_DWORD */
5161 sz = MAX_PATH;
5162 lstrcpyA(buf, "apple");
5163 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5165 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5166 ok(sz == 0, "Expected 0, got %d\n", sz);
5167
5168 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5169 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5170
5171 /* PackageCode value exists */
5172 sz = MAX_PATH;
5173 lstrcpyA(buf, "apple");
5174 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5175 ok(r == ERROR_BAD_CONFIGURATION,
5176 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5177 ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
5178 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5179
5180 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
5181 (const BYTE *)&val, sizeof(DWORD));
5182 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5183
5184 /* PackageCode type is REG_DWORD */
5185 sz = MAX_PATH;
5186 lstrcpyA(buf, "apple");
5187 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5188 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5189 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5190 ok(sz == 2, "Expected 2, got %d\n", sz);
5191
5192 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
5193 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5194
5195 /* PackageCode value exists */
5196 sz = MAX_PATH;
5197 lstrcpyA(buf, "apple");
5198 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5199 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5200 ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
5201 ok(sz == 38, "Expected 38, got %d\n", sz);
5202
5203 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5204 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5205
5206 /* Version value exists */
5207 sz = MAX_PATH;
5208 lstrcpyA(buf, "apple");
5209 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5211 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5212 ok(sz == 0, "Expected 0, got %d\n", sz);
5213
5214 res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
5215 (const BYTE *)&val, sizeof(DWORD));
5216 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5217
5218 /* Version type is REG_DWORD */
5219 sz = MAX_PATH;
5220 lstrcpyA(buf, "apple");
5221 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5223 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5224 ok(sz == 0, "Expected 0, got %d\n", sz);
5225
5226 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5227 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5228
5229 /* Version value exists */
5230 sz = MAX_PATH;
5231 lstrcpyA(buf, "apple");
5232 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5234 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5235 ok(sz == 3, "Expected 3, got %d\n", sz);
5236
5237 res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
5238 (const BYTE *)&val, sizeof(DWORD));
5239 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5240
5241 /* Version type is REG_DWORD */
5242 sz = MAX_PATH;
5243 lstrcpyA(buf, "apple");
5244 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5246 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5247 ok(sz == 2, "Expected 2, got %d\n", sz);
5248
5249 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5251
5252 /* ProductIcon value exists */
5253 sz = MAX_PATH;
5254 lstrcpyA(buf, "apple");
5255 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5256 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5257 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5258 ok(sz == 0, "Expected 0, got %d\n", sz);
5259
5260 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
5261 (const BYTE *)&val, sizeof(DWORD));
5262 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5263
5264 /* ProductIcon type is REG_DWORD */
5265 sz = MAX_PATH;
5266 lstrcpyA(buf, "apple");
5267 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5269 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5270 ok(sz == 0, "Expected 0, got %d\n", sz);
5271
5272 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5273 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5274
5275 /* ProductIcon value exists */
5276 sz = MAX_PATH;
5277 lstrcpyA(buf, "apple");
5278 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5279 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5280 ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
5281 ok(sz == 3, "Expected 3, got %d\n", sz);
5282
5283 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
5284 (const BYTE *)&val, sizeof(DWORD));
5285 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5286
5287 /* ProductIcon type is REG_DWORD */
5288 sz = MAX_PATH;
5289 lstrcpyA(buf, "apple");
5290 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5292 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5293 ok(sz == 2, "Expected 2, got %d\n", sz);
5294
5295 /* SourceList key does not exist */
5296 sz = MAX_PATH;
5297 lstrcpyA(buf, "apple");
5298 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5299 ok(r == ERROR_UNKNOWN_PRODUCT,
5300 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5301 ok(!lstrcmpA(buf, "apple"),
5302 "Expected buf to be unchanged, got \"%s\"\n", buf);
5303 ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
5304
5305 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
5306 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5307
5308 /* SourceList key exists, but PackageName val does not exist */
5309 sz = MAX_PATH;
5310 lstrcpyA(buf, "apple");
5311 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5313 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5314 ok(sz == 0, "Expected 0, got %d\n", sz);
5315
5316 res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
5317 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5318
5319 /* PackageName val exists */
5320 sz = MAX_PATH;
5321 lstrcpyA(buf, "apple");
5322 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5324 ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
5325 ok(sz == 8, "Expected 8, got %d\n", sz);
5326
5327 res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
5328 (const BYTE *)&val, sizeof(DWORD));
5329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5330
5331 /* PackageName type is REG_DWORD */
5332 sz = MAX_PATH;
5333 lstrcpyA(buf, "apple");
5334 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5336 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5337 ok(sz == 2, "Expected 2, got %d\n", sz);
5338
5339 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5340 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5341
5342 /* Authorized value exists */
5343 sz = MAX_PATH;
5344 lstrcpyA(buf, "apple");
5345 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5346 if (r != ERROR_UNKNOWN_PROPERTY)
5347 {
5348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5349 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5350 ok(sz == 0, "Expected 0, got %d\n", sz);
5351 }
5352
5353 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
5354 (const BYTE *)&val, sizeof(DWORD));
5355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5356
5357 /* AuthorizedLUAApp type is REG_DWORD */
5358 sz = MAX_PATH;
5359 lstrcpyA(buf, "apple");
5360 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5361 if (r != ERROR_UNKNOWN_PROPERTY)
5362 {
5363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5364 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5365 ok(sz == 0, "Expected 0, got %d\n", sz);
5366 }
5367
5368 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5369 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5370
5371 /* Authorized value exists */
5372 sz = MAX_PATH;
5373 lstrcpyA(buf, "apple");
5374 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5375 if (r != ERROR_UNKNOWN_PROPERTY)
5376 {
5377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5378 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5379 ok(sz == 4, "Expected 4, got %d\n", sz);
5380 }
5381
5382 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
5383 (const BYTE *)&val, sizeof(DWORD));
5384 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5385
5386 /* AuthorizedLUAApp type is REG_DWORD */
5387 sz = MAX_PATH;
5388 lstrcpyA(buf, "apple");
5389 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5390 if (r != ERROR_UNKNOWN_PROPERTY)
5391 {
5392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5393 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5394 ok(sz == 2, "Expected 2, got %d\n", sz);
5395 }
5396
5397 RegDeleteValueA(propkey, "HelpLink");
5398 RegDeleteValueA(propkey, "DisplayName");
5399 RegDeleteValueA(propkey, "DisplayVersion");
5400 RegDeleteValueA(propkey, "HelpTelephone");
5401 RegDeleteValueA(propkey, "InstallLocation");
5402 RegDeleteValueA(propkey, "InstallSource");
5403 RegDeleteValueA(propkey, "InstallDate");
5404 RegDeleteValueA(propkey, "Publisher");
5405 RegDeleteValueA(propkey, "LocalPackage");
5406 RegDeleteValueA(propkey, "UrlInfoAbout");
5407 RegDeleteValueA(propkey, "UrlUpdateInfo");
5408 RegDeleteValueA(propkey, "VersionMinor");
5409 RegDeleteValueA(propkey, "VersionMajor");
5410 RegDeleteValueA(propkey, "ProductID");
5411 RegDeleteValueA(propkey, "RegCompany");
5412 RegDeleteValueA(propkey, "RegOwner");
5413 RegDeleteValueA(propkey, "InstanceType");
5414 RegDeleteValueA(propkey, "Transforms");
5415 RegDeleteValueA(propkey, "Language");
5416 RegDeleteValueA(propkey, "ProductName");
5417 RegDeleteValueA(propkey, "Assignment");
5418 RegDeleteValueA(propkey, "PackageCode");
5419 RegDeleteValueA(propkey, "Version");
5420 RegDeleteValueA(propkey, "ProductIcon");
5421 RegDeleteValueA(propkey, "AuthorizedLUAApp");
5422 delete_key(propkey, "", access & KEY_WOW64_64KEY);
5423 delete_key(localkey, "", access & KEY_WOW64_64KEY);
5424 RegDeleteValueA(prodkey, "InstanceType");
5425 RegDeleteValueA(prodkey, "Transforms");
5426 RegDeleteValueA(prodkey, "Language");
5427 RegDeleteValueA(prodkey, "ProductName");
5428 RegDeleteValueA(prodkey, "Assignment");
5429 RegDeleteValueA(prodkey, "PackageCode");
5430 RegDeleteValueA(prodkey, "Version");
5431 RegDeleteValueA(prodkey, "ProductIcon");
5432 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5433 RegDeleteValueA(source, "PackageName");
5434 delete_key(source, "", access & KEY_WOW64_64KEY);
5435 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5436 RegCloseKey(propkey);
5437 RegCloseKey(localkey);
5438 RegCloseKey(source);
5439 RegCloseKey(prodkey);
5440 LocalFree(usersid);
5441 }
5442
5443 static void test_MsiGetProductInfoEx(void)
5444 {
5445 UINT r;
5446 LONG res;
5447 HKEY propkey, userkey;
5448 HKEY prodkey, localkey;
5449 CHAR prodcode[MAX_PATH];
5450 CHAR prod_squashed[MAX_PATH];
5451 CHAR packcode[MAX_PATH];
5452 CHAR pack_squashed[MAX_PATH];
5453 CHAR buf[MAX_PATH];
5454 CHAR keypath[MAX_PATH];
5455 LPSTR usersid;
5456 DWORD sz;
5457 REGSAM access = KEY_ALL_ACCESS;
5458
5459 if (!pMsiGetProductInfoExA)
5460 {
5461 win_skip("MsiGetProductInfoExA is not available\n");
5462 return;
5463 }
5464
5465 create_test_guid(prodcode, prod_squashed);
5466 create_test_guid(packcode, pack_squashed);
5467 usersid = get_user_sid();
5468
5469 if (is_wow64)
5470 access |= KEY_WOW64_64KEY;
5471
5472 /* NULL szProductCode */
5473 sz = MAX_PATH;
5474 lstrcpyA(buf, "apple");
5475 r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5476 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5477 ok(r == ERROR_INVALID_PARAMETER,
5478 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5479 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5480 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5481
5482 /* empty szProductCode */
5483 sz = MAX_PATH;
5484 lstrcpyA(buf, "apple");
5485 r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5486 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5487 ok(r == ERROR_INVALID_PARAMETER,
5488 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5489 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5490 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5491
5492 /* garbage szProductCode */
5493 sz = MAX_PATH;
5494 lstrcpyA(buf, "apple");
5495 r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5496 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5497 ok(r == ERROR_INVALID_PARAMETER,
5498 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5499 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5500 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5501
5502 /* guid without brackets */
5503 sz = MAX_PATH;
5504 lstrcpyA(buf, "apple");
5505 r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
5506 MSIINSTALLCONTEXT_USERUNMANAGED,
5507 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5508 ok(r == ERROR_INVALID_PARAMETER,
5509 "Expected ERROR_INVALID_PARAMETER, 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 /* guid with brackets */
5514 sz = MAX_PATH;
5515 lstrcpyA(buf, "apple");
5516 r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
5517 MSIINSTALLCONTEXT_USERUNMANAGED,
5518 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5519 ok(r == ERROR_UNKNOWN_PRODUCT,
5520 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5521 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5522 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5523
5524 /* szValue is non-NULL while pcchValue is NULL */
5525 lstrcpyA(buf, "apple");
5526 r = pMsiGetProductInfoExA(prodcode, usersid,
5527 MSIINSTALLCONTEXT_USERUNMANAGED,
5528 INSTALLPROPERTY_PRODUCTSTATEA, buf, NULL);
5529 ok(r == ERROR_INVALID_PARAMETER,
5530 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5531 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5532
5533 /* dwContext is out of range */
5534 sz = MAX_PATH;
5535 lstrcpyA(buf, "apple");
5536 r = pMsiGetProductInfoExA(prodcode, usersid, 42,
5537 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5538 ok(r == ERROR_INVALID_PARAMETER,
5539 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5540 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5541 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5542
5543 /* szProperty is NULL */
5544 sz = MAX_PATH;
5545 lstrcpyA(buf, "apple");
5546 r = pMsiGetProductInfoExA(prodcode, usersid,
5547 MSIINSTALLCONTEXT_USERUNMANAGED,
5548 NULL, buf, &sz);
5549 ok(r == ERROR_INVALID_PARAMETER,
5550 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5551 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5552 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5553
5554 /* szProperty is empty */
5555 sz = MAX_PATH;
5556 lstrcpyA(buf, "apple");
5557 r = pMsiGetProductInfoExA(prodcode, usersid,
5558 MSIINSTALLCONTEXT_USERUNMANAGED,
5559 "", buf, &sz);
5560 ok(r == ERROR_INVALID_PARAMETER,
5561 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5562 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5563 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5564
5565 /* szProperty is not a valid property */
5566 sz = MAX_PATH;
5567 lstrcpyA(buf, "apple");
5568 r = pMsiGetProductInfoExA(prodcode, usersid,
5569 MSIINSTALLCONTEXT_USERUNMANAGED,
5570 "notvalid", buf, &sz);
5571 ok(r == ERROR_UNKNOWN_PRODUCT,
5572 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5573 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5574 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5575
5576 /* same length as guid, but random */
5577 sz = MAX_PATH;
5578 lstrcpyA(buf, "apple");
5579 r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
5580 MSIINSTALLCONTEXT_USERUNMANAGED,
5581 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5582 ok(r == ERROR_INVALID_PARAMETER,
5583 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5584 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5585 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5586
5587 /* MSIINSTALLCONTEXT_USERUNMANAGED */
5588
5589 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5590 lstrcatA(keypath, usersid);
5591 lstrcatA(keypath, "\\Products\\");
5592 lstrcatA(keypath, prod_squashed);
5593
5594 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5595 if (res == ERROR_ACCESS_DENIED)
5596 {
5597 skip("Not enough rights to perform tests\n");
5598 LocalFree(usersid);
5599 return;
5600 }
5601 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5602
5603 /* local user product key exists */
5604 sz = MAX_PATH;
5605 lstrcpyA(buf, "apple");
5606 r = pMsiGetProductInfoExA(prodcode, usersid,
5607 MSIINSTALLCONTEXT_USERUNMANAGED,
5608 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5609 ok(r == ERROR_UNKNOWN_PRODUCT,
5610 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5611 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5612 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5613
5614 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5615 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5616
5617 /* InstallProperties key exists */
5618 sz = MAX_PATH;
5619 lstrcpyA(buf, "apple");
5620 r = pMsiGetProductInfoExA(prodcode, usersid,
5621 MSIINSTALLCONTEXT_USERUNMANAGED,
5622 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5623 ok(r == ERROR_UNKNOWN_PRODUCT,
5624 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5625 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5626 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5627
5628 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5629 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5630
5631 /* LocalPackage value exists */
5632 sz = MAX_PATH;
5633 lstrcpyA(buf, "apple");
5634 r = pMsiGetProductInfoExA(prodcode, usersid,
5635 MSIINSTALLCONTEXT_USERUNMANAGED,
5636 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5638 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5639 ok(sz == 1, "Expected 1, got %d\n", sz);
5640
5641 RegDeleteValueA(propkey, "LocalPackage");
5642
5643 /* LocalPackage value must exist */
5644 sz = MAX_PATH;
5645 lstrcpyA(buf, "apple");
5646 r = pMsiGetProductInfoExA(prodcode, usersid,
5647 MSIINSTALLCONTEXT_USERUNMANAGED,
5648 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5649 ok(r == ERROR_UNKNOWN_PRODUCT,
5650 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5651 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5652 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5653
5654 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5655 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5656
5657 /* LocalPackage exists, but HelpLink does not exist */
5658 sz = MAX_PATH;
5659 lstrcpyA(buf, "apple");
5660 r = pMsiGetProductInfoExA(prodcode, usersid,
5661 MSIINSTALLCONTEXT_USERUNMANAGED,
5662 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5664 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5665 ok(sz == 0, "Expected 0, got %d\n", sz);
5666
5667 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5668 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5669
5670 /* HelpLink value exists */
5671 sz = MAX_PATH;
5672 lstrcpyA(buf, "apple");
5673 r = pMsiGetProductInfoExA(prodcode, usersid,
5674 MSIINSTALLCONTEXT_USERUNMANAGED,
5675 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5677 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5678 ok(sz == 4, "Expected 4, got %d\n", sz);
5679
5680 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5681 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5682
5683 /* HelpTelephone value exists */
5684 sz = MAX_PATH;
5685 lstrcpyA(buf, "apple");
5686 r = pMsiGetProductInfoExA(prodcode, usersid,
5687 MSIINSTALLCONTEXT_USERUNMANAGED,
5688 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5690 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5691 ok(sz == 5, "Expected 5, got %d\n", sz);
5692
5693 /* szValue and pcchValue are NULL */
5694 r = pMsiGetProductInfoExA(prodcode, usersid,
5695 MSIINSTALLCONTEXT_USERUNMANAGED,
5696 INSTALLPROPERTY_HELPTELEPHONEA, NULL, NULL);
5697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5698
5699 /* pcchValue is exactly 5 */
5700 sz = 5;
5701 lstrcpyA(buf, "apple");
5702 r = pMsiGetProductInfoExA(prodcode, usersid,
5703 MSIINSTALLCONTEXT_USERUNMANAGED,
5704 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5705 ok(r == ERROR_MORE_DATA,
5706 "Expected ERROR_MORE_DATA, got %d\n", r);
5707 ok(sz == 10, "Expected 10, got %d\n", sz);
5708
5709 /* szValue is NULL, pcchValue is exactly 5 */
5710 sz = 5;
5711 r = pMsiGetProductInfoExA(prodcode, usersid,
5712 MSIINSTALLCONTEXT_USERUNMANAGED,
5713 INSTALLPROPERTY_HELPTELEPHONEA, NULL, &sz);
5714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5715 ok(sz == 10, "Expected 10, got %d\n", sz);
5716
5717 /* szValue is NULL, pcchValue is MAX_PATH */
5718 sz = MAX_PATH;
5719 r = pMsiGetProductInfoExA(prodcode, usersid,
5720 MSIINSTALLCONTEXT_USERUNMANAGED,
5721 INSTALLPROPERTY_HELPTELEPHONEA, NULL, &sz);
5722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5723 ok(sz == 10, "Expected 10, got %d\n", sz);
5724
5725 /* pcchValue is exactly 0 */
5726 sz = 0;
5727 lstrcpyA(buf, "apple");
5728 r = pMsiGetProductInfoExA(prodcode, usersid,
5729 MSIINSTALLCONTEXT_USERUNMANAGED,
5730 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5731 ok(r == ERROR_MORE_DATA,
5732 "Expected ERROR_MORE_DATA, got %d\n", r);
5733 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5734 ok(sz == 10, "Expected 10, got %d\n", sz);
5735
5736 res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
5737 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5738
5739 /* szProperty is not a valid property */
5740 sz = MAX_PATH;
5741 lstrcpyA(buf, "apple");
5742 r = pMsiGetProductInfoExA(prodcode, usersid,
5743 MSIINSTALLCONTEXT_USERUNMANAGED,
5744 "notvalid", buf, &sz);
5745 ok(r == ERROR_UNKNOWN_PROPERTY,
5746 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5747 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5748 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5749
5750 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5751 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5752
5753 /* InstallDate value exists */
5754 sz = MAX_PATH;
5755 lstrcpyA(buf, "apple");
5756 r = pMsiGetProductInfoExA(prodcode, usersid,
5757 MSIINSTALLCONTEXT_USERUNMANAGED,
5758 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
5759 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5760 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5761 ok(sz == 4, "Expected 4, got %d\n", sz);
5762
5763 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5764 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5765
5766 /* DisplayName value exists */
5767 sz = MAX_PATH;
5768 lstrcpyA(buf, "apple");
5769 r = pMsiGetProductInfoExA(prodcode, usersid,
5770 MSIINSTALLCONTEXT_USERUNMANAGED,
5771 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
5772 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5773 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5774 ok(sz == 4, "Expected 4, got %d\n", sz);
5775
5776 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5777 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5778
5779 /* InstallLocation value exists */
5780 sz = MAX_PATH;
5781 lstrcpyA(buf, "apple");
5782 r = pMsiGetProductInfoExA(prodcode, usersid,
5783 MSIINSTALLCONTEXT_USERUNMANAGED,
5784 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
5785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5786 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5787 ok(sz == 3, "Expected 3, got %d\n", sz);
5788
5789 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5790 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5791
5792 /* InstallSource value exists */
5793 sz = MAX_PATH;
5794 lstrcpyA(buf, "apple");
5795 r = pMsiGetProductInfoExA(prodcode, usersid,
5796 MSIINSTALLCONTEXT_USERUNMANAGED,
5797 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
5798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5799 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5800 ok(sz == 6, "Expected 6, got %d\n", sz);
5801
5802 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5803 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5804
5805 /* LocalPackage value exists */
5806 sz = MAX_PATH;
5807 lstrcpyA(buf, "apple");
5808 r = pMsiGetProductInfoExA(prodcode, usersid,
5809 MSIINSTALLCONTEXT_USERUNMANAGED,
5810 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
5811 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5812 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5813 ok(sz == 5, "Expected 5, got %d\n", sz);
5814
5815 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5816 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5817
5818 /* Publisher value exists */
5819 sz = MAX_PATH;
5820 lstrcpyA(buf, "apple");
5821 r = pMsiGetProductInfoExA(prodcode, usersid,
5822 MSIINSTALLCONTEXT_USERUNMANAGED,
5823 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
5824 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5825 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5826 ok(sz == 3, "Expected 3, got %d\n", sz);
5827
5828 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5829 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5830
5831 /* URLInfoAbout value exists */
5832 sz = MAX_PATH;
5833 lstrcpyA(buf, "apple");
5834 r = pMsiGetProductInfoExA(prodcode, usersid,
5835 MSIINSTALLCONTEXT_USERUNMANAGED,
5836 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
5837 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5838 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5839 ok(sz == 5, "Expected 5, got %d\n", sz);
5840
5841 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5842 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5843
5844 /* URLUpdateInfo value exists */
5845 sz = MAX_PATH;
5846 lstrcpyA(buf, "apple");
5847 r = pMsiGetProductInfoExA(prodcode, usersid,
5848 MSIINSTALLCONTEXT_USERUNMANAGED,
5849 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
5850 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5851 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5852 ok(sz == 6, "Expected 6, got %d\n", sz);
5853
5854 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5855 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5856
5857 /* VersionMinor value exists */
5858 sz = MAX_PATH;
5859 lstrcpyA(buf, "apple");
5860 r = pMsiGetProductInfoExA(prodcode, usersid,
5861 MSIINSTALLCONTEXT_USERUNMANAGED,
5862 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
5863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5864 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5865 ok(sz == 1, "Expected 1, got %d\n", sz);
5866
5867 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5869
5870 /* VersionMajor value exists */
5871 sz = MAX_PATH;
5872 lstrcpyA(buf, "apple");
5873 r = pMsiGetProductInfoExA(prodcode, usersid,
5874 MSIINSTALLCONTEXT_USERUNMANAGED,
5875 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
5876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5877 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5878 ok(sz == 1, "Expected 1, got %d\n", sz);
5879
5880 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5881 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5882
5883 /* DisplayVersion value exists */
5884 sz = MAX_PATH;
5885 lstrcpyA(buf, "apple");
5886 r = pMsiGetProductInfoExA(prodcode, usersid,
5887 MSIINSTALLCONTEXT_USERUNMANAGED,
5888 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
5889 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5890 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5891 ok(sz == 5, "Expected 5, got %d\n", sz);
5892
5893 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5894 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5895
5896 /* ProductID value exists */
5897 sz = MAX_PATH;
5898 lstrcpyA(buf, "apple");
5899 r = pMsiGetProductInfoExA(prodcode, usersid,
5900 MSIINSTALLCONTEXT_USERUNMANAGED,
5901 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
5902 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5903 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5904 ok(sz == 2, "Expected 2, got %d\n", sz);
5905
5906 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5907 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5908
5909 /* RegCompany value exists */
5910 sz = MAX_PATH;
5911 lstrcpyA(buf, "apple");
5912 r = pMsiGetProductInfoExA(prodcode, usersid,
5913 MSIINSTALLCONTEXT_USERUNMANAGED,
5914 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
5915 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5916 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5917 ok(sz == 4, "Expected 4, got %d\n", sz);
5918
5919 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5920 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5921
5922 /* RegOwner value exists */
5923 sz = MAX_PATH;
5924 lstrcpyA(buf, "apple");
5925 r = pMsiGetProductInfoExA(prodcode, usersid,
5926 MSIINSTALLCONTEXT_USERUNMANAGED,
5927 INSTALLPROPERTY_REGOWNERA, buf, &sz);
5928 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5929 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5930 ok(sz == 5, "Expected 5, got %d\n", sz);
5931
5932 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5933 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5934
5935 /* Transforms value exists */
5936 sz = MAX_PATH;
5937 lstrcpyA(buf, "apple");
5938 r = pMsiGetProductInfoExA(prodcode, usersid,
5939 MSIINSTALLCONTEXT_USERUNMANAGED,
5940 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5941 ok(r == ERROR_UNKNOWN_PRODUCT,
5942 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5943 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5944 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5945
5946 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5948
5949 /* Language value exists */
5950 sz = MAX_PATH;
5951 lstrcpyA(buf, "apple");
5952 r = pMsiGetProductInfoExA(prodcode, usersid,
5953 MSIINSTALLCONTEXT_USERUNMANAGED,
5954 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5955 ok(r == ERROR_UNKNOWN_PRODUCT,
5956 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5957 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5958 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5959
5960 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5961 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5962
5963 /* ProductName value exists */
5964 sz = MAX_PATH;
5965 lstrcpyA(buf, "apple");
5966 r = pMsiGetProductInfoExA(prodcode, usersid,
5967 MSIINSTALLCONTEXT_USERUNMANAGED,
5968 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5969 ok(r == ERROR_UNKNOWN_PRODUCT,
5970 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5971 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5972 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5973
5974 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5975 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5976
5977 /* FIXME */
5978
5979 /* AssignmentType value exists */
5980 sz = MAX_PATH;
5981 lstrcpyA(buf, "apple");
5982 r = pMsiGetProductInfoExA(prodcode, usersid,
5983 MSIINSTALLCONTEXT_USERUNMANAGED,
5984 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5985 ok(r == ERROR_UNKNOWN_PRODUCT,
5986 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5987 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5988 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5989
5990 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5991 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5992
5993 /* PackageCode value exists */
5994 sz = MAX_PATH;
5995 lstrcpyA(buf, "apple");
5996 r = pMsiGetProductInfoExA(prodcode, usersid,
5997 MSIINSTALLCONTEXT_USERUNMANAGED,
5998 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5999 ok(r == ERROR_UNKNOWN_PRODUCT,
6000 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6001 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6002 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6003
6004 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6005 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6006
6007 /* Version value exists */
6008 sz = MAX_PATH;
6009 lstrcpyA(buf, "apple");
6010 r = pMsiGetProductInfoExA(prodcode, usersid,
6011 MSIINSTALLCONTEXT_USERUNMANAGED,
6012 INSTALLPROPERTY_VERSIONA, buf, &sz);
6013 ok(r == ERROR_UNKNOWN_PRODUCT,
6014 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6015 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6016 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6017
6018 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6019 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6020
6021 /* ProductIcon value exists */
6022 sz = MAX_PATH;
6023 lstrcpyA(buf, "apple");
6024 r = pMsiGetProductInfoExA(prodcode, usersid,
6025 MSIINSTALLCONTEXT_USERUNMANAGED,
6026 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6027 ok(r == ERROR_UNKNOWN_PRODUCT,
6028 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6029 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6030 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6031
6032 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6033 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6034
6035 /* PackageName value exists */
6036 sz = MAX_PATH;
6037 lstrcpyA(buf, "apple");
6038 r = pMsiGetProductInfoExA(prodcode, usersid,
6039 MSIINSTALLCONTEXT_USERUNMANAGED,
6040 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
6041 ok(r == ERROR_UNKNOWN_PRODUCT,
6042 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6043 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6044 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6045
6046 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6047 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6048
6049 /* AuthorizedLUAApp value exists */
6050 sz = MAX_PATH;
6051 lstrcpyA(buf, "apple");
6052 r = pMsiGetProductInfoExA(prodcode, usersid,
6053 MSIINSTALLCONTEXT_USERUNMANAGED,
6054 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
6055 ok(r == ERROR_UNKNOWN_PRODUCT,
6056 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6057 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6058 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6059
6060 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6061 RegDeleteValueA(propkey, "PackageName");
6062 RegDeleteValueA(propkey, "ProductIcon");
6063 RegDeleteValueA(propkey, "Version");
6064 RegDeleteValueA(propkey, "PackageCode");
6065 RegDeleteValueA(propkey, "AssignmentType");
6066 RegDeleteValueA(propkey, "ProductName");
6067 RegDeleteValueA(propkey, "Language");
6068 RegDeleteValueA(propkey, "Transforms");
6069 RegDeleteValueA(propkey, "RegOwner");
6070 RegDeleteValueA(propkey, "RegCompany");
6071 RegDeleteValueA(propkey, "ProductID");
6072 RegDeleteValueA(propkey, "DisplayVersion");
6073 RegDeleteValueA(propkey, "VersionMajor");
6074 RegDeleteValueA(propkey, "VersionMinor");
6075 RegDeleteValueA(propkey, "URLUpdateInfo");
6076 RegDeleteValueA(propkey, "URLInfoAbout");
6077 RegDeleteValueA(propkey, "Publisher");
6078 RegDeleteValueA(propkey, "LocalPackage");
6079 RegDeleteValueA(propkey, "InstallSource");
6080 RegDeleteValueA(propkey, "InstallLocation");
6081 RegDeleteValueA(propkey, "DisplayName");
6082 RegDeleteValueA(propkey, "InstallDate");
6083 RegDeleteValueA(propkey, "HelpTelephone");
6084 RegDeleteValueA(propkey, "HelpLink");
6085 RegDeleteValueA(propkey, "LocalPackage");
6086 RegDeleteKeyA(propkey, "");
6087 RegCloseKey(propkey);
6088 RegDeleteKeyA(localkey, "");
6089 RegCloseKey(localkey);
6090
6091 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6092 lstrcatA(keypath, usersid);
6093 lstrcatA(keypath, "\\Installer\\Products\\");
6094 lstrcatA(keypath, prod_squashed);
6095
6096 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6097 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6098
6099 /* user product key exists */
6100 sz = MAX_PATH;
6101 lstrcpyA(buf, "apple");
6102 r = pMsiGetProductInfoExA(prodcode, usersid,
6103 MSIINSTALLCONTEXT_USERUNMANAGED,
6104 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6105 ok(r == ERROR_UNKNOWN_PRODUCT,
6106 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6107 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6108 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6109
6110 RegDeleteKeyA(userkey, "");
6111 RegCloseKey(userkey);
6112
6113 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6114 lstrcatA(keypath, prod_squashed);
6115
6116 res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6117 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6118
6119 sz = MAX_PATH;
6120 lstrcpyA(buf, "apple");
6121 r = pMsiGetProductInfoExA(prodcode, usersid,
6122 MSIINSTALLCONTEXT_USERUNMANAGED,
6123 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6124 ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
6125 if (r == ERROR_UNKNOWN_PRODUCT)
6126 {
6127 win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
6128 delete_key(prodkey, "", access);
6129 RegCloseKey(prodkey);
6130 return;
6131 }
6132 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6133 ok(sz == 1, "Expected 1, got %d\n", sz);
6134
6135 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6136 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6137
6138 /* HelpLink value exists */
6139 sz = MAX_PATH;
6140 lstrcpyA(buf, "apple");
6141 r = pMsiGetProductInfoExA(prodcode, usersid,
6142 MSIINSTALLCONTEXT_USERUNMANAGED,
6143 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6144 ok(r == ERROR_UNKNOWN_PROPERTY,
6145 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6146 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6147 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6148
6149 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6150 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6151
6152 /* HelpTelephone value exists */
6153 sz = MAX_PATH;
6154 lstrcpyA(buf, "apple");
6155 r = pMsiGetProductInfoExA(prodcode, usersid,
6156 MSIINSTALLCONTEXT_USERUNMANAGED,
6157 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6158 ok(r == ERROR_UNKNOWN_PROPERTY,
6159 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6160 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6161 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6162
6163 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6164 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6165
6166 /* InstallDate value exists */
6167 sz = MAX_PATH;
6168 lstrcpyA(buf, "apple");
6169 r = pMsiGetProductInfoExA(prodcode, usersid,
6170 MSIINSTALLCONTEXT_USERUNMANAGED,
6171 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6172 ok(r == ERROR_UNKNOWN_PROPERTY,
6173 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6174 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6175 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6176
6177 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6178 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6179
6180 /* DisplayName value exists */
6181 sz = MAX_PATH;
6182 lstrcpyA(buf, "apple");
6183 r = pMsiGetProductInfoExA(prodcode, usersid,
6184 MSIINSTALLCONTEXT_USERUNMANAGED,
6185 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6186 ok(r == ERROR_UNKNOWN_PROPERTY,
6187 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6188 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6189 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6190
6191 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6192 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6193
6194 /* InstallLocation value exists */
6195 sz = MAX_PATH;
6196 lstrcpyA(buf, "apple");
6197 r = pMsiGetProductInfoExA(prodcode, usersid,
6198 MSIINSTALLCONTEXT_USERUNMANAGED,
6199 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6200 ok(r == ERROR_UNKNOWN_PROPERTY,
6201 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6202 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6203 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6204
6205 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6206 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6207
6208 /* InstallSource value exists */
6209 sz = MAX_PATH;
6210 lstrcpyA(buf, "apple");
6211 r = pMsiGetProductInfoExA(prodcode, usersid,
6212 MSIINSTALLCONTEXT_USERUNMANAGED,
6213 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6214 ok(r == ERROR_UNKNOWN_PROPERTY,
6215 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6216 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6217 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6218
6219 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6221
6222 /* LocalPackage value exists */
6223 sz = MAX_PATH;
6224 lstrcpyA(buf, "apple");
6225 r = pMsiGetProductInfoExA(prodcode, usersid,
6226 MSIINSTALLCONTEXT_USERUNMANAGED,
6227 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6228 ok(r == ERROR_UNKNOWN_PROPERTY,
6229 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6230 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6231 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6232
6233 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6234 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6235
6236 /* Publisher value exists */
6237 sz = MAX_PATH;
6238 lstrcpyA(buf, "apple");
6239 r = pMsiGetProductInfoExA(prodcode, usersid,
6240 MSIINSTALLCONTEXT_USERUNMANAGED,
6241 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6242 ok(r == ERROR_UNKNOWN_PROPERTY,
6243 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6244 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6245 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6246
6247 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6248 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6249
6250 /* URLInfoAbout value exists */
6251 sz = MAX_PATH;
6252 lstrcpyA(buf, "apple");
6253 r = pMsiGetProductInfoExA(prodcode, usersid,
6254 MSIINSTALLCONTEXT_USERUNMANAGED,
6255 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6256 ok(r == ERROR_UNKNOWN_PROPERTY,
6257 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6258 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6259 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6260
6261 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6262 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6263
6264 /* URLUpdateInfo value exists */
6265 sz = MAX_PATH;
6266 lstrcpyA(buf, "apple");
6267 r = pMsiGetProductInfoExA(prodcode, usersid,
6268 MSIINSTALLCONTEXT_USERUNMANAGED,
6269 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6270 ok(r == ERROR_UNKNOWN_PROPERTY,
6271 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6272 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6273 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6274
6275 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6276 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6277
6278 /* VersionMinor value exists */
6279 sz = MAX_PATH;
6280 lstrcpyA(buf, "apple");
6281 r = pMsiGetProductInfoExA(prodcode, usersid,
6282 MSIINSTALLCONTEXT_USERUNMANAGED,
6283 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6284 ok(r == ERROR_UNKNOWN_PROPERTY,
6285 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6286 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6287 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6288
6289 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6290 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6291
6292 /* VersionMajor value exists */
6293 sz = MAX_PATH;
6294 lstrcpyA(buf, "apple");
6295 r = pMsiGetProductInfoExA(prodcode, usersid,
6296 MSIINSTALLCONTEXT_USERUNMANAGED,
6297 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6298 ok(r == ERROR_UNKNOWN_PROPERTY,
6299 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6300 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6301 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6302
6303 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6304 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6305
6306 /* DisplayVersion value exists */
6307 sz = MAX_PATH;
6308 lstrcpyA(buf, "apple");
6309 r = pMsiGetProductInfoExA(prodcode, usersid,
6310 MSIINSTALLCONTEXT_USERUNMANAGED,
6311 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6312 ok(r == ERROR_UNKNOWN_PROPERTY,
6313 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6314 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6315 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6316
6317 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6318 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6319
6320 /* ProductID value exists */
6321 sz = MAX_PATH;
6322 lstrcpyA(buf, "apple");
6323 r = pMsiGetProductInfoExA(prodcode, usersid,
6324 MSIINSTALLCONTEXT_USERUNMANAGED,
6325 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6326 ok(r == ERROR_UNKNOWN_PROPERTY,
6327 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6328 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6329 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6330
6331 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6332 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6333
6334 /* RegCompany value exists */
6335 sz = MAX_PATH;
6336 lstrcpyA(buf, "apple");
6337 r = pMsiGetProductInfoExA(prodcode, usersid,
6338 MSIINSTALLCONTEXT_USERUNMANAGED,
6339 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6340 ok(r == ERROR_UNKNOWN_PROPERTY,
6341 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6342 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6343 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6344
6345 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6346 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6347
6348 /* RegOwner value exists */
6349 sz = MAX_PATH;
6350 lstrcpyA(buf, "apple");
6351 r = pMsiGetProductInfoExA(prodcode, usersid,
6352 MSIINSTALLCONTEXT_USERUNMANAGED,
6353 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6354 ok(r == ERROR_UNKNOWN_PROPERTY,
6355 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6356 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6357 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6358
6359 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6360 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6361
6362 /* Transforms value exists */
6363 sz = MAX_PATH;
6364 lstrcpyA(buf, "apple");
6365 r = pMsiGetProductInfoExA(prodcode, usersid,
6366 MSIINSTALLCONTEXT_USERUNMANAGED,
6367 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6369 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6370 ok(sz == 5, "Expected 5, got %d\n", sz);
6371
6372 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6373 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6374
6375 /* Language value exists */
6376 sz = MAX_PATH;
6377 lstrcpyA(buf, "apple");
6378 r = pMsiGetProductInfoExA(prodcode, usersid,
6379 MSIINSTALLCONTEXT_USERUNMANAGED,
6380 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6382 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6383 ok(sz == 4, "Expected 4, got %d\n", sz);
6384
6385 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6386 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6387
6388 /* ProductName value exists */
6389 sz = MAX_PATH;
6390 lstrcpyA(buf, "apple");
6391 r = pMsiGetProductInfoExA(prodcode, usersid,
6392 MSIINSTALLCONTEXT_USERUNMANAGED,
6393 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6394 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6395 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6396 ok(sz == 4, "Expected 4, got %d\n", sz);
6397
6398 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6399 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6400
6401 /* FIXME */
6402
6403 /* AssignmentType value exists */
6404 sz = MAX_PATH;
6405 lstrcpyA(buf, "apple");
6406 r = pMsiGetProductInfoExA(prodcode, usersid,
6407 MSIINSTALLCONTEXT_USERUNMANAGED,
6408 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
6409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6410 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6411 ok(sz == 0, "Expected 0, got %d\n", sz);
6412
6413 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6414 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6415
6416 /* FIXME */
6417
6418 /* PackageCode value exists */
6419 sz = MAX_PATH;
6420 lstrcpyA(buf, "apple");
6421 r = pMsiGetProductInfoExA(prodcode, usersid,
6422 MSIINSTALLCONTEXT_USERUNMANAGED,
6423 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
6424 todo_wine
6425 {
6426 ok(r == ERROR_BAD_CONFIGURATION,
6427 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6428 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6429 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6430 }
6431
6432 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6433 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6434
6435 /* Version value exists */
6436 sz = MAX_PATH;
6437 lstrcpyA(buf, "apple");
6438 r = pMsiGetProductInfoExA(prodcode, usersid,
6439 MSIINSTALLCONTEXT_USERUNMANAGED,
6440 INSTALLPROPERTY_VERSIONA, buf, &sz);
6441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6442 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6443 ok(sz == 3, "Expected 3, got %d\n", sz);
6444
6445 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6446 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6447
6448 /* ProductIcon value exists */
6449 sz = MAX_PATH;
6450 lstrcpyA(buf, "apple");
6451 r = pMsiGetProductInfoExA(prodcode, usersid,
6452 MSIINSTALLCONTEXT_USERUNMANAGED,
6453 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6454 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6455 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6456 ok(sz == 4, "Expected 4, got %d\n", sz);
6457
6458 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6459 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6460
6461 /* PackageName value exists */
6462 sz = MAX_PATH;
6463 lstrcpyA(buf, "apple");
6464 r = pMsiGetProductInfoExA(prodcode, usersid,
6465 MSIINSTALLCONTEXT_USERUNMANAGED,
6466 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
6467 todo_wine
6468 {
6469 ok(r == ERROR_UNKNOWN_PRODUCT,
6470 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6471 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6472 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6473 }
6474
6475 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6476 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6477
6478 /* AuthorizedLUAApp value exists */
6479 sz = MAX_PATH;
6480 lstrcpyA(buf, "apple");
6481 r = pMsiGetProductInfoExA(prodcode, usersid,
6482 MSIINSTALLCONTEXT_USERUNMANAGED,
6483 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
6484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6485 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6486 ok(sz == 4, "Expected 4, got %d\n", sz);
6487
6488 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6489 RegDeleteValueA(prodkey, "PackageName");
6490 RegDeleteValueA(prodkey, "ProductIcon");
6491 RegDeleteValueA(prodkey, "Version");
6492 RegDeleteValueA(prodkey, "PackageCode");
6493 RegDeleteValueA(prodkey, "AssignmentType");
6494 RegDeleteValueA(prodkey, "ProductName");
6495 RegDeleteValueA(prodkey, "Language");
6496 RegDeleteValueA(prodkey, "Transforms");
6497 RegDeleteValueA(prodkey, "RegOwner");
6498 RegDeleteValueA(prodkey, "RegCompany");
6499 RegDeleteValueA(prodkey, "ProductID");
6500 RegDeleteValueA(prodkey, "DisplayVersion");
6501 RegDeleteValueA(prodkey, "VersionMajor");
6502 RegDeleteValueA(prodkey, "VersionMinor");
6503 RegDeleteValueA(prodkey, "URLUpdateInfo");
6504 RegDeleteValueA(prodkey, "URLInfoAbout");
6505 RegDeleteValueA(prodkey, "Publisher");
6506 RegDeleteValueA(prodkey, "LocalPackage");
6507 RegDeleteValueA(prodkey, "InstallSource");
6508 RegDeleteValueA(prodkey, "InstallLocation");
6509 RegDeleteValueA(prodkey, "DisplayName");
6510 RegDeleteValueA(prodkey, "InstallDate");
6511 RegDeleteValueA(prodkey, "HelpTelephone");
6512 RegDeleteValueA(prodkey, "HelpLink");
6513 RegDeleteValueA(prodkey, "LocalPackage");
6514 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6515 RegCloseKey(prodkey);
6516
6517 /* MSIINSTALLCONTEXT_USERMANAGED */
6518
6519 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
6520 lstrcatA(keypath, usersid);
6521 lstrcatA(keypath, "\\Products\\");
6522 lstrcatA(keypath, prod_squashed);
6523
6524 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6526
6527 /* local user product key exists */
6528 sz = MAX_PATH;
6529 lstrcpyA(buf, "apple");
6530 r = pMsiGetProductInfoExA(prodcode, usersid,
6531 MSIINSTALLCONTEXT_USERMANAGED,
6532 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6533 ok(r == ERROR_UNKNOWN_PRODUCT,
6534 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6535 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6536 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6537
6538 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6539 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6540
6541 /* InstallProperties key exists */
6542 sz = MAX_PATH;
6543 lstrcpyA(buf, "apple");
6544 r = pMsiGetProductInfoExA(prodcode, usersid,
6545 MSIINSTALLCONTEXT_USERMANAGED,
6546 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6547 ok(r == ERROR_UNKNOWN_PRODUCT,
6548 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6549 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6550 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6551
6552 res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6553 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6554
6555 /* ManagedLocalPackage value exists */
6556 sz = MAX_PATH;
6557 lstrcpyA(buf, "apple");
6558 r = pMsiGetProductInfoExA(prodcode, usersid,
6559 MSIINSTALLCONTEXT_USERMANAGED,
6560 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6561 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6562 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6563 ok(sz == 1, "Expected 1, got %d\n", sz);
6564
6565 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6566 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6567
6568 /* HelpLink value exists */
6569 sz = MAX_PATH;
6570 lstrcpyA(buf, "apple");
6571 r = pMsiGetProductInfoExA(prodcode, usersid,
6572 MSIINSTALLCONTEXT_USERMANAGED,
6573 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6575 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6576 ok(sz == 4, "Expected 4, got %d\n", sz);
6577
6578 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6579 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6580
6581 /* HelpTelephone value exists */
6582 sz = MAX_PATH;
6583 lstrcpyA(buf, "apple");
6584 r = pMsiGetProductInfoExA(prodcode, usersid,
6585 MSIINSTALLCONTEXT_USERMANAGED,
6586 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6587 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6588 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6589 ok(sz == 5, "Expected 5, got %d\n", sz);
6590
6591 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6593
6594 /* InstallDate value exists */
6595 sz = MAX_PATH;
6596 lstrcpyA(buf, "apple");
6597 r = pMsiGetProductInfoExA(prodcode, usersid,
6598 MSIINSTALLCONTEXT_USERMANAGED,
6599 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6601 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6602 ok(sz == 4, "Expected 4, got %d\n", sz);
6603
6604 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6605 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6606
6607 /* DisplayName value exists */
6608 sz = MAX_PATH;
6609 lstrcpyA(buf, "apple");
6610 r = pMsiGetProductInfoExA(prodcode, usersid,
6611 MSIINSTALLCONTEXT_USERMANAGED,
6612 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6613 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6614 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6615 ok(sz == 4, "Expected 4, got %d\n", sz);
6616
6617 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6618 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6619
6620 /* InstallLocation value exists */
6621 sz = MAX_PATH;
6622 lstrcpyA(buf, "apple");
6623 r = pMsiGetProductInfoExA(prodcode, usersid,
6624 MSIINSTALLCONTEXT_USERMANAGED,
6625 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6626 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6627 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6628 ok(sz == 3, "Expected 3, got %d\n", sz);
6629
6630 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6631 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6632
6633 /* InstallSource value exists */
6634 sz = MAX_PATH;
6635 lstrcpyA(buf, "apple");
6636 r = pMsiGetProductInfoExA(prodcode, usersid,
6637 MSIINSTALLCONTEXT_USERMANAGED,
6638 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6639 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6640 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6641 ok(sz == 6, "Expected 6, got %d\n", sz);
6642
6643 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6644 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6645
6646 /* LocalPackage value exists */
6647 sz = MAX_PATH;
6648 lstrcpyA(buf, "apple");
6649 r = pMsiGetProductInfoExA(prodcode, usersid,
6650 MSIINSTALLCONTEXT_USERMANAGED,
6651 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6652 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6653 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6654 ok(sz == 5, "Expected 5, got %d\n", sz);
6655
6656 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6657 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6658
6659 /* Publisher value exists */
6660 sz = MAX_PATH;
6661 lstrcpyA(buf, "apple");
6662 r = pMsiGetProductInfoExA(prodcode, usersid,
6663 MSIINSTALLCONTEXT_USERMANAGED,
6664 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6665 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6666 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6667 ok(sz == 3, "Expected 3, got %d\n", sz);
6668
6669 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6670 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6671
6672 /* URLInfoAbout value exists */
6673 sz = MAX_PATH;
6674 lstrcpyA(buf, "apple");
6675 r = pMsiGetProductInfoExA(prodcode, usersid,
6676 MSIINSTALLCONTEXT_USERMANAGED,
6677 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6679 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6680 ok(sz == 5, "Expected 5, got %d\n", sz);
6681
6682 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6684
6685 /* URLUpdateInfo value exists */
6686 sz = MAX_PATH;
6687 lstrcpyA(buf, "apple");
6688 r = pMsiGetProductInfoExA(prodcode, usersid,
6689 MSIINSTALLCONTEXT_USERMANAGED,
6690 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6691 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6692 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6693 ok(sz == 6, "Expected 6, got %d\n", sz);
6694
6695 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6696 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6697
6698 /* VersionMinor value exists */
6699 sz = MAX_PATH;
6700 lstrcpyA(buf, "apple");
6701 r = pMsiGetProductInfoExA(prodcode, usersid,
6702 MSIINSTALLCONTEXT_USERMANAGED,
6703 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6704 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6705 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6706 ok(sz == 1, "Expected 1, got %d\n", sz);
6707
6708 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6709 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6710
6711 /* VersionMajor value exists */
6712 sz = MAX_PATH;
6713 lstrcpyA(buf, "apple");
6714 r = pMsiGetProductInfoExA(prodcode, usersid,
6715 MSIINSTALLCONTEXT_USERMANAGED,
6716 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6717 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6718 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6719 ok(sz == 1, "Expected 1, got %d\n", sz);
6720
6721 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6722 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6723
6724 /* DisplayVersion value exists */
6725 sz = MAX_PATH;
6726 lstrcpyA(buf, "apple");
6727 r = pMsiGetProductInfoExA(prodcode, usersid,
6728 MSIINSTALLCONTEXT_USERMANAGED,
6729 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6730 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6731 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6732 ok(sz == 5, "Expected 5, got %d\n", sz);
6733
6734 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6735 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6736
6737 /* ProductID value exists */
6738 sz = MAX_PATH;
6739 lstrcpyA(buf, "apple");
6740 r = pMsiGetProductInfoExA(prodcode, usersid,
6741 MSIINSTALLCONTEXT_USERMANAGED,
6742 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6743 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6744 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6745 ok(sz == 2, "Expected 2, got %d\n", sz);
6746
6747 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6748 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6749
6750 /* RegCompany value exists */
6751 sz = MAX_PATH;
6752 lstrcpyA(buf, "apple");
6753 r = pMsiGetProductInfoExA(prodcode, usersid,
6754 MSIINSTALLCONTEXT_USERMANAGED,
6755 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6756 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6757 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6758 ok(sz == 4, "Expected 4, got %d\n", sz);
6759
6760 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6761 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6762
6763 /* RegOwner value exists */
6764 sz = MAX_PATH;
6765 lstrcpyA(buf, "apple");
6766 r = pMsiGetProductInfoExA(prodcode, usersid,
6767 MSIINSTALLCONTEXT_USERMANAGED,
6768 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6769 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6770 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6771 ok(sz == 5, "Expected 5, got %d\n", sz);
6772
6773 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6774 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6775
6776 /* Transforms value exists */
6777 sz = MAX_PATH;
6778 lstrcpyA(buf, "apple");
6779 r = pMsiGetProductInfoExA(prodcode, usersid,
6780 MSIINSTALLCONTEXT_USERMANAGED,
6781 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6782 ok(r == ERROR_UNKNOWN_PRODUCT,
6783 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6784 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6785 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6786
6787 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6788 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6789
6790 /* Language value exists */
6791 sz = MAX_PATH;
6792 lstrcpyA(buf, "apple");
6793 r = pMsiGetProductInfoExA(prodcode, usersid,
6794 MSIINSTALLCONTEXT_USERMANAGED,
6795 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6796 ok(r == ERROR_UNKNOWN_PRODUCT,
6797 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6798 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6799 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6800
6801 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6802 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6803
6804 /* ProductName value exists */
6805 sz = MAX_PATH;
6806 lstrcpyA(buf, "apple");
6807 r = pMsiGetProductInfoExA(prodcode, usersid,
6808 MSIINSTALLCONTEXT_USERMANAGED,
6809 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6810 ok(r == ERROR_UNKNOWN_PRODUCT,
6811 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6812 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6813 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6814
6815 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6816 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6817
6818 /* FIXME */
6819
6820 /* AssignmentType value exists */
6821 sz = MAX_PATH;
6822 lstrcpyA(buf, "apple");
6823 r = pMsiGetProductInfoExA(prodcode, usersid,
6824 MSIINSTALLCONTEXT_USERMANAGED,
6825 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
6826 ok(r == ERROR_UNKNOWN_PRODUCT,
6827 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6828 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6829 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6830
6831 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6832 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6833
6834 /* PackageCode value exists */
6835 sz = MAX_PATH;
6836 lstrcpyA(buf, "apple");
6837 r = pMsiGetProductInfoExA(prodcode, usersid,
6838 MSIINSTALLCONTEXT_USERMANAGED,
6839 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
6840 ok(r == ERROR_UNKNOWN_PRODUCT,
6841 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6842 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6843 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6844
6845 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6846 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6847
6848 /* Version value exists */
6849 sz = MAX_PATH;
6850 lstrcpyA(buf, "apple");
6851 r = pMsiGetProductInfoExA(prodcode, usersid,
6852 MSIINSTALLCONTEXT_USERMANAGED,
6853 INSTALLPROPERTY_VERSIONA, buf, &sz);
6854 ok(r == ERROR_UNKNOWN_PRODUCT,
6855 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6856 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6857 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6858
6859 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6860 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6861
6862 /* ProductIcon value exists */
6863 sz = MAX_PATH;
6864 lstrcpyA(buf, "apple");
6865 r = pMsiGetProductInfoExA(prodcode, usersid,
6866 MSIINSTALLCONTEXT_USERMANAGED,
6867 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6868 ok(r == ERROR_UNKNOWN_PRODUCT,
6869 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6870 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6871 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6872
6873 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6875
6876 /* PackageName value exists */
6877 sz = MAX_PATH;
6878 lstrcpyA(buf, "apple");
6879 r = pMsiGetProductInfoExA(prodcode, usersid,
6880 MSIINSTALLCONTEXT_USERMANAGED,
6881 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
6882 ok(r == ERROR_UNKNOWN_PRODUCT,
6883 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6884 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6885 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6886
6887 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6888 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6889
6890 /* AuthorizedLUAApp value exists */
6891 sz = MAX_PATH;
6892 lstrcpyA(buf, "apple");
6893 r = pMsiGetProductInfoExA(prodcode, usersid,
6894 MSIINSTALLCONTEXT_USERMANAGED,
6895 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
6896 ok(r == ERROR_UNKNOWN_PRODUCT,
6897 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6898 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6899 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6900
6901 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6902 RegDeleteValueA(propkey, "PackageName");
6903 RegDeleteValueA(propkey, "ProductIcon");
6904 RegDeleteValueA(propkey, "Version");
6905 RegDeleteValueA(propkey, "PackageCode");
6906 RegDeleteValueA(propkey, "AssignmentType");
6907 RegDeleteValueA(propkey, "ProductName");
6908 RegDeleteValueA(propkey, "Language");
6909 RegDeleteValueA(propkey, "Transforms");
6910 RegDeleteValueA(propkey, "RegOwner");
6911 RegDeleteValueA(propkey, "RegCompany");
6912 RegDeleteValueA(propkey, "ProductID");
6913 RegDeleteValueA(propkey, "DisplayVersion");
6914 RegDeleteValueA(propkey, "VersionMajor");
6915 RegDeleteValueA(propkey, "VersionMinor");
6916 RegDeleteValueA(propkey, "URLUpdateInfo");
6917 RegDeleteValueA(propkey, "URLInfoAbout");
6918 RegDeleteValueA(propkey, "Publisher");
6919 RegDeleteValueA(propkey, "LocalPackage");
6920 RegDeleteValueA(propkey, "InstallSource");
6921 RegDeleteValueA(propkey, "InstallLocation");
6922 RegDeleteValueA(propkey, "DisplayName");
6923 RegDeleteValueA(propkey, "InstallDate");
6924 RegDeleteValueA(propkey, "HelpTelephone");
6925 RegDeleteValueA(propkey, "HelpLink");
6926 RegDeleteValueA(propkey, "ManagedLocalPackage");
6927 delete_key(propkey, "", access & KEY_WOW64_64KEY);
6928 RegCloseKey(propkey);
6929 delete_key(localkey, "", access & KEY_WOW64_64KEY);
6930 RegCloseKey(localkey);
6931
6932 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6933 lstrcatA(keypath, usersid);
6934 lstrcatA(keypath, "\\Installer\\Products\\");
6935 lstrcatA(keypath, prod_squashed);
6936
6937 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6938 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6939
6940 /* user product key exists */
6941 sz = MAX_PATH;
6942 lstrcpyA(buf, "apple");
6943 r = pMsiGetProductInfoExA(prodcode, usersid,
6944 MSIINSTALLCONTEXT_USERMANAGED,
6945 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6946 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6947 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6948 ok(sz == 1, "Expected 1, got %d\n", sz);
6949
6950 delete_key(userkey, "", access & KEY_WOW64_64KEY);
6951 RegCloseKey(userkey);
6952
6953 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6954 lstrcatA(keypath, prod_squashed);
6955
6956 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6958
6959 /* current user product key exists */
6960 sz = MAX_PATH;
6961 lstrcpyA(buf, "apple");
6962 r = pMsiGetProductInfoExA(prodcode, usersid,
6963 MSIINSTALLCONTEXT_USERMANAGED,
6964 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6965 ok(r == ERROR_UNKNOWN_PRODUCT,
6966 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6967 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6968 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6969
6970 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6971 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6972
6973 /* HelpLink value exists, user product key does not exist */
6974 sz = MAX_PATH;
6975 lstrcpyA(buf, "apple");
6976 r = pMsiGetProductInfoExA(prodcode, usersid,
6977 MSIINSTALLCONTEXT_USERMANAGED,
6978 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6979 ok(r == ERROR_UNKNOWN_PRODUCT,
6980 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6981 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6982 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6983
6984 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6985 lstrcatA(keypath, usersid);
6986 lstrcatA(keypath, "\\Installer\\Products\\");
6987 lstrcatA(keypath, prod_squashed);
6988
6989 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6990 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6991
6992 res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6993 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6994
6995 /* HelpLink value exists, user product key does exist */
6996 sz = MAX_PATH;
6997 lstrcpyA(buf, "apple");
6998 r = pMsiGetProductInfoExA(prodcode, usersid,
6999 MSIINSTALLCONTEXT_USERMANAGED,
7000 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7001 ok(r == ERROR_UNKNOWN_PROPERTY,
7002 "Expected ERROR_UNKNOWN_PROPERTY, 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 res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7007 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7008
7009 /* HelpTelephone value exists */
7010 sz = MAX_PATH;
7011 lstrcpyA(buf, "apple");
7012 r = pMsiGetProductInfoExA(prodcode, usersid,
7013 MSIINSTALLCONTEXT_USERMANAGED,
7014 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7015 ok(r == ERROR_UNKNOWN_PROPERTY,
7016 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7017 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7018 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7019
7020 res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7021 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7022
7023 /* InstallDate value exists */
7024 sz = MAX_PATH;
7025 lstrcpyA(buf, "apple");
7026 r = pMsiGetProductInfoExA(prodcode, usersid,
7027 MSIINSTALLCONTEXT_USERMANAGED,
7028 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7029 ok(r == ERROR_UNKNOWN_PROPERTY,
7030 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7031 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7032 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7033
7034 res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7035 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7036
7037 /* DisplayName value exists */
7038 sz = MAX_PATH;
7039 lstrcpyA(buf, "apple");
7040 r = pMsiGetProductInfoExA(prodcode, usersid,
7041 MSIINSTALLCONTEXT_USERMANAGED,
7042 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7043 ok(r == ERROR_UNKNOWN_PROPERTY,
7044 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7045 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7046 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7047
7048 res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7049 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7050
7051 /* InstallLocation value exists */
7052 sz = MAX_PATH;
7053 lstrcpyA(buf, "apple");
7054 r = pMsiGetProductInfoExA(prodcode, usersid,
7055 MSIINSTALLCONTEXT_USERMANAGED,
7056 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7057 ok(r == ERROR_UNKNOWN_PROPERTY,
7058 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7059 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7060 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7061
7062 res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7063 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7064
7065 /* InstallSource value exists */
7066 sz = MAX_PATH;
7067 lstrcpyA(buf, "apple");
7068 r = pMsiGetProductInfoExA(prodcode, usersid,
7069 MSIINSTALLCONTEXT_USERMANAGED,
7070 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7071 ok(r == ERROR_UNKNOWN_PROPERTY,
7072 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7073 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7074 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7075
7076 res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7077 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7078
7079 /* LocalPackage value exists */
7080 sz = MAX_PATH;
7081 lstrcpyA(buf, "apple");
7082 r = pMsiGetProductInfoExA(prodcode, usersid,
7083 MSIINSTALLCONTEXT_USERMANAGED,
7084 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7085 ok(r == ERROR_UNKNOWN_PROPERTY,
7086 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7087 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7088 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7089
7090 res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7091 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7092
7093 /* Publisher value exists */
7094 sz = MAX_PATH;
7095 lstrcpyA(buf, "apple");
7096 r = pMsiGetProductInfoExA(prodcode, usersid,
7097 MSIINSTALLCONTEXT_USERMANAGED,
7098 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7099 ok(r == ERROR_UNKNOWN_PROPERTY,
7100 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7101 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7102 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7103
7104 res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7105 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7106
7107 /* URLInfoAbout value exists */
7108 sz = MAX_PATH;
7109 lstrcpyA(buf, "apple");
7110 r = pMsiGetProductInfoExA(prodcode, usersid,
7111 MSIINSTALLCONTEXT_USERMANAGED,
7112 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7113 ok(r == ERROR_UNKNOWN_PROPERTY,
7114 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7115 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7116 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7117
7118 res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7120
7121 /* URLUpdateInfo value exists */
7122 sz = MAX_PATH;
7123 lstrcpyA(buf, "apple");
7124 r = pMsiGetProductInfoExA(prodcode, usersid,
7125 MSIINSTALLCONTEXT_USERMANAGED,
7126 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7127 ok(r == ERROR_UNKNOWN_PROPERTY,
7128 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7129 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7130 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7131
7132 res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7133 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7134
7135 /* VersionMinor value exists */
7136 sz = MAX_PATH;
7137 lstrcpyA(buf, "apple");
7138 r = pMsiGetProductInfoExA(prodcode, usersid,
7139 MSIINSTALLCONTEXT_USERMANAGED,
7140 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7141 ok(r == ERROR_UNKNOWN_PROPERTY,
7142 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7143 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7144 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7145
7146 res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7147 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7148
7149 /* VersionMajor value exists */
7150 sz = MAX_PATH;
7151 lstrcpyA(buf, "apple");
7152 r = pMsiGetProductInfoExA(prodcode, usersid,
7153 MSIINSTALLCONTEXT_USERMANAGED,
7154 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7155 ok(r == ERROR_UNKNOWN_PROPERTY,
7156 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7157 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7158 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7159
7160 res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7161 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7162
7163 /* DisplayVersion value exists */
7164 sz = MAX_PATH;
7165 lstrcpyA(buf, "apple");
7166 r = pMsiGetProductInfoExA(prodcode, usersid,
7167 MSIINSTALLCONTEXT_USERMANAGED,
7168 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7169 ok(r == ERROR_UNKNOWN_PROPERTY,
7170 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7171 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7172 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7173
7174 res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7175 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7176
7177 /* ProductID value exists */
7178 sz = MAX_PATH;
7179 lstrcpyA(buf, "apple");
7180 r = pMsiGetProductInfoExA(prodcode, usersid,
7181 MSIINSTALLCONTEXT_USERMANAGED,
7182 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7183 ok(r == ERROR_UNKNOWN_PROPERTY,
7184 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7185 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7186 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7187
7188 res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7190
7191 /* RegCompany value exists */
7192 sz = MAX_PATH;
7193 lstrcpyA(buf, "apple");
7194 r = pMsiGetProductInfoExA(prodcode, usersid,
7195 MSIINSTALLCONTEXT_USERMANAGED,
7196 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7197 ok(r == ERROR_UNKNOWN_PROPERTY,
7198 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7199 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7200 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7201
7202 res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7203 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7204
7205 /* RegOwner value exists */
7206 sz = MAX_PATH;
7207 lstrcpyA(buf, "apple");
7208 r = pMsiGetProductInfoExA(prodcode, usersid,
7209 MSIINSTALLCONTEXT_USERMANAGED,
7210 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7211 ok(r == ERROR_UNKNOWN_PROPERTY,
7212 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7213 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7214 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7215
7216 res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7217 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7218
7219 /* Transforms value exists */
7220 sz = MAX_PATH;
7221 lstrcpyA(buf, "apple");
7222 r = pMsiGetProductInfoExA(prodcode, usersid,
7223 MSIINSTALLCONTEXT_USERMANAGED,
7224 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7226 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
7227 ok(sz == 5, "Expected 5, got %d\n", sz);
7228
7229 res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7230 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7231
7232 /* Language value exists */
7233 sz = MAX_PATH;
7234 lstrcpyA(buf, "apple");
7235 r = pMsiGetProductInfoExA(prodcode, usersid,
7236 MSIINSTALLCONTEXT_USERMANAGED,
7237 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7238 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7239 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
7240 ok(sz == 4, "Expected 4, got %d\n", sz);
7241
7242 res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7243 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7244
7245 /* ProductName value exists */
7246 sz = MAX_PATH;
7247 lstrcpyA(buf, "apple");
7248 r = pMsiGetProductInfoExA(prodcode, usersid,
7249 MSIINSTALLCONTEXT_USERMANAGED,
7250 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7251 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7252 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7253 ok(sz == 4, "Expected 4, got %d\n", sz);
7254
7255 res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7256 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7257
7258 /* FIXME */
7259
7260 /* AssignmentType value exists */
7261 sz = MAX_PATH;
7262 lstrcpyA(buf, "apple");
7263 r = pMsiGetProductInfoExA(prodcode, usersid,
7264 MSIINSTALLCONTEXT_USERMANAGED,
7265 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7267 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7268 ok(sz == 0, "Expected 0, got %d\n", sz);
7269
7270 res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7272
7273 /* FIXME */
7274
7275 /* PackageCode value exists */
7276 sz = MAX_PATH;
7277 lstrcpyA(buf, "apple");
7278 r = pMsiGetProductInfoExA(prodcode, usersid,
7279 MSIINSTALLCONTEXT_USERMANAGED,
7280 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7281 todo_wine
7282 {
7283 ok(r == ERROR_BAD_CONFIGURATION,
7284 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7285 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7286 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7287 }
7288
7289 res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7290 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7291
7292 /* Version value exists */
7293 sz = MAX_PATH;
7294 lstrcpyA(buf, "apple");
7295 r = pMsiGetProductInfoExA(prodcode, usersid,
7296 MSIINSTALLCONTEXT_USERMANAGED,
7297 INSTALLPROPERTY_VERSIONA, buf, &sz);
7298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7299 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7300 ok(sz == 3, "Expected 3, got %d\n", sz);
7301
7302 res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7303 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7304
7305 /* ProductIcon value exists */
7306 sz = MAX_PATH;
7307 lstrcpyA(buf, "apple");
7308 r = pMsiGetProductInfoExA(prodcode, usersid,
7309 MSIINSTALLCONTEXT_USERMANAGED,
7310 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7312 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7313 ok(sz == 4, "Expected 4, got %d\n", sz);
7314
7315 res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7316 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7317
7318 /* PackageName value exists */
7319 sz = MAX_PATH;
7320 lstrcpyA(buf, "apple");
7321 r = pMsiGetProductInfoExA(prodcode, usersid,
7322 MSIINSTALLCONTEXT_USERMANAGED,
7323 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7324 todo_wine
7325 {
7326 ok(r == ERROR_UNKNOWN_PRODUCT,
7327 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7328 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7329 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7330 }
7331
7332 res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7333 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7334
7335 /* AuthorizedLUAApp value exists */
7336 sz = MAX_PATH;
7337 lstrcpyA(buf, "apple");
7338 r = pMsiGetProductInfoExA(prodcode, usersid,
7339 MSIINSTALLCONTEXT_USERMANAGED,
7340 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7342 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7343 ok(sz == 4, "Expected 4, got %d\n", sz);
7344
7345 RegDeleteValueA(userkey, "AuthorizedLUAApp");
7346 RegDeleteValueA(userkey, "PackageName");
7347 RegDeleteValueA(userkey, "ProductIcon");
7348 RegDeleteValueA(userkey, "Version");
7349 RegDeleteValueA(userkey, "PackageCode");
7350 RegDeleteValueA(userkey, "AssignmentType");
7351 RegDeleteValueA(userkey, "ProductName");
7352 RegDeleteValueA(userkey, "Language");
7353 RegDeleteValueA(userkey, "Transforms");
7354 RegDeleteValueA(userkey, "RegOwner");
7355 RegDeleteValueA(userkey, "RegCompany");
7356 RegDeleteValueA(userkey, "ProductID");
7357 RegDeleteValueA(userkey, "DisplayVersion");
7358 RegDeleteValueA(userkey, "VersionMajor");
7359 RegDeleteValueA(userkey, "VersionMinor");
7360 RegDeleteValueA(userkey, "URLUpdateInfo");
7361 RegDeleteValueA(userkey, "URLInfoAbout");
7362 RegDeleteValueA(userkey, "Publisher");
7363 RegDeleteValueA(userkey, "LocalPackage");
7364 RegDeleteValueA(userkey, "InstallSource");
7365 RegDeleteValueA(userkey, "InstallLocation");
7366 RegDeleteValueA(userkey, "DisplayName");
7367 RegDeleteValueA(userkey, "InstallDate");
7368 RegDeleteValueA(userkey, "HelpTelephone");
7369 RegDeleteValueA(userkey, "HelpLink");
7370 delete_key(userkey, "", access & KEY_WOW64_64KEY);
7371 RegCloseKey(userkey);
7372 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7373 RegCloseKey(prodkey);
7374
7375 /* MSIINSTALLCONTEXT_MACHINE */
7376
7377 /* szUserSid is non-NULL */
7378 sz = MAX_PATH;
7379 lstrcpyA(buf, "apple");
7380 r = pMsiGetProductInfoExA(prodcode, usersid,
7381 MSIINSTALLCONTEXT_MACHINE,
7382 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7383 ok(r == ERROR_INVALID_PARAMETER,
7384 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7385 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7386 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7387
7388 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
7389 lstrcatA(keypath, prod_squashed);
7390
7391 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
7392 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7393
7394 /* local system product key exists */
7395 sz = MAX_PATH;
7396 lstrcpyA(buf, "apple");
7397 r = pMsiGetProductInfoExA(prodcode, NULL,
7398 MSIINSTALLCONTEXT_MACHINE,
7399 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7400 ok(r == ERROR_UNKNOWN_PRODUCT,
7401 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7402 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7403 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7404
7405 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
7406 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7407
7408 /* InstallProperties key exists */
7409 sz = MAX_PATH;
7410 lstrcpyA(buf, "apple");
7411 r = pMsiGetProductInfoExA(prodcode, NULL,
7412 MSIINSTALLCONTEXT_MACHINE,
7413 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7414 ok(r == ERROR_UNKNOWN_PRODUCT,
7415 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7416 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7417 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7418
7419 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7421
7422 /* LocalPackage value exists */
7423 sz = MAX_PATH;
7424 lstrcpyA(buf, "apple");
7425 r = pMsiGetProductInfoExA(prodcode, NULL,
7426 MSIINSTALLCONTEXT_MACHINE,
7427 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7429 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
7430 ok(sz == 1, "Expected 1, got %d\n", sz);
7431
7432 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7433 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7434
7435 /* HelpLink value exists */
7436 sz = MAX_PATH;
7437 lstrcpyA(buf, "apple");
7438 r = pMsiGetProductInfoExA(prodcode, NULL,
7439 MSIINSTALLCONTEXT_MACHINE,
7440 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7442 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
7443 ok(sz == 4, "Expected 4, got %d\n", sz);
7444
7445 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7446 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7447
7448 /* HelpTelephone value exists */
7449 sz = MAX_PATH;
7450 lstrcpyA(buf, "apple");
7451 r = pMsiGetProductInfoExA(prodcode, NULL,
7452 MSIINSTALLCONTEXT_MACHINE,
7453 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7454 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7455 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
7456 ok(sz == 5, "Expected 5, got %d\n", sz);
7457
7458 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7459 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7460
7461 /* InstallDate value exists */
7462 sz = MAX_PATH;
7463 lstrcpyA(buf, "apple");
7464 r = pMsiGetProductInfoExA(prodcode, NULL,
7465 MSIINSTALLCONTEXT_MACHINE,
7466 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7467 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7468 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
7469 ok(sz == 4, "Expected 4, got %d\n", sz);
7470
7471 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7472 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7473
7474 /* DisplayName value exists */
7475 sz = MAX_PATH;
7476 lstrcpyA(buf, "apple");
7477 r = pMsiGetProductInfoExA(prodcode, NULL,
7478 MSIINSTALLCONTEXT_MACHINE,
7479 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7481 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7482 ok(sz == 4, "Expected 4, got %d\n", sz);
7483
7484 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7485 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7486
7487 /* InstallLocation value exists */
7488 sz = MAX_PATH;
7489 lstrcpyA(buf, "apple");
7490 r = pMsiGetProductInfoExA(prodcode, NULL,
7491 MSIINSTALLCONTEXT_MACHINE,
7492 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7494 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
7495 ok(sz == 3, "Expected 3, got %d\n", sz);
7496
7497 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7498 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7499
7500 /* InstallSource value exists */
7501 sz = MAX_PATH;
7502 lstrcpyA(buf, "apple");
7503 r = pMsiGetProductInfoExA(prodcode, NULL,
7504 MSIINSTALLCONTEXT_MACHINE,
7505 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7506 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7507 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
7508 ok(sz == 6, "Expected 6, got %d\n", sz);
7509
7510 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7511 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7512
7513 /* LocalPackage value exists */
7514 sz = MAX_PATH;
7515 lstrcpyA(buf, "apple");
7516 r = pMsiGetProductInfoExA(prodcode, NULL,
7517 MSIINSTALLCONTEXT_MACHINE,
7518 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7520 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
7521 ok(sz == 5, "Expected 5, got %d\n", sz);
7522
7523 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7524 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7525
7526 /* Publisher value exists */
7527 sz = MAX_PATH;
7528 lstrcpyA(buf, "apple");
7529 r = pMsiGetProductInfoExA(prodcode, NULL,
7530 MSIINSTALLCONTEXT_MACHINE,
7531 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7533 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
7534 ok(sz == 3, "Expected 3, got %d\n", sz);
7535
7536 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7537 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7538
7539 /* URLInfoAbout value exists */
7540 sz = MAX_PATH;
7541 lstrcpyA(buf, "apple");
7542 r = pMsiGetProductInfoExA(prodcode, NULL,
7543 MSIINSTALLCONTEXT_MACHINE,
7544 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7545 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7546 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
7547 ok(sz == 5, "Expected 5, got %d\n", sz);
7548
7549 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7550 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7551
7552 /* URLUpdateInfo value exists */
7553 sz = MAX_PATH;
7554 lstrcpyA(buf, "apple");
7555 r = pMsiGetProductInfoExA(prodcode, NULL,
7556 MSIINSTALLCONTEXT_MACHINE,
7557 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7558 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7559 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
7560 ok(sz == 6, "Expected 6, got %d\n", sz);
7561
7562 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7563 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7564
7565 /* VersionMinor value exists */
7566 sz = MAX_PATH;
7567 lstrcpyA(buf, "apple");
7568 r = pMsiGetProductInfoExA(prodcode, NULL,
7569 MSIINSTALLCONTEXT_MACHINE,
7570 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7571 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7572 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
7573 ok(sz == 1, "Expected 1, got %d\n", sz);
7574
7575 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7576 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7577
7578 /* VersionMajor value exists */
7579 sz = MAX_PATH;
7580 lstrcpyA(buf, "apple");
7581 r = pMsiGetProductInfoExA(prodcode, NULL,
7582 MSIINSTALLCONTEXT_MACHINE,
7583 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7584 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7585 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
7586 ok(sz == 1, "Expected 1, got %d\n", sz);
7587
7588 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7589 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7590
7591 /* DisplayVersion value exists */
7592 sz = MAX_PATH;
7593 lstrcpyA(buf, "apple");
7594 r = pMsiGetProductInfoExA(prodcode, NULL,
7595 MSIINSTALLCONTEXT_MACHINE,
7596 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7598 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
7599 ok(sz == 5, "Expected 5, got %d\n", sz);
7600
7601 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7602 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7603
7604 /* ProductID value exists */
7605 sz = MAX_PATH;
7606 lstrcpyA(buf, "apple");
7607 r = pMsiGetProductInfoExA(prodcode, NULL,
7608 MSIINSTALLCONTEXT_MACHINE,
7609 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7610 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7611 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
7612 ok(sz == 2, "Expected 2, got %d\n", sz);
7613
7614 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7615 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7616
7617 /* RegCompany value exists */
7618 sz = MAX_PATH;
7619 lstrcpyA(buf, "apple");
7620 r = pMsiGetProductInfoExA(prodcode, NULL,
7621 MSIINSTALLCONTEXT_MACHINE,
7622 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7624 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
7625 ok(sz == 4, "Expected 4, got %d\n", sz);
7626
7627 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7628 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7629
7630 /* RegOwner value exists */
7631 sz = MAX_PATH;
7632 lstrcpyA(buf, "apple");
7633 r = pMsiGetProductInfoExA(prodcode, NULL,
7634 MSIINSTALLCONTEXT_MACHINE,
7635 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7637 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
7638 ok(sz == 5, "Expected 5, got %d\n", sz);
7639
7640 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7641 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7642
7643 /* Transforms value exists */
7644 sz = MAX_PATH;
7645 lstrcpyA(buf, "apple");
7646 r = pMsiGetProductInfoExA(prodcode, NULL,
7647 MSIINSTALLCONTEXT_MACHINE,
7648 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7649 ok(r == ERROR_UNKNOWN_PRODUCT,
7650 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7651 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7652 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7653
7654 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7655 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7656
7657 /* Language value exists */
7658 sz = MAX_PATH;
7659 lstrcpyA(buf, "apple");
7660 r = pMsiGetProductInfoExA(prodcode, NULL,
7661 MSIINSTALLCONTEXT_MACHINE,
7662 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7663 ok(r == ERROR_UNKNOWN_PRODUCT,
7664 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7665 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7666 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7667
7668 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7669 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7670
7671 /* ProductName value exists */
7672 sz = MAX_PATH;
7673 lstrcpyA(buf, "apple");
7674 r = pMsiGetProductInfoExA(prodcode, NULL,
7675 MSIINSTALLCONTEXT_MACHINE,
7676 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7677 ok(r == ERROR_UNKNOWN_PRODUCT,
7678 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7679 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7680 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7681
7682 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7684
7685 /* FIXME */
7686
7687 /* AssignmentType value exists */
7688 sz = MAX_PATH;
7689 lstrcpyA(buf, "apple");
7690 r = pMsiGetProductInfoExA(prodcode, NULL,
7691 MSIINSTALLCONTEXT_MACHINE,
7692 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7693 ok(r == ERROR_UNKNOWN_PRODUCT,
7694 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7695 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7696 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7697
7698 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7699 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7700
7701 /* PackageCode value exists */
7702 sz = MAX_PATH;
7703 lstrcpyA(buf, "apple");
7704 r = pMsiGetProductInfoExA(prodcode, NULL,
7705 MSIINSTALLCONTEXT_MACHINE,
7706 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7707 ok(r == ERROR_UNKNOWN_PRODUCT,
7708 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7709 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7710 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7711
7712 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7713 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7714
7715 /* Version value exists */
7716 sz = MAX_PATH;
7717 lstrcpyA(buf, "apple");
7718 r = pMsiGetProductInfoExA(prodcode, NULL,
7719 MSIINSTALLCONTEXT_MACHINE,
7720 INSTALLPROPERTY_VERSIONA, buf, &sz);
7721 ok(r == ERROR_UNKNOWN_PRODUCT,
7722 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7723 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7724 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7725
7726 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7727 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7728
7729 /* ProductIcon value exists */
7730 sz = MAX_PATH;
7731 lstrcpyA(buf, "apple");
7732 r = pMsiGetProductInfoExA(prodcode, NULL,
7733 MSIINSTALLCONTEXT_MACHINE,
7734 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7735 ok(r == ERROR_UNKNOWN_PRODUCT,
7736 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7737 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7738 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7739
7740 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7741 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7742
7743 /* PackageName value exists */
7744 sz = MAX_PATH;
7745 lstrcpyA(buf, "apple");
7746 r = pMsiGetProductInfoExA(prodcode, NULL,
7747 MSIINSTALLCONTEXT_MACHINE,
7748 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7749 ok(r == ERROR_UNKNOWN_PRODUCT,
7750 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7751 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7752 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7753
7754 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7755 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7756
7757 /* AuthorizedLUAApp value exists */
7758 sz = MAX_PATH;
7759 lstrcpyA(buf, "apple");
7760 r = pMsiGetProductInfoExA(prodcode, NULL,
7761 MSIINSTALLCONTEXT_MACHINE,
7762 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7763 ok(r == ERROR_UNKNOWN_PRODUCT,
7764 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7765 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7766 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7767
7768 RegDeleteValueA(propkey, "AuthorizedLUAApp");
7769 RegDeleteValueA(propkey, "PackageName");
7770 RegDeleteValueA(propkey, "ProductIcon");
7771 RegDeleteValueA(propkey, "Version");
7772 RegDeleteValueA(propkey, "PackageCode");
7773 RegDeleteValueA(propkey, "AssignmentType");
7774 RegDeleteValueA(propkey, "ProductName");
7775 RegDeleteValueA(propkey, "Language");
7776 RegDeleteValueA(propkey, "Transforms");
7777 RegDeleteValueA(propkey, "RegOwner");
7778 RegDeleteValueA(propkey, "RegCompany");
7779 RegDeleteValueA(propkey, "ProductID");
7780 RegDeleteValueA(propkey, "DisplayVersion");
7781 RegDeleteValueA(propkey, "VersionMajor");
7782 RegDeleteValueA(propkey, "VersionMinor");
7783 RegDeleteValueA(propkey, "URLUpdateInfo");
7784 RegDeleteValueA(propkey, "URLInfoAbout");
7785 RegDeleteValueA(propkey, "Publisher");
7786 RegDeleteValueA(propkey, "LocalPackage");
7787 RegDeleteValueA(propkey, "InstallSource");
7788 RegDeleteValueA(propkey, "InstallLocation");
7789 RegDeleteValueA(propkey, "DisplayName");
7790 RegDeleteValueA(propkey, "InstallDate");
7791 RegDeleteValueA(propkey, "HelpTelephone");
7792 RegDeleteValueA(propkey, "HelpLink");
7793 RegDeleteValueA(propkey, "LocalPackage");
7794 delete_key(propkey, "", access & KEY_WOW64_64KEY);
7795 RegCloseKey(propkey);
7796 delete_key(localkey, "", access & KEY_WOW64_64KEY);
7797 RegCloseKey(localkey);
7798
7799 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7800 lstrcatA(keypath, prod_squashed);
7801
7802 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7803 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7804
7805 /* local classes product key exists */
7806 sz = MAX_PATH;
7807 lstrcpyA(buf, "apple");
7808 r = pMsiGetProductInfoExA(prodcode, NULL,
7809 MSIINSTALLCONTEXT_MACHINE,
7810 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7811 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7812 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
7813 ok(sz == 1, "Expected 1, got %d\n", sz);
7814
7815 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7816 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7817
7818 /* HelpLink value exists */
7819 sz = MAX_PATH;
7820 lstrcpyA(buf, "apple");
7821 r = pMsiGetProductInfoExA(prodcode, NULL,
7822 MSIINSTALLCONTEXT_MACHINE,
7823 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7824 ok(r == ERROR_UNKNOWN_PROPERTY,
7825 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7826 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7827 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7828
7829 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7830 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7831
7832 /* HelpTelephone value exists */
7833 sz = MAX_PATH;
7834 lstrcpyA(buf, "apple");
7835 r = pMsiGetProductInfoExA(prodcode, NULL,
7836 MSIINSTALLCONTEXT_MACHINE,
7837 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7838 ok(r == ERROR_UNKNOWN_PROPERTY,
7839 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7840 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7841 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7842
7843 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7844 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7845
7846 /* InstallDate value exists */
7847 sz = MAX_PATH;
7848 lstrcpyA(buf, "apple");
7849 r = pMsiGetProductInfoExA(prodcode, NULL,
7850 MSIINSTALLCONTEXT_MACHINE,
7851 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7852 ok(r == ERROR_UNKNOWN_PROPERTY,
7853 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7854 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7855 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7856
7857 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7858 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7859
7860 /* DisplayName value exists */
7861 sz = MAX_PATH;
7862 lstrcpyA(buf, "apple");
7863 r = pMsiGetProductInfoExA(prodcode, NULL,
7864 MSIINSTALLCONTEXT_MACHINE,
7865 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7866 ok(r == ERROR_UNKNOWN_PROPERTY,
7867 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7868 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7869 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7870
7871 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7872 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7873
7874 /* InstallLocation value exists */
7875 sz = MAX_PATH;
7876 lstrcpyA(buf, "apple");
7877 r = pMsiGetProductInfoExA(prodcode, NULL,
7878 MSIINSTALLCONTEXT_MACHINE,
7879 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7880 ok(r == ERROR_UNKNOWN_PROPERTY,
7881 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7882 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7883 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7884
7885 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7886 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7887
7888 /* InstallSource value exists */
7889 sz = MAX_PATH;
7890 lstrcpyA(buf, "apple");
7891 r = pMsiGetProductInfoExA(prodcode, NULL,
7892 MSIINSTALLCONTEXT_MACHINE,
7893 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7894 ok(r == ERROR_UNKNOWN_PROPERTY,
7895 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7896 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7897 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7898
7899 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7900 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7901
7902 /* LocalPackage value exists */
7903 sz = MAX_PATH;
7904 lstrcpyA(buf, "apple");
7905 r = pMsiGetProductInfoExA(prodcode, NULL,
7906 MSIINSTALLCONTEXT_MACHINE,
7907 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7908 ok(r == ERROR_UNKNOWN_PROPERTY,
7909 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7910 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7911 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7912
7913 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7914 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7915
7916 /* Publisher value exists */
7917 sz = MAX_PATH;
7918 lstrcpyA(buf, "apple");
7919 r = pMsiGetProductInfoExA(prodcode, NULL,
7920 MSIINSTALLCONTEXT_MACHINE,
7921 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7922 ok(r == ERROR_UNKNOWN_PROPERTY,
7923 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7924 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7925 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7926
7927 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7928 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7929
7930 /* URLInfoAbout value exists */
7931 sz = MAX_PATH;
7932 lstrcpyA(buf, "apple");
7933 r = pMsiGetProductInfoExA(prodcode, NULL,
7934 MSIINSTALLCONTEXT_MACHINE,
7935 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7936 ok(r == ERROR_UNKNOWN_PROPERTY,
7937 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7938 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7939 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7940
7941 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7942 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7943
7944 /* URLUpdateInfo value exists */
7945 sz = MAX_PATH;
7946 lstrcpyA(buf, "apple");
7947 r = pMsiGetProductInfoExA(prodcode, NULL,
7948 MSIINSTALLCONTEXT_MACHINE,
7949 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7950 ok(r == ERROR_UNKNOWN_PROPERTY,
7951 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7952 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7953 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7954
7955 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7956 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7957
7958 /* VersionMinor value exists */
7959 sz = MAX_PATH;
7960 lstrcpyA(buf, "apple");
7961 r = pMsiGetProductInfoExA(prodcode, NULL,
7962 MSIINSTALLCONTEXT_MACHINE,
7963 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7964 ok(r == ERROR_UNKNOWN_PROPERTY,
7965 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7966 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7967 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7968
7969 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7970 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7971
7972 /* VersionMajor value exists */
7973 sz = MAX_PATH;
7974 lstrcpyA(buf, "apple");
7975 r = pMsiGetProductInfoExA(prodcode, NULL,
7976 MSIINSTALLCONTEXT_MACHINE,
7977 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7978 ok(r == ERROR_UNKNOWN_PROPERTY,
7979 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7980 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7981 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7982
7983 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7984 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7985
7986 /* DisplayVersion value exists */
7987 sz = MAX_PATH;
7988 lstrcpyA(buf, "apple");
7989 r = pMsiGetProductInfoExA(prodcode, NULL,
7990 MSIINSTALLCONTEXT_MACHINE,
7991 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7992 ok(r == ERROR_UNKNOWN_PROPERTY,
7993 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7994 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7995 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7996
7997 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7998 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7999
8000 /* ProductID value exists */
8001 sz = MAX_PATH;
8002 lstrcpyA(buf, "apple");
8003 r = pMsiGetProductInfoExA(prodcode, NULL,
8004 MSIINSTALLCONTEXT_MACHINE,
8005 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
8006 ok(r == ERROR_UNKNOWN_PROPERTY,
8007 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8008 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8009 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8010
8011 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
8012 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8013
8014 /* RegCompany value exists */
8015 sz = MAX_PATH;
8016 lstrcpyA(buf, "apple");
8017 r = pMsiGetProductInfoExA(prodcode, NULL,
8018 MSIINSTALLCONTEXT_MACHINE,
8019 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
8020 ok(r == ERROR_UNKNOWN_PROPERTY,
8021 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8022 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8023 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8024
8025 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8026 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8027
8028 /* RegOwner value exists */
8029 sz = MAX_PATH;
8030 lstrcpyA(buf, "apple");
8031 r = pMsiGetProductInfoExA(prodcode, NULL,
8032 MSIINSTALLCONTEXT_MACHINE,
8033 INSTALLPROPERTY_REGOWNERA, buf, &sz);
8034 ok(r == ERROR_UNKNOWN_PROPERTY,
8035 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8036 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8037 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8038
8039 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
8040 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8041
8042 /* Transforms value exists */
8043 sz = MAX_PATH;
8044 lstrcpyA(buf, "apple");
8045 r = pMsiGetProductInfoExA(prodcode, NULL,
8046 MSIINSTALLCONTEXT_MACHINE,
8047 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
8048 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8049 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
8050 ok(sz == 5, "Expected 5, got %d\n", sz);
8051
8052 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
8053 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8054
8055 /* Language value exists */
8056 sz = MAX_PATH;
8057 lstrcpyA(buf, "apple");
8058 r = pMsiGetProductInfoExA(prodcode, NULL,
8059 MSIINSTALLCONTEXT_MACHINE,
8060 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
8061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8062 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
8063 ok(sz == 4, "Expected 4, got %d\n", sz);
8064
8065 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
8066 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8067
8068 /* ProductName value exists */
8069 sz = MAX_PATH;
8070 lstrcpyA(buf, "apple");
8071 r = pMsiGetProductInfoExA(prodcode, NULL,
8072 MSIINSTALLCONTEXT_MACHINE,
8073 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
8074 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8075 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
8076 ok(sz == 4, "Expected 4, got %d\n", sz);
8077
8078 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
8079 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8080
8081 /* FIXME */
8082
8083 /* AssignmentType value exists */
8084 sz = MAX_PATH;
8085 lstrcpyA(buf, "apple");
8086 r = pMsiGetProductInfoExA(prodcode, NULL,
8087 MSIINSTALLCONTEXT_MACHINE,
8088 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
8089 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8090 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8091 ok(sz == 0, "Expected 0, got %d\n", sz);
8092
8093 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
8094 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8095
8096 /* FIXME */
8097
8098 /* PackageCode value exists */
8099 sz = MAX_PATH;
8100 lstrcpyA(buf, "apple");
8101 r = pMsiGetProductInfoExA(prodcode, NULL,
8102 MSIINSTALLCONTEXT_MACHINE,
8103 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
8104 todo_wine
8105 {
8106 ok(r == ERROR_BAD_CONFIGURATION,
8107 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8108 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8109 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8110 }
8111
8112 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
8113 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8114
8115 /* Version value exists */
8116 sz = MAX_PATH;
8117 lstrcpyA(buf, "apple");
8118 r = pMsiGetProductInfoExA(prodcode, NULL,
8119 MSIINSTALLCONTEXT_MACHINE,
8120 INSTALLPROPERTY_VERSIONA, buf, &sz);
8121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8122 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
8123 ok(sz == 3, "Expected 3, got %d\n", sz);
8124
8125 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
8126 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8127
8128 /* ProductIcon value exists */
8129 sz = MAX_PATH;
8130 lstrcpyA(buf, "apple");
8131 r = pMsiGetProductInfoExA(prodcode, NULL,
8132 MSIINSTALLCONTEXT_MACHINE,
8133 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
8134 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8135 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
8136 ok(sz == 4, "Expected 4, got %d\n", sz);
8137
8138 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
8139 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8140
8141 /* PackageName value exists */
8142 sz = MAX_PATH;
8143 lstrcpyA(buf, "apple");
8144 r = pMsiGetProductInfoExA(prodcode, NULL,
8145 MSIINSTALLCONTEXT_MACHINE,
8146 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
8147 todo_wine
8148 {
8149 ok(r == ERROR_UNKNOWN_PRODUCT,
8150 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8151 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8152 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8153 }
8154
8155 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
8156 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8157
8158 /* AuthorizedLUAApp value exists */
8159 sz = MAX_PATH;
8160 lstrcpyA(buf, "apple");
8161 r = pMsiGetProductInfoExA(prodcode, NULL,
8162 MSIINSTALLCONTEXT_MACHINE,
8163 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
8164 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8165 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
8166 ok(sz == 4, "Expected 4, got %d\n", sz);
8167
8168 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
8169 RegDeleteValueA(prodkey, "PackageName");
8170 RegDeleteValueA(prodkey, "ProductIcon");
8171 RegDeleteValueA(prodkey, "Version");
8172 RegDeleteValueA(prodkey, "PackageCode");
8173 RegDeleteValueA(prodkey, "AssignmentType");
8174 RegDeleteValueA(prodkey, "ProductName");
8175 RegDeleteValueA(prodkey, "Language");
8176 RegDeleteValueA(prodkey, "Transforms");
8177 RegDeleteValueA(prodkey, "RegOwner");
8178 RegDeleteValueA(prodkey, "RegCompany");
8179 RegDeleteValueA(prodkey, "ProductID");
8180 RegDeleteValueA(prodkey, "DisplayVersion");
8181 RegDeleteValueA(prodkey, "VersionMajor");
8182 RegDeleteValueA(prodkey, "VersionMinor");
8183 RegDeleteValueA(prodkey, "URLUpdateInfo");
8184 RegDeleteValueA(prodkey, "URLInfoAbout");
8185 RegDeleteValueA(prodkey, "Publisher");
8186 RegDeleteValueA(prodkey, "LocalPackage");
8187 RegDeleteValueA(prodkey, "InstallSource");
8188 RegDeleteValueA(prodkey, "InstallLocation");
8189 RegDeleteValueA(prodkey, "DisplayName");
8190 RegDeleteValueA(prodkey, "InstallDate");
8191 RegDeleteValueA(prodkey, "HelpTelephone");
8192 RegDeleteValueA(prodkey, "HelpLink");
8193 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8194 RegCloseKey(prodkey);
8195 LocalFree(usersid);
8196 }
8197
8198 #define INIT_USERINFO() \
8199 lstrcpyA(user, "apple"); \
8200 lstrcpyA(org, "orange"); \
8201 lstrcpyA(serial, "banana"); \
8202 usersz = orgsz = serialsz = MAX_PATH;
8203
8204 static void test_MsiGetUserInfo(void)
8205 {
8206 USERINFOSTATE state;
8207 CHAR user[MAX_PATH];
8208 CHAR org[MAX_PATH];
8209 CHAR serial[MAX_PATH];
8210 DWORD usersz, orgsz, serialsz;
8211 CHAR keypath[MAX_PATH * 2];
8212 CHAR prodcode[MAX_PATH];
8213 CHAR prod_squashed[MAX_PATH];
8214 HKEY prodkey, userprod, props;
8215 LPSTR usersid;
8216 LONG res;
8217 REGSAM access = KEY_ALL_ACCESS;
8218
8219 create_test_guid(prodcode, prod_squashed);
8220 usersid = get_user_sid();
8221
8222 if (is_wow64)
8223 access |= KEY_WOW64_64KEY;
8224
8225 /* NULL szProduct */
8226 INIT_USERINFO();
8227 state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
8228 ok(state == USERINFOSTATE_INVALIDARG,
8229 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8230 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8231 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8232 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8233 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8234 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8235 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8236
8237 /* empty szProductCode */
8238 INIT_USERINFO();
8239 state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
8240 ok(state == USERINFOSTATE_INVALIDARG,
8241 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8242 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8243 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8244 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8245 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8246 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8247 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8248
8249 /* garbage szProductCode */
8250 INIT_USERINFO();
8251 state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
8252 ok(state == USERINFOSTATE_INVALIDARG,
8253 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8254 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8255 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8256 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8257 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8258 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8259 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8260
8261 /* guid without brackets */
8262 INIT_USERINFO();
8263 state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
8264 user, &usersz, org, &orgsz, serial, &serialsz);
8265 ok(state == USERINFOSTATE_INVALIDARG,
8266 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8267 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8268 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8269 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8270 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8271 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8272 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8273
8274 /* guid with brackets */
8275 INIT_USERINFO();
8276 state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
8277 user, &usersz, org, &orgsz, serial, &serialsz);
8278 ok(state == USERINFOSTATE_UNKNOWN,
8279 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8280 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8281 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8282 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8283 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8284 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8285 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8286
8287 /* NULL lpUserNameBuf */
8288 INIT_USERINFO();
8289 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8290 ok(state == USERINFOSTATE_UNKNOWN,
8291 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8292 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8293 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8294 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8295 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8296 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8297
8298 /* NULL pcchUserNameBuf */
8299 INIT_USERINFO();
8300 state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
8301 ok(state == USERINFOSTATE_INVALIDARG,
8302 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8303 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8304 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8305 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8306 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8307 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8308
8309 /* both lpUserNameBuf and pcchUserNameBuf NULL */
8310 INIT_USERINFO();
8311 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8312 ok(state == USERINFOSTATE_UNKNOWN,
8313 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8314 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8315 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8316 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8317 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8318
8319 /* NULL lpOrgNameBuf */
8320 INIT_USERINFO();
8321 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
8322 ok(state == USERINFOSTATE_UNKNOWN,
8323 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8324 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8325 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8326 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8327 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8328 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8329
8330 /* NULL pcchOrgNameBuf */
8331 INIT_USERINFO();
8332 state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
8333 ok(state == USERINFOSTATE_INVALIDARG,
8334 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8335 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8336 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8337 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8338 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8339 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8340
8341 /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
8342 INIT_USERINFO();
8343 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
8344 ok(state == USERINFOSTATE_UNKNOWN,
8345 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8346 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8347 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8348 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8349 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8350
8351 /* NULL lpSerialBuf */
8352 INIT_USERINFO();
8353 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
8354 ok(state == USERINFOSTATE_UNKNOWN,
8355 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8356 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8357 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8358 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8359 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8360 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8361
8362 /* NULL pcchSerialBuf */
8363 INIT_USERINFO();
8364 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
8365 ok(state == USERINFOSTATE_INVALIDARG,
8366 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8367 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8368 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8369 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8370 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8371 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8372
8373 /* both lpSerialBuf and pcchSerialBuf NULL */
8374 INIT_USERINFO();
8375 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
8376 ok(state == USERINFOSTATE_UNKNOWN,
8377 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8378 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8379 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8380 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8381 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8382
8383 /* MSIINSTALLCONTEXT_USERMANAGED */
8384
8385 /* create local system product key */
8386 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8387 lstrcatA(keypath, usersid);
8388 lstrcatA(keypath, "\\Installer\\Products\\");
8389 lstrcatA(keypath, prod_squashed);
8390
8391 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8392 if (res == ERROR_ACCESS_DENIED)
8393 {
8394 skip("Not enough rights to perform tests\n");
8395 LocalFree(usersid);
8396 return;
8397 }
8398 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8399
8400 /* managed product key exists */
8401 INIT_USERINFO();
8402 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8403 ok(state == USERINFOSTATE_ABSENT,
8404 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8405 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8406 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8407 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8408 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8409 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8410 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8411
8412 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8413 lstrcatA(keypath, "Installer\\UserData\\");
8414 lstrcatA(keypath, usersid);
8415 lstrcatA(keypath, "\\Products\\");
8416 lstrcatA(keypath, prod_squashed);
8417
8418 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8419 if (res == ERROR_ACCESS_DENIED)
8420 {
8421 skip("Not enough rights to perform tests\n");
8422 LocalFree(usersid);
8423 return;
8424 }
8425 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8426
8427 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8428 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8429
8430 /* InstallProperties key exists */
8431 INIT_USERINFO();
8432 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8433 ok(state == USERINFOSTATE_ABSENT,
8434 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8435 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8436 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8437 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8438 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8439 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8440 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8441
8442 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8443 INIT_USERINFO();
8444 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8445 ok(state == USERINFOSTATE_ABSENT,
8446 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8447 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8448 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8449 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8450 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8451
8452 /* RegOwner, RegCompany don't exist, out params are NULL */
8453 INIT_USERINFO();
8454 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8455 ok(state == USERINFOSTATE_ABSENT,
8456 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8457 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8458 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8459
8460 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8461 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8462
8463 /* RegOwner value exists */
8464 INIT_USERINFO();
8465 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8466 ok(state == USERINFOSTATE_ABSENT,
8467 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8468 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8469 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8470 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8471 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8472 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8473 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8474
8475 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8476 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8477
8478 /* RegCompany value exists */
8479 INIT_USERINFO();
8480 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8481 ok(state == USERINFOSTATE_ABSENT,
8482 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8483 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8484 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8485 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8486 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8487 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8488 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8489
8490 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8491 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8492
8493 /* ProductID value exists */
8494 INIT_USERINFO();
8495 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8496 ok(state == USERINFOSTATE_PRESENT,
8497 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8498 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8499 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8500 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8501 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8502 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8503 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8504
8505 /* pcchUserNameBuf is too small */
8506 INIT_USERINFO();
8507 usersz = 0;
8508 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8509 ok(state == USERINFOSTATE_MOREDATA,
8510 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8511 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8512 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8513 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8514 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8515 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8516 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8517
8518 /* pcchUserNameBuf has no room for NULL terminator */
8519 INIT_USERINFO();
8520 usersz = 5;
8521 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8522 ok(state == USERINFOSTATE_MOREDATA,
8523 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8524 todo_wine
8525 {
8526 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8527 }
8528 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8529 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8530 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8531 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8532 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8533
8534 /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
8535 INIT_USERINFO();
8536 usersz = 0;
8537 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8538 ok(state == USERINFOSTATE_PRESENT,
8539 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8540 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8541 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8542 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8543 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8544 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8545 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8546
8547 RegDeleteValueA(props, "ProductID");
8548 RegDeleteValueA(props, "RegCompany");
8549 RegDeleteValueA(props, "RegOwner");
8550 delete_key(props, "", access & KEY_WOW64_64KEY);
8551 RegCloseKey(props);
8552 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8553 RegCloseKey(userprod);
8554 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8555 RegCloseKey(prodkey);
8556
8557 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8558
8559 /* create local system product key */
8560 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8561 lstrcatA(keypath, prod_squashed);
8562
8563 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8564 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8565
8566 /* product key exists */
8567 INIT_USERINFO();
8568 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8569 ok(state == USERINFOSTATE_ABSENT,
8570 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8571 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8572 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8573 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8574 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8575 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8576 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8577
8578 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8579 lstrcatA(keypath, "Installer\\UserData\\");
8580 lstrcatA(keypath, usersid);
8581 lstrcatA(keypath, "\\Products\\");
8582 lstrcatA(keypath, prod_squashed);
8583
8584 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8585 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8586
8587 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8588 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8589
8590 /* InstallProperties key exists */
8591 INIT_USERINFO();
8592 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8593 ok(state == USERINFOSTATE_ABSENT,
8594 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8595 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8596 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8597 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8598 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8599 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8600 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8601
8602 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8603 INIT_USERINFO();
8604 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8605 ok(state == USERINFOSTATE_ABSENT,
8606 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8607 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8608 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8609 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8610 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8611
8612 /* RegOwner, RegCompany don't exist, out params are NULL */
8613 INIT_USERINFO();
8614 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8615 ok(state == USERINFOSTATE_ABSENT,
8616 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8617 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8618 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8619
8620 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8621 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8622
8623 /* RegOwner value exists */
8624 INIT_USERINFO();
8625 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8626 ok(state == USERINFOSTATE_ABSENT,
8627 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8628 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8629 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8630 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8631 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8632 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8633 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8634
8635 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8636 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8637
8638 /* RegCompany value exists */
8639 INIT_USERINFO();
8640 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8641 ok(state == USERINFOSTATE_ABSENT,
8642 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8643 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8644 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8645 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8646 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8647 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8648 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8649
8650 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8651 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8652
8653 /* ProductID value exists */
8654 INIT_USERINFO();
8655 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8656 ok(state == USERINFOSTATE_PRESENT,
8657 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8658 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8659 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8660 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8661 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8662 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8663 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8664
8665 RegDeleteValueA(props, "ProductID");
8666 RegDeleteValueA(props, "RegCompany");
8667 RegDeleteValueA(props, "RegOwner");
8668 delete_key(props, "", access & KEY_WOW64_64KEY);
8669 RegCloseKey(props);
8670 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8671 RegCloseKey(userprod);
8672 RegDeleteKeyA(prodkey, "");
8673 RegCloseKey(prodkey);
8674
8675 /* MSIINSTALLCONTEXT_MACHINE */
8676
8677 /* create local system product key */
8678 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8679 lstrcatA(keypath, prod_squashed);
8680
8681 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8682 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8683
8684 /* product key exists */
8685 INIT_USERINFO();
8686 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8687 ok(state == USERINFOSTATE_ABSENT,
8688 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8689 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8690 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8691 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8692 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8693 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8694 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8695
8696 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8697 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
8698 lstrcatA(keypath, "\\Products\\");
8699 lstrcatA(keypath, prod_squashed);
8700
8701 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8702 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8703
8704 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8705 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8706
8707 /* InstallProperties key exists */
8708 INIT_USERINFO();
8709 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8710 ok(state == USERINFOSTATE_ABSENT,
8711 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8712 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8713 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8714 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8715 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8716 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8717 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8718
8719 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8720 INIT_USERINFO();
8721 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8722 ok(state == USERINFOSTATE_ABSENT,
8723 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8724 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8725 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8726 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8727 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8728
8729 /* RegOwner, RegCompany don't exist, out params are NULL */
8730 INIT_USERINFO();
8731 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8732 ok(state == USERINFOSTATE_ABSENT,
8733 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8734 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8735 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8736
8737 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8738 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8739
8740 /* RegOwner value exists */
8741 INIT_USERINFO();
8742 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8743 ok(state == USERINFOSTATE_ABSENT,
8744 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8745 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8746 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8747 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8748 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8749 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8750 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8751
8752 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8753 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8754
8755 /* RegCompany value exists */
8756 INIT_USERINFO();
8757 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8758 ok(state == USERINFOSTATE_ABSENT,
8759 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8760 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8761 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8762 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8763 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8764 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8765 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8766
8767 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8768 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8769
8770 /* ProductID value exists */
8771 INIT_USERINFO();
8772 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8773 ok(state == USERINFOSTATE_PRESENT,
8774 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8775 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8776 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8777 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8778 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8779 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8780 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8781
8782 RegDeleteValueA(props, "ProductID");
8783 RegDeleteValueA(props, "RegCompany");
8784 RegDeleteValueA(props, "RegOwner");
8785 delete_key(props, "", access & KEY_WOW64_64KEY);
8786 RegCloseKey(props);
8787 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8788 RegCloseKey(userprod);
8789 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8790 RegCloseKey(prodkey);
8791 LocalFree(usersid);
8792 }
8793
8794 static void test_MsiOpenProduct(void)
8795 {
8796 MSIHANDLE hprod, hdb;
8797 CHAR val[MAX_PATH];
8798 CHAR path[MAX_PATH];
8799 CHAR keypath[MAX_PATH*2];
8800 CHAR prodcode[MAX_PATH];
8801 CHAR prod_squashed[MAX_PATH];
8802 HKEY prodkey, userkey, props;
8803 LPSTR usersid;
8804 DWORD size;
8805 LONG res;
8806 UINT r;
8807 REGSAM access = KEY_ALL_ACCESS;
8808
8809 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8810
8811 GetCurrentDirectoryA(MAX_PATH, path);
8812 lstrcatA(path, "\\");
8813
8814 create_test_guid(prodcode, prod_squashed);
8815 usersid = get_user_sid();
8816
8817 if (is_wow64)
8818 access |= KEY_WOW64_64KEY;
8819
8820 hdb = create_package_db(prodcode);
8821 MsiCloseHandle(hdb);
8822
8823 /* NULL szProduct */
8824 hprod = 0xdeadbeef;
8825 r = MsiOpenProductA(NULL, &hprod);
8826 ok(r == ERROR_INVALID_PARAMETER,
8827 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8828 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8829
8830 /* empty szProduct */
8831 hprod = 0xdeadbeef;
8832 r = MsiOpenProductA("", &hprod);
8833 ok(r == ERROR_INVALID_PARAMETER,
8834 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8835 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8836
8837 /* garbage szProduct */
8838 hprod = 0xdeadbeef;
8839 r = MsiOpenProductA("garbage", &hprod);
8840 ok(r == ERROR_INVALID_PARAMETER,
8841 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8842 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8843
8844 /* guid without brackets */
8845 hprod = 0xdeadbeef;
8846 r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
8847 ok(r == ERROR_INVALID_PARAMETER,
8848 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8849 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8850
8851 /* guid with brackets */
8852 hprod = 0xdeadbeef;
8853 r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
8854 ok(r == ERROR_UNKNOWN_PRODUCT,
8855 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8856 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8857
8858 /* same length as guid, but random */
8859 hprod = 0xdeadbeef;
8860 r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
8861 ok(r == ERROR_INVALID_PARAMETER,
8862 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8863 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8864
8865 /* hProduct is NULL */
8866 hprod = 0xdeadbeef;
8867 r = MsiOpenProductA(prodcode, NULL);
8868 ok(r == ERROR_INVALID_PARAMETER,
8869 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8870 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8871
8872 /* MSIINSTALLCONTEXT_USERMANAGED */
8873
8874 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8875 lstrcatA(keypath, "Installer\\Managed\\");
8876 lstrcatA(keypath, usersid);
8877 lstrcatA(keypath, "\\Installer\\Products\\");
8878 lstrcatA(keypath, prod_squashed);
8879
8880 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8881 if (res == ERROR_ACCESS_DENIED)
8882 {
8883 skip("Not enough rights to perform tests\n");
8884 LocalFree(usersid);
8885 return;
8886 }
8887 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8888
8889 /* managed product key exists */
8890 hprod = 0xdeadbeef;
8891 r = MsiOpenProductA(prodcode, &hprod);
8892 ok(r == ERROR_UNKNOWN_PRODUCT,
8893 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8894 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8895
8896 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8897 lstrcatA(keypath, "Installer\\UserData\\");
8898 lstrcatA(keypath, usersid);
8899 lstrcatA(keypath, "\\Products\\");
8900 lstrcatA(keypath, prod_squashed);
8901
8902 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8903 if (res == ERROR_ACCESS_DENIED)
8904 {
8905 skip("Not enough rights to perform tests\n");
8906 LocalFree(usersid);
8907 return;
8908 }
8909 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8910
8911 /* user product key exists */
8912 hprod = 0xdeadbeef;
8913 r = MsiOpenProductA(prodcode, &hprod);
8914 ok(r == ERROR_UNKNOWN_PRODUCT,
8915 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8916 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8917
8918 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8919 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8920
8921 /* InstallProperties key exists */
8922 hprod = 0xdeadbeef;
8923 r = MsiOpenProductA(prodcode, &hprod);
8924 ok(r == ERROR_UNKNOWN_PRODUCT,
8925 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8926 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8927
8928 lstrcpyA(val, path);
8929 lstrcatA(val, "\\winetest.msi");
8930 res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
8931 (const BYTE *)val, lstrlenA(val) + 1);
8932 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8933
8934 /* ManagedLocalPackage value exists */
8935 hprod = 0xdeadbeef;
8936 r = MsiOpenProductA(prodcode, &hprod);
8937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8938 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8939
8940 size = MAX_PATH;
8941 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8943 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8944 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
8945
8946 MsiCloseHandle(hprod);
8947
8948 RegDeleteValueA(props, "ManagedLocalPackage");
8949 delete_key(props, "", access & KEY_WOW64_64KEY);
8950 RegCloseKey(props);
8951 delete_key(userkey, "", access & KEY_WOW64_64KEY);
8952 RegCloseKey(userkey);
8953 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8954 RegCloseKey(prodkey);
8955
8956 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8957
8958 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8959 lstrcatA(keypath, prod_squashed);
8960
8961 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8962 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8963
8964 /* unmanaged product key exists */
8965 hprod = 0xdeadbeef;
8966 r = MsiOpenProductA(prodcode, &hprod);
8967 ok(r == ERROR_UNKNOWN_PRODUCT,
8968 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8969 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8970
8971 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8972 lstrcatA(keypath, "Installer\\UserData\\");
8973 lstrcatA(keypath, usersid);
8974 lstrcatA(keypath, "\\Products\\");
8975 lstrcatA(keypath, prod_squashed);
8976
8977 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8978 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8979
8980 /* user product key exists */
8981 hprod = 0xdeadbeef;
8982 r = MsiOpenProductA(prodcode, &hprod);
8983 ok(r == ERROR_UNKNOWN_PRODUCT,
8984 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8985 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8986
8987 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8988 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8989
8990 /* InstallProperties key exists */
8991 hprod = 0xdeadbeef;
8992 r = MsiOpenProductA(prodcode, &hprod);
8993 ok(r == ERROR_UNKNOWN_PRODUCT,
8994 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8995 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8996
8997 lstrcpyA(val, path);
8998 lstrcatA(val, "\\winetest.msi");
8999 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9000 (const BYTE *)val, lstrlenA(val) + 1);
9001 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9002
9003 /* LocalPackage value exists */
9004 hprod = 0xdeadbeef;
9005 r = MsiOpenProductA(prodcode, &hprod);
9006 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9007 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9008
9009 size = MAX_PATH;
9010 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9012 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9013 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9014
9015 MsiCloseHandle(hprod);
9016
9017 RegDeleteValueA(props, "LocalPackage");
9018 delete_key(props, "", access & KEY_WOW64_64KEY);
9019 RegCloseKey(props);
9020 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9021 RegCloseKey(userkey);
9022 RegDeleteKeyA(prodkey, "");
9023 RegCloseKey(prodkey);
9024
9025 /* MSIINSTALLCONTEXT_MACHINE */
9026
9027 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9028 lstrcatA(keypath, prod_squashed);
9029
9030 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9031 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9032
9033 /* managed product key exists */
9034 hprod = 0xdeadbeef;
9035 r = MsiOpenProductA(prodcode, &hprod);
9036 ok(r == ERROR_UNKNOWN_PRODUCT,
9037 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9038 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9039
9040 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9041 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9042 lstrcatA(keypath, prod_squashed);
9043
9044 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9045 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9046
9047 /* user product key exists */
9048 hprod = 0xdeadbeef;
9049 r = MsiOpenProductA(prodcode, &hprod);
9050 ok(r == ERROR_UNKNOWN_PRODUCT,
9051 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9052 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9053
9054 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9055 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9056
9057 /* InstallProperties key exists */
9058 hprod = 0xdeadbeef;
9059 r = MsiOpenProductA(prodcode, &hprod);
9060 ok(r == ERROR_UNKNOWN_PRODUCT,
9061 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9062 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9063
9064 lstrcpyA(val, path);
9065 lstrcatA(val, "\\winetest.msi");
9066 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9067 (const BYTE *)val, lstrlenA(val) + 1);
9068 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9069
9070 /* LocalPackage value exists */
9071 hprod = 0xdeadbeef;
9072 r = MsiOpenProductA(prodcode, &hprod);
9073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9074 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9075
9076 size = MAX_PATH;
9077 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9078 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9079 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9080 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9081
9082 MsiCloseHandle(hprod);
9083
9084 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9085 (const BYTE *)"winetest.msi", 13);
9086 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9087
9088 lstrcpyA(val, path);
9089 lstrcatA(val, "\\winetest.msi");
9090 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9091 (const BYTE *)val, lstrlenA(val) + 1);
9092 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9093
9094 DeleteFileA(msifile);
9095
9096 /* local package does not exist */
9097 hprod = 0xdeadbeef;
9098 r = MsiOpenProductA(prodcode, &hprod);
9099 ok(r == ERROR_UNKNOWN_PRODUCT,
9100 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9101 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9102
9103 RegDeleteValueA(props, "LocalPackage");
9104 delete_key(props, "", access & KEY_WOW64_64KEY);
9105 RegCloseKey(props);
9106 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9107 RegCloseKey(userkey);
9108 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9109 RegCloseKey(prodkey);
9110
9111 DeleteFileA(msifile);
9112 LocalFree(usersid);
9113 }
9114
9115 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
9116 {
9117 MSIINSTALLCONTEXT context;
9118 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9119 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9120 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9121 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9122 HKEY prodkey, patches, udprod, udpatch, hpatch;
9123 DWORD size, data;
9124 LONG res;
9125 UINT r;
9126 REGSAM access = KEY_ALL_ACCESS;
9127
9128 create_test_guid(prodcode, prod_squashed);
9129 create_test_guid(patch, patch_squashed);
9130
9131 if (is_wow64)
9132 access |= KEY_WOW64_64KEY;
9133
9134 /* MSIPATCHSTATE_APPLIED */
9135
9136 lstrcpyA(patchcode, "apple");
9137 lstrcpyA(targetprod, "banana");
9138 context = 0xdeadbeef;
9139 lstrcpyA(targetsid, "kiwi");
9140 size = MAX_PATH;
9141 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9142 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9143 &context, targetsid, &size);
9144 if (r == ERROR_ACCESS_DENIED)
9145 {
9146 skip("Not enough rights to perform tests\n");
9147 return;
9148 }
9149 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9150 ok(!lstrcmpA(patchcode, "apple"),
9151 "Expected patchcode to be unchanged, got %s\n", patchcode);
9152 ok(!lstrcmpA(targetprod, "banana"),
9153 "Expected targetprod to be unchanged, got %s\n", targetprod);
9154 ok(context == 0xdeadbeef,
9155 "Expected context to be unchanged, got %d\n", context);
9156 ok(!lstrcmpA(targetsid, "kiwi"),
9157 "Expected targetsid to be unchanged, got %s\n", targetsid);
9158 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9159
9160 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9161 lstrcatA(keypath, expectedsid);
9162 lstrcatA(keypath, "\\Installer\\Products\\");
9163 lstrcatA(keypath, prod_squashed);
9164
9165 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9166 if (res == ERROR_ACCESS_DENIED)
9167 {
9168 skip("Not enough rights to perform tests\n");
9169 return;
9170 }
9171 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9172
9173 /* managed product key exists */
9174 lstrcpyA(patchcode, "apple");
9175 lstrcpyA(targetprod, "banana");
9176 context = 0xdeadbeef;
9177 lstrcpyA(targetsid, "kiwi");
9178 size = MAX_PATH;
9179 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9180 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9181 &context, targetsid, &size);
9182 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9183 ok(!lstrcmpA(patchcode, "apple"),
9184 "Expected patchcode to be unchanged, got %s\n", patchcode);
9185 ok(!lstrcmpA(targetprod, "banana"),
9186 "Expected targetprod to be unchanged, got %s\n", targetprod);
9187 ok(context == 0xdeadbeef,
9188 "Expected context to be unchanged, got %d\n", context);
9189 ok(!lstrcmpA(targetsid, "kiwi"),
9190 "Expected targetsid to be unchanged, got %s\n", targetsid);
9191 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9192
9193 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9194 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9195
9196 /* patches key exists */
9197 lstrcpyA(patchcode, "apple");
9198 lstrcpyA(targetprod, "banana");
9199 context = 0xdeadbeef;
9200 lstrcpyA(targetsid, "kiwi");
9201 size = MAX_PATH;
9202 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9203 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9204 &context, targetsid, &size);
9205 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9206 ok(!lstrcmpA(patchcode, "apple"),
9207 "Expected patchcode to be unchanged, got %s\n", patchcode);
9208 ok(!lstrcmpA(targetprod, "banana"),
9209 "Expected targetprod to be unchanged, got %s\n", targetprod);
9210 ok(context == 0xdeadbeef,
9211 "Expected context to be unchanged, got %d\n", context);
9212 ok(!lstrcmpA(targetsid, "kiwi"),
9213 "Expected targetsid to be unchanged, got %s\n", targetsid);
9214 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9215
9216 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9217 (const BYTE *)patch_squashed,
9218 lstrlenA(patch_squashed) + 1);
9219 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9220
9221 /* Patches value exists, is not REG_MULTI_SZ */
9222 lstrcpyA(patchcode, "apple");
9223 lstrcpyA(targetprod, "banana");
9224 context = 0xdeadbeef;
9225 lstrcpyA(targetsid, "kiwi");
9226 size = MAX_PATH;
9227 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9228 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9229 &context, targetsid, &size);
9230 ok(r == ERROR_BAD_CONFIGURATION,
9231 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9232 ok(!lstrcmpA(patchcode, "apple"),
9233 "Expected patchcode to be unchanged, got %s\n", patchcode);
9234 ok(!lstrcmpA(targetprod, "banana"),
9235 "Expected targetprod to be unchanged, got %s\n", targetprod);
9236 ok(context == 0xdeadbeef,
9237 "Expected context to be unchanged, got %d\n", context);
9238 ok(!lstrcmpA(targetsid, "kiwi"),
9239 "Expected targetsid to be unchanged, got %s\n", targetsid);
9240 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9241
9242 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9243 (const BYTE *)"a\0b\0c\0\0", 7);
9244 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9245
9246 /* Patches value exists, is not a squashed guid */
9247 lstrcpyA(patchcode, "apple");
9248 lstrcpyA(targetprod, "banana");
9249 context = 0xdeadbeef;
9250 lstrcpyA(targetsid, "kiwi");
9251 size = MAX_PATH;
9252 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9253 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9254 &context, targetsid, &size);
9255 ok(r == ERROR_BAD_CONFIGURATION,
9256 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9257 ok(!lstrcmpA(patchcode, "apple"),
9258 "Expected patchcode to be unchanged, got %s\n", patchcode);
9259 ok(!lstrcmpA(targetprod, "banana"),
9260 "Expected targetprod to be unchanged, got %s\n", targetprod);
9261 ok(context == 0xdeadbeef,
9262 "Expected context to be unchanged, got %d\n", context);
9263 ok(!lstrcmpA(targetsid, "kiwi"),
9264 "Expected targetsid to be unchanged, got %s\n", targetsid);
9265 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9266
9267 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9268 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9269 (const BYTE *)patch_squashed,
9270 lstrlenA(patch_squashed) + 2);
9271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9272
9273 /* Patches value exists */
9274 lstrcpyA(patchcode, "apple");
9275 lstrcpyA(targetprod, "banana");
9276 context = 0xdeadbeef;
9277 lstrcpyA(targetsid, "kiwi");
9278 size = MAX_PATH;
9279 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9280 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9281 &context, targetsid, &size);
9282 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9283 ok(!lstrcmpA(patchcode, "apple"),
9284 "Expected patchcode to be unchanged, got %s\n", patchcode);
9285 ok(!lstrcmpA(targetprod, "banana"),
9286 "Expected targetprod to be unchanged, got %s\n", targetprod);
9287 ok(context == 0xdeadbeef,
9288 "Expected context to be unchanged, got %d\n", context);
9289 ok(!lstrcmpA(targetsid, "kiwi"),
9290 "Expected targetsid to be unchanged, got %s\n", targetsid);
9291 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9292
9293 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9294 (const BYTE *)"whatever", 9);
9295 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9296
9297 /* patch squashed value exists */
9298 lstrcpyA(patchcode, "apple");
9299 lstrcpyA(targetprod, "banana");
9300 context = 0xdeadbeef;
9301 lstrcpyA(targetsid, "kiwi");
9302 size = MAX_PATH;
9303 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9304 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9305 &context, targetsid, &size);
9306 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9307 ok(!lstrcmpA(patchcode, patch),
9308 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9309 ok(!lstrcmpA(targetprod, prodcode),
9310 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9311 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9312 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9313 ok(!lstrcmpA(targetsid, expectedsid),
9314 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9315 ok(size == lstrlenA(expectedsid),
9316 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9317
9318 /* increase the index */
9319 lstrcpyA(patchcode, "apple");
9320 lstrcpyA(targetprod, "banana");
9321 context = 0xdeadbeef;
9322 lstrcpyA(targetsid, "kiwi");
9323 size = MAX_PATH;
9324 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9325 MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
9326 &context, targetsid, &size);
9327 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9328 ok(!lstrcmpA(patchcode, "apple"),
9329 "Expected patchcode to be unchanged, got %s\n", patchcode);
9330 ok(!lstrcmpA(targetprod, "banana"),
9331 "Expected targetprod to be unchanged, got %s\n", targetprod);
9332 ok(context == 0xdeadbeef,
9333 "Expected context to be unchanged, got %d\n", context);
9334 ok(!lstrcmpA(targetsid, "kiwi"),
9335 "Expected targetsid to be unchanged, got %s\n", targetsid);
9336 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9337
9338 /* increase again */
9339 lstrcpyA(patchcode, "apple");
9340 lstrcpyA(targetprod, "banana");
9341 context = 0xdeadbeef;
9342 lstrcpyA(targetsid, "kiwi");
9343 size = MAX_PATH;
9344 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9345 MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
9346 &context, targetsid, &size);
9347 ok(r == ERROR_INVALID_PARAMETER,
9348 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9349 ok(!lstrcmpA(patchcode, "apple"),
9350 "Expected patchcode to be unchanged, got %s\n", patchcode);
9351 ok(!lstrcmpA(targetprod, "banana"),
9352 "Expected targetprod to be unchanged, got %s\n", targetprod);
9353 ok(context == 0xdeadbeef,
9354 "Expected context to be unchanged, got %d\n", context);
9355 ok(!lstrcmpA(targetsid, "kiwi"),
9356 "Expected targetsid to be unchanged, got %s\n", targetsid);
9357 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9358
9359 /* szPatchCode is NULL */
9360 lstrcpyA(targetprod, "banana");
9361 context = 0xdeadbeef;
9362 lstrcpyA(targetsid, "kiwi");
9363 size = MAX_PATH;
9364 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9365 MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
9366 &context, targetsid, &size);
9367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9368 ok(!lstrcmpA(targetprod, prodcode),
9369 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9370 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9371 "Expected MSIINSTALLCONTEXT_USERMANAGED, 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 /* szTargetProductCode is NULL */
9378 lstrcpyA(patchcode, "apple");
9379 context = 0xdeadbeef;
9380 lstrcpyA(targetsid, "kiwi");
9381 size = MAX_PATH;
9382 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9383 MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
9384 &context, targetsid, &size);
9385 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9386 ok(!lstrcmpA(patchcode, patch),
9387 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9388 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9389 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9390 ok(!lstrcmpA(targetsid, expectedsid),
9391 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9392 ok(size == lstrlenA(expectedsid),
9393 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9394
9395 /* pdwTargetProductContext is NULL */
9396 lstrcpyA(patchcode, "apple");
9397 lstrcpyA(targetprod, "banana");
9398 lstrcpyA(targetsid, "kiwi");
9399 size = MAX_PATH;
9400 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9401 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9402 NULL, targetsid, &size);
9403 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9404 ok(!lstrcmpA(patchcode, patch),
9405 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9406 ok(!lstrcmpA(targetprod, prodcode),
9407 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9408 ok(!lstrcmpA(targetsid, expectedsid),
9409 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9410 ok(size == lstrlenA(expectedsid),
9411 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9412
9413 /* szTargetUserSid is NULL */
9414 lstrcpyA(patchcode, "apple");
9415 lstrcpyA(targetprod, "banana");
9416 context = 0xdeadbeef;
9417 size = MAX_PATH;
9418 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9419 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9420 &context, NULL, &size);
9421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9422 ok(!lstrcmpA(patchcode, patch),
9423 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9424 ok(!lstrcmpA(targetprod, prodcode),
9425 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9426 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9427 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9428 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
9429 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
9430
9431 /* pcchTargetUserSid is exactly the length of szTargetUserSid */
9432 lstrcpyA(patchcode, "apple");
9433 lstrcpyA(targetprod, "banana");
9434 context = 0xdeadbeef;
9435 lstrcpyA(targetsid, "kiwi");
9436 size = lstrlenA(expectedsid);
9437 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9438 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9439 &context, targetsid, &size);
9440 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9441 ok(!lstrcmpA(patchcode, patch),
9442 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9443 ok(!lstrcmpA(targetprod, prodcode),
9444 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9445 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9446 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9447 ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
9448 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9449 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
9450 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
9451
9452 /* pcchTargetUserSid has enough room for NULL terminator */
9453 lstrcpyA(patchcode, "apple");
9454 lstrcpyA(targetprod, "banana");
9455 context = 0xdeadbeef;
9456 lstrcpyA(targetsid, "kiwi");
9457 size = lstrlenA(expectedsid) + 1;
9458 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9459 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9460 &context, targetsid, &size);
9461 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9462 ok(!lstrcmpA(patchcode, patch),
9463 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9464 ok(!lstrcmpA(targetprod, prodcode),
9465 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9466 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9467 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9468 ok(!lstrcmpA(targetsid, expectedsid),
9469 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9470 ok(size == lstrlenA(expectedsid),
9471 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9472
9473 /* both szTargetuserSid and pcchTargetUserSid are NULL */
9474 lstrcpyA(patchcode, "apple");
9475 lstrcpyA(targetprod, "banana");
9476 context = 0xdeadbeef;
9477 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9478 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9479 &context, NULL, NULL);
9480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9481 ok(!lstrcmpA(patchcode, patch),
9482 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9483 ok(!lstrcmpA(targetprod, prodcode),
9484 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9485 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9486 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9487
9488 /* MSIPATCHSTATE_SUPERSEDED */
9489
9490 lstrcpyA(patchcode, "apple");
9491 lstrcpyA(targetprod, "banana");
9492 context = 0xdeadbeef;
9493 lstrcpyA(targetsid, "kiwi");
9494 size = MAX_PATH;
9495 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9496 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9497 &context, targetsid, &size);
9498 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9499 ok(!lstrcmpA(patchcode, "apple"),
9500 "Expected patchcode to be unchanged, got %s\n", patchcode);
9501 ok(!lstrcmpA(targetprod, "banana"),
9502 "Expected targetprod to be unchanged, got %s\n", targetprod);
9503 ok(context == 0xdeadbeef,
9504 "Expected context to be unchanged, got %d\n", context);
9505 ok(!lstrcmpA(targetsid, "kiwi"),
9506 "Expected targetsid to be unchanged, got %s\n", targetsid);
9507 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9508
9509 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9510 lstrcatA(keypath, expectedsid);
9511 lstrcatA(keypath, "\\Products\\");
9512 lstrcatA(keypath, prod_squashed);
9513
9514 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9515 if (res == ERROR_ACCESS_DENIED)
9516 {
9517 skip("Not enough rights to perform tests\n");
9518 return;
9519 }
9520 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9521
9522 /* UserData product key exists */
9523 lstrcpyA(patchcode, "apple");
9524 lstrcpyA(targetprod, "banana");
9525 context = 0xdeadbeef;
9526 lstrcpyA(targetsid, "kiwi");
9527 size = MAX_PATH;
9528 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9529 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9530 &context, targetsid, &size);
9531 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9532 ok(!lstrcmpA(patchcode, "apple"),
9533 "Expected patchcode to be unchanged, got %s\n", patchcode);
9534 ok(!lstrcmpA(targetprod, "banana"),
9535 "Expected targetprod to be unchanged, got %s\n", targetprod);
9536 ok(context == 0xdeadbeef,
9537 "Expected context to be unchanged, got %d\n", context);
9538 ok(!lstrcmpA(targetsid, "kiwi"),
9539 "Expected targetsid to be unchanged, got %s\n", targetsid);
9540 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9541
9542 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9543 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9544
9545 /* UserData patches key exists */
9546 lstrcpyA(patchcode, "apple");
9547 lstrcpyA(targetprod, "banana");
9548 context = 0xdeadbeef;
9549 lstrcpyA(targetsid, "kiwi");
9550 size = MAX_PATH;
9551 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9552 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9553 &context, targetsid, &size);
9554 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9555 ok(!lstrcmpA(patchcode, "apple"),
9556 "Expected patchcode to be unchanged, got %s\n", patchcode);
9557 ok(!lstrcmpA(targetprod, "banana"),
9558 "Expected targetprod to be unchanged, got %s\n", targetprod);
9559 ok(context == 0xdeadbeef,
9560 "Expected context to be unchanged, got %d\n", context);
9561 ok(!lstrcmpA(targetsid, "kiwi"),
9562 "Expected targetsid to be unchanged, got %s\n", targetsid);
9563 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9564
9565 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9566 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9567
9568 /* specific UserData patch key exists */
9569 lstrcpyA(patchcode, "apple");
9570 lstrcpyA(targetprod, "banana");
9571 context = 0xdeadbeef;
9572 lstrcpyA(targetsid, "kiwi");
9573 size = MAX_PATH;
9574 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9575 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9576 &context, targetsid, &size);
9577 ok(r == ERROR_BAD_CONFIGURATION,
9578 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9579 ok(!lstrcmpA(patchcode, "apple"),
9580 "Expected patchcode to be unchanged, got %s\n", patchcode);
9581 ok(!lstrcmpA(targetprod, "banana"),
9582 "Expected targetprod to be unchanged, got %s\n", targetprod);
9583 ok(context == 0xdeadbeef,
9584 "Expected context to be unchanged, got %d\n", context);
9585 ok(!lstrcmpA(targetsid, "kiwi"),
9586 "Expected targetsid to be unchanged, got %s\n", targetsid);
9587 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9588
9589 data = MSIPATCHSTATE_SUPERSEDED;
9590 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9591 (const BYTE *)&data, sizeof(DWORD));
9592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9593
9594 /* State 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, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9601 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9602 &context, targetsid, &size);
9603 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9604 ok(!lstrcmpA(patchcode, patch),
9605 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9606 ok(!lstrcmpA(targetprod, prodcode),
9607 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9608 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9609 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9610 ok(!lstrcmpA(targetsid, expectedsid),
9611 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9612 ok(size == lstrlenA(expectedsid),
9613 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9614
9615 /* MSIPATCHSTATE_OBSOLETED */
9616
9617 lstrcpyA(patchcode, "apple");
9618 lstrcpyA(targetprod, "banana");
9619 context = 0xdeadbeef;
9620 lstrcpyA(targetsid, "kiwi");
9621 size = MAX_PATH;
9622 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9623 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9624 &context, targetsid, &size);
9625 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9626 ok(!lstrcmpA(patchcode, "apple"),
9627 "Expected patchcode to be unchanged, got %s\n", patchcode);
9628 ok(!lstrcmpA(targetprod, "banana"),
9629 "Expected targetprod to be unchanged, got %s\n", targetprod);
9630 ok(context == 0xdeadbeef,
9631 "Expected context to be unchanged, got %d\n", context);
9632 ok(!lstrcmpA(targetsid, "kiwi"),
9633 "Expected targetsid to be unchanged, got %s\n", targetsid);
9634 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9635
9636 data = MSIPATCHSTATE_OBSOLETED;
9637 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9638 (const BYTE *)&data, sizeof(DWORD));
9639 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9640
9641 /* State value is obsoleted */
9642 lstrcpyA(patchcode, "apple");
9643 lstrcpyA(targetprod, "banana");
9644 context = 0xdeadbeef;
9645 lstrcpyA(targetsid, "kiwi");
9646 size = MAX_PATH;
9647 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9648 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9649 &context, targetsid, &size);
9650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9651 ok(!lstrcmpA(patchcode, patch),
9652 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9653 ok(!lstrcmpA(targetprod, prodcode),
9654 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9655 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9656 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9657 ok(!lstrcmpA(targetsid, expectedsid),
9658 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9659 ok(size == lstrlenA(expectedsid),
9660 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9661
9662 /* MSIPATCHSTATE_REGISTERED */
9663 /* FIXME */
9664
9665 /* MSIPATCHSTATE_ALL */
9666
9667 /* 1st */
9668 lstrcpyA(patchcode, "apple");
9669 lstrcpyA(targetprod, "banana");
9670 context = 0xdeadbeef;
9671 lstrcpyA(targetsid, "kiwi");
9672 size = MAX_PATH;
9673 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9674 MSIPATCHSTATE_ALL, 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_USERMANAGED,
9682 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9683 ok(!lstrcmpA(targetsid, expectedsid),
9684 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9685 ok(size == lstrlenA(expectedsid),
9686 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9687
9688 /* same patch in multiple places, only one is enumerated */
9689 lstrcpyA(patchcode, "apple");
9690 lstrcpyA(targetprod, "banana");
9691 context = 0xdeadbeef;
9692 lstrcpyA(targetsid, "kiwi");
9693 size = MAX_PATH;
9694 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9695 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9696 &context, targetsid, &size);
9697 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9698 ok(!lstrcmpA(patchcode, "apple"),
9699 "Expected patchcode to be unchanged, got %s\n", patchcode);
9700 ok(!lstrcmpA(targetprod, "banana"),
9701 "Expected targetprod to be unchanged, got %s\n", targetprod);
9702 ok(context == 0xdeadbeef,
9703 "Expected context to be unchanged, got %d\n", context);
9704 ok(!lstrcmpA(targetsid, "kiwi"),
9705 "Expected targetsid to be unchanged, got %s\n", targetsid);
9706 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9707
9708 RegDeleteValueA(hpatch, "State");
9709 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9710 RegCloseKey(hpatch);
9711 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9712 RegCloseKey(udpatch);
9713 delete_key(udprod, "", access & KEY_WOW64_64KEY);
9714 RegCloseKey(udprod);
9715 RegDeleteValueA(patches, "Patches");
9716 delete_key(patches, "", access & KEY_WOW64_64KEY);
9717 RegCloseKey(patches);
9718 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9719 RegCloseKey(prodkey);
9720 }
9721
9722 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
9723 {
9724 MSIINSTALLCONTEXT context;
9725 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9726 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9727 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9728 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9729 HKEY prodkey, patches, udprod, udpatch;
9730 HKEY userkey, hpatch;
9731 DWORD size, data;
9732 LONG res;
9733 UINT r;
9734 REGSAM access = KEY_ALL_ACCESS;
9735
9736 create_test_guid(prodcode, prod_squashed);
9737 create_test_guid(patch, patch_squashed);
9738
9739 if (is_wow64)
9740 access |= KEY_WOW64_64KEY;
9741
9742 /* MSIPATCHSTATE_APPLIED */
9743
9744 lstrcpyA(patchcode, "apple");
9745 lstrcpyA(targetprod, "banana");
9746 context = 0xdeadbeef;
9747 lstrcpyA(targetsid, "kiwi");
9748 size = MAX_PATH;
9749 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9750 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9751 &context, targetsid, &size);
9752 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9753 ok(!lstrcmpA(patchcode, "apple"),
9754 "Expected patchcode to be unchanged, got %s\n", patchcode);
9755 ok(!lstrcmpA(targetprod, "banana"),
9756 "Expected targetprod to be unchanged, got %s\n", targetprod);
9757 ok(context == 0xdeadbeef,
9758 "Expected context to be unchanged, got %d\n", context);
9759 ok(!lstrcmpA(targetsid, "kiwi"),
9760 "Expected targetsid to be unchanged, got %s\n", targetsid);
9761 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9762
9763 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9764 lstrcatA(keypath, prod_squashed);
9765
9766 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9767 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9768
9769 /* current user product key exists */
9770 lstrcpyA(patchcode, "apple");
9771 lstrcpyA(targetprod, "banana");
9772 context = 0xdeadbeef;
9773 lstrcpyA(targetsid, "kiwi");
9774 size = MAX_PATH;
9775 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9776 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9777 &context, targetsid, &size);
9778 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9779 ok(!lstrcmpA(patchcode, "apple"),
9780 "Expected patchcode to be unchanged, got %s\n", patchcode);
9781 ok(!lstrcmpA(targetprod, "banana"),
9782 "Expected targetprod to be unchanged, got %s\n", targetprod);
9783 ok(context == 0xdeadbeef,
9784 "Expected context to be unchanged, got %d\n", context);
9785 ok(!lstrcmpA(targetsid, "kiwi"),
9786 "Expected targetsid to be unchanged, got %s\n", targetsid);
9787 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9788
9789 res = RegCreateKeyA(prodkey, "Patches", &patches);
9790 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9791
9792 /* Patches key exists */
9793 lstrcpyA(patchcode, "apple");
9794 lstrcpyA(targetprod, "banana");
9795 context = 0xdeadbeef;
9796 lstrcpyA(targetsid, "kiwi");
9797 size = MAX_PATH;
9798 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9799 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9800 &context, targetsid, &size);
9801 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9802 ok(!lstrcmpA(patchcode, "apple"),
9803 "Expected patchcode to be unchanged, got %s\n", patchcode);
9804 ok(!lstrcmpA(targetprod, "banana"),
9805 "Expected targetprod to be unchanged, got %s\n", targetprod);
9806 ok(context == 0xdeadbeef,
9807 "Expected context to be unchanged, got %d\n", context);
9808 ok(!lstrcmpA(targetsid, "kiwi"),
9809 "Expected targetsid to be unchanged, got %s\n", targetsid);
9810 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9811
9812 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9813 (const BYTE *)patch_squashed,
9814 lstrlenA(patch_squashed) + 1);
9815 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9816
9817 /* Patches value exists, is not REG_MULTI_SZ */
9818 lstrcpyA(patchcode, "apple");
9819 lstrcpyA(targetprod, "banana");
9820 context = 0xdeadbeef;
9821 lstrcpyA(targetsid, "kiwi");
9822 size = MAX_PATH;
9823 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9824 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9825 &context, targetsid, &size);
9826 ok(r == ERROR_BAD_CONFIGURATION,
9827 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9828 ok(!lstrcmpA(patchcode, "apple"),
9829 "Expected patchcode to be unchanged, got %s\n", patchcode);
9830 ok(!lstrcmpA(targetprod, "banana"),
9831 "Expected targetprod to be unchanged, got %s\n", targetprod);
9832 ok(context == 0xdeadbeef,
9833 "Expected context to be unchanged, got %d\n", context);
9834 ok(!lstrcmpA(targetsid, "kiwi"),
9835 "Expected targetsid to be unchanged, got %s\n", targetsid);
9836 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9837
9838 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9839 (const BYTE *)"a\0b\0c\0\0", 7);
9840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9841
9842 /* Patches value exists, is not a squashed guid */
9843 lstrcpyA(patchcode, "apple");
9844 lstrcpyA(targetprod, "banana");
9845 context = 0xdeadbeef;
9846 lstrcpyA(targetsid, "kiwi");
9847 size = MAX_PATH;
9848 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9849 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9850 &context, targetsid, &size);
9851 ok(r == ERROR_BAD_CONFIGURATION,
9852 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9853 ok(!lstrcmpA(patchcode, "apple"),
9854 "Expected patchcode to be unchanged, got %s\n", patchcode);
9855 ok(!lstrcmpA(targetprod, "banana"),
9856 "Expected targetprod to be unchanged, got %s\n", targetprod);
9857 ok(context == 0xdeadbeef,
9858 "Expected context to be unchanged, got %d\n", context);
9859 ok(!lstrcmpA(targetsid, "kiwi"),
9860 "Expected targetsid to be unchanged, got %s\n", targetsid);
9861 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9862
9863 patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
9864 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9865 (const BYTE *)patch_squashed,
9866 lstrlenA(patch_squashed) + 2);
9867 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9868
9869 /* Patches value exists */
9870 lstrcpyA(patchcode, "apple");
9871 lstrcpyA(targetprod, "banana");
9872 context = 0xdeadbeef;
9873 lstrcpyA(targetsid, "kiwi");
9874 size = MAX_PATH;
9875 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9876 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9877 &context, targetsid, &size);
9878 ok(r == ERROR_NO_MORE_ITEMS ||
9879 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
9880 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9881 ok(!lstrcmpA(patchcode, "apple"),
9882 "Expected patchcode to be unchanged, got %s\n", patchcode);
9883 ok(!lstrcmpA(targetprod, "banana"),
9884 "Expected targetprod to be unchanged, got %s\n", targetprod);
9885 ok(context == 0xdeadbeef,
9886 "Expected context to be unchanged, got %d\n", context);
9887 ok(!lstrcmpA(targetsid, "kiwi"),
9888 "Expected targetsid to be unchanged, got %s\n", targetsid);
9889 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9890
9891 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9892 (const BYTE *)"whatever", 9);
9893 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9894
9895 /* patch code value exists */
9896 lstrcpyA(patchcode, "apple");
9897 lstrcpyA(targetprod, "banana");
9898 context = 0xdeadbeef;
9899 lstrcpyA(targetsid, "kiwi");
9900 size = MAX_PATH;
9901 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9902 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9903 &context, targetsid, &size);
9904 ok(r == ERROR_NO_MORE_ITEMS ||
9905 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
9906 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9907 ok(!lstrcmpA(patchcode, "apple"),
9908 "Expected patchcode to be unchanged, got %s\n", patchcode);
9909 ok(!lstrcmpA(targetprod, "banana"),
9910 "Expected targetprod to be unchanged, got %s\n", targetprod);
9911 ok(context == 0xdeadbeef,
9912 "Expected context to be unchanged, got %d\n", context);
9913 ok(!lstrcmpA(targetsid, "kiwi"),
9914 "Expected targetsid to be unchanged, got %s\n", targetsid);
9915 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9916
9917 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9918 lstrcatA(keypath, expectedsid);
9919 lstrcatA(keypath, "\\Patches\\");
9920 lstrcatA(keypath, patch_squashed);
9921
9922 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9923 if (res == ERROR_ACCESS_DENIED)
9924 {
9925 skip("Not enough rights to perform tests\n");
9926 goto error;
9927 }
9928 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9929
9930 /* userdata patch key exists */
9931 lstrcpyA(patchcode, "apple");
9932 lstrcpyA(targetprod, "banana");
9933 context = 0xdeadbeef;
9934 lstrcpyA(targetsid, "kiwi");
9935 size = MAX_PATH;
9936 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9937 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9938 &context, targetsid, &size);
9939 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9940 ok(!lstrcmpA(patchcode, patch),
9941 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9942 ok(!lstrcmpA(targetprod, prodcode),
9943 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9944 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9945 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9946 ok(!lstrcmpA(targetsid, expectedsid),
9947 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9948 ok(size == lstrlenA(expectedsid),
9949 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9950
9951 /* MSIPATCHSTATE_SUPERSEDED */
9952
9953 lstrcpyA(patchcode, "apple");
9954 lstrcpyA(targetprod, "banana");
9955 context = 0xdeadbeef;
9956 lstrcpyA(targetsid, "kiwi");
9957 size = MAX_PATH;
9958 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9959 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9960 &context, targetsid, &size);
9961 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9962 ok(!lstrcmpA(patchcode, "apple"),
9963 "Expected patchcode to be unchanged, got %s\n", patchcode);
9964 ok(!lstrcmpA(targetprod, "banana"),
9965 "Expected targetprod to be unchanged, got %s\n", targetprod);
9966 ok(context == 0xdeadbeef,
9967 "Expected context to be unchanged, got %d\n", context);
9968 ok(!lstrcmpA(targetsid, "kiwi"),
9969 "Expected targetsid to be unchanged, got %s\n", targetsid);
9970 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9971
9972 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9973 lstrcatA(keypath, expectedsid);
9974 lstrcatA(keypath, "\\Products\\");
9975 lstrcatA(keypath, prod_squashed);
9976
9977 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9978 if (res == ERROR_ACCESS_DENIED)
9979 {
9980 skip("Not enough rights to perform tests\n");
9981 goto error;
9982 }
9983 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9984
9985 /* UserData product key exists */
9986 lstrcpyA(patchcode, "apple");
9987 lstrcpyA(targetprod, "banana");
9988 context = 0xdeadbeef;
9989 lstrcpyA(targetsid, "kiwi");
9990 size = MAX_PATH;
9991 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9992 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9993 &context, targetsid, &size);
9994 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9995 ok(!lstrcmpA(patchcode, "apple"),
9996 "Expected patchcode to be unchanged, got %s\n", patchcode);
9997 ok(!lstrcmpA(targetprod, "banana"),
9998 "Expected targetprod to be unchanged, got %s\n", targetprod);
9999 ok(context == 0xdeadbeef,
10000 "Expected context to be unchanged, got %d\n", context);
10001 ok(!lstrcmpA(targetsid, "kiwi"),
10002 "Expected targetsid to be unchanged, got %s\n", targetsid);
10003 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10004
10005 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10006 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10007
10008 /* UserData patches key exists */
10009 lstrcpyA(patchcode, "apple");
10010 lstrcpyA(targetprod, "banana");
10011 context = 0xdeadbeef;
10012 lstrcpyA(targetsid, "kiwi");
10013 size = MAX_PATH;
10014 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10015 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10016 &context, targetsid, &size);
10017 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10018 ok(!lstrcmpA(patchcode, "apple"),
10019 "Expected patchcode to be unchanged, got %s\n", patchcode);
10020 ok(!lstrcmpA(targetprod, "banana"),
10021 "Expected targetprod to be unchanged, got %s\n", targetprod);
10022 ok(context == 0xdeadbeef,
10023 "Expected context to be unchanged, got %d\n", context);
10024 ok(!lstrcmpA(targetsid, "kiwi"),
10025 "Expected targetsid to be unchanged, got %s\n", targetsid);
10026 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10027
10028 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10030
10031 /* specific UserData patch key exists */
10032 lstrcpyA(patchcode, "apple");
10033 lstrcpyA(targetprod, "banana");
10034 context = 0xdeadbeef;
10035 lstrcpyA(targetsid, "kiwi");
10036 size = MAX_PATH;
10037 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10038 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10039 &context, targetsid, &size);
10040 ok(r == ERROR_BAD_CONFIGURATION,
10041 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10042 ok(!lstrcmpA(patchcode, "apple"),
10043 "Expected patchcode to be unchanged, got %s\n", patchcode);
10044 ok(!lstrcmpA(targetprod, "banana"),
10045 "Expected targetprod to be unchanged, got %s\n", targetprod);
10046 ok(context == 0xdeadbeef,
10047 "Expected context to be unchanged, got %d\n", context);
10048 ok(!lstrcmpA(targetsid, "kiwi"),
10049 "Expected targetsid to be unchanged, got %s\n", targetsid);
10050 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10051
10052 data = MSIPATCHSTATE_SUPERSEDED;
10053 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10054 (const BYTE *)&data, sizeof(DWORD));
10055 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10056
10057 /* State value exists */
10058 lstrcpyA(patchcode, "apple");
10059 lstrcpyA(targetprod, "banana");
10060 context = 0xdeadbeef;
10061 lstrcpyA(targetsid, "kiwi");
10062 size = MAX_PATH;
10063 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10064 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10065 &context, targetsid, &size);
10066 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10067 ok(!lstrcmpA(patchcode, patch),
10068 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10069 ok(!lstrcmpA(targetprod, prodcode),
10070 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10071 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10072 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10073 ok(!lstrcmpA(targetsid, expectedsid),
10074 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10075 ok(size == lstrlenA(expectedsid),
10076 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10077
10078 /* MSIPATCHSTATE_OBSOLETED */
10079
10080 lstrcpyA(patchcode, "apple");
10081 lstrcpyA(targetprod, "banana");
10082 context = 0xdeadbeef;
10083 lstrcpyA(targetsid, "kiwi");
10084 size = MAX_PATH;
10085 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10086 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10087 &context, targetsid, &size);
10088 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10089 ok(!lstrcmpA(patchcode, "apple"),
10090 "Expected patchcode to be unchanged, got %s\n", patchcode);
10091 ok(!lstrcmpA(targetprod, "banana"),
10092 "Expected targetprod to be unchanged, got %s\n", targetprod);
10093 ok(context == 0xdeadbeef,
10094 "Expected context to be unchanged, got %d\n", context);
10095 ok(!lstrcmpA(targetsid, "kiwi"),
10096 "Expected targetsid to be unchanged, got %s\n", targetsid);
10097 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10098
10099 data = MSIPATCHSTATE_OBSOLETED;
10100 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10101 (const BYTE *)&data, sizeof(DWORD));
10102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10103
10104 /* State value is obsoleted */
10105 lstrcpyA(patchcode, "apple");
10106 lstrcpyA(targetprod, "banana");
10107 context = 0xdeadbeef;
10108 lstrcpyA(targetsid, "kiwi");
10109 size = MAX_PATH;
10110 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10111 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10112 &context, targetsid, &size);
10113 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10114 ok(!lstrcmpA(patchcode, patch),
10115 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10116 ok(!lstrcmpA(targetprod, prodcode),
10117 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10118 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10119 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10120 ok(!lstrcmpA(targetsid, expectedsid),
10121 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10122 ok(size == lstrlenA(expectedsid),
10123 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10124
10125 /* MSIPATCHSTATE_REGISTERED */
10126 /* FIXME */
10127
10128 /* MSIPATCHSTATE_ALL */
10129
10130 /* 1st */
10131 lstrcpyA(patchcode, "apple");
10132 lstrcpyA(targetprod, "banana");
10133 context = 0xdeadbeef;
10134 lstrcpyA(targetsid, "kiwi");
10135 size = MAX_PATH;
10136 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10137 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10138 &context, targetsid, &size);
10139 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10140 ok(!lstrcmpA(patchcode, patch),
10141 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10142 ok(!lstrcmpA(targetprod, prodcode),
10143 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10144 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10145 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10146 ok(!lstrcmpA(targetsid, expectedsid),
10147 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10148 ok(size == lstrlenA(expectedsid),
10149 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10150
10151 /* same patch in multiple places, only one is enumerated */
10152 lstrcpyA(patchcode, "apple");
10153 lstrcpyA(targetprod, "banana");
10154 context = 0xdeadbeef;
10155 lstrcpyA(targetsid, "kiwi");
10156 size = MAX_PATH;
10157 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10158 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10159 &context, targetsid, &size);
10160 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10161 ok(!lstrcmpA(patchcode, "apple"),
10162 "Expected patchcode to be unchanged, got %s\n", patchcode);
10163 ok(!lstrcmpA(targetprod, "banana"),
10164 "Expected targetprod to be unchanged, got %s\n", targetprod);
10165 ok(context == 0xdeadbeef,
10166 "Expected context to be unchanged, got %d\n", context);
10167 ok(!lstrcmpA(targetsid, "kiwi"),
10168 "Expected targetsid to be unchanged, got %s\n", targetsid);
10169 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10170
10171 RegDeleteValueA(hpatch, "State");
10172 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10173 RegCloseKey(hpatch);
10174 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10175 RegCloseKey(udpatch);
10176 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10177 RegCloseKey(udprod);
10178 delete_key(userkey, "", access & KEY_WOW64_64KEY);
10179 RegCloseKey(userkey);
10180 RegDeleteValueA(patches, patch_squashed);
10181 RegDeleteValueA(patches, "Patches");
10182
10183 error:
10184 RegDeleteKeyA(patches, "");
10185 RegCloseKey(patches);
10186 RegDeleteKeyA(prodkey, "");
10187 RegCloseKey(prodkey);
10188 }
10189
10190 static void test_MsiEnumPatchesEx_machine(void)
10191 {
10192 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10193 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
10194 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10195 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10196 HKEY prodkey, patches, udprod, udpatch;
10197 HKEY hpatch;
10198 MSIINSTALLCONTEXT context;
10199 DWORD size, data;
10200 LONG res;
10201 UINT r;
10202 REGSAM access = KEY_ALL_ACCESS;
10203
10204 create_test_guid(prodcode, prod_squashed);
10205 create_test_guid(patch, patch_squashed);
10206
10207 if (is_wow64)
10208 access |= KEY_WOW64_64KEY;
10209
10210 /* MSIPATCHSTATE_APPLIED */
10211
10212 lstrcpyA(patchcode, "apple");
10213 lstrcpyA(targetprod, "banana");
10214 context = 0xdeadbeef;
10215 lstrcpyA(targetsid, "kiwi");
10216 size = MAX_PATH;
10217 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10218 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10219 &context, targetsid, &size);
10220 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10221 ok(!lstrcmpA(patchcode, "apple"),
10222 "Expected patchcode to be unchanged, got %s\n", patchcode);
10223 ok(!lstrcmpA(targetprod, "banana"),
10224 "Expected targetprod to be unchanged, got %s\n", targetprod);
10225 ok(context == 0xdeadbeef,
10226 "Expected context to be unchanged, got %d\n", context);
10227 ok(!lstrcmpA(targetsid, "kiwi"),
10228 "Expected targetsid to be unchanged, got %s\n", targetsid);
10229 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10230
10231 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10232 lstrcatA(keypath, prod_squashed);
10233
10234 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10235 if (res == ERROR_ACCESS_DENIED)
10236 {
10237 skip("Not enough rights to perform tests\n");
10238 return;
10239 }
10240 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10241
10242 /* local product key exists */
10243 lstrcpyA(patchcode, "apple");
10244 lstrcpyA(targetprod, "banana");
10245 context = 0xdeadbeef;
10246 lstrcpyA(targetsid, "kiwi");
10247 size = MAX_PATH;
10248 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10249 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10250 &context, targetsid, &size);
10251 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10252 ok(!lstrcmpA(patchcode, "apple"),
10253 "Expected patchcode to be unchanged, got %s\n", patchcode);
10254 ok(!lstrcmpA(targetprod, "banana"),
10255 "Expected targetprod to be unchanged, got %s\n", targetprod);
10256 ok(context == 0xdeadbeef,
10257 "Expected context to be unchanged, got %d\n", context);
10258 ok(!lstrcmpA(targetsid, "kiwi"),
10259 "Expected targetsid to be unchanged, got %s\n", targetsid);
10260 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10261
10262 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10263 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10264
10265 /* Patches key exists */
10266 lstrcpyA(patchcode, "apple");
10267 lstrcpyA(targetprod, "banana");
10268 context = 0xdeadbeef;
10269 lstrcpyA(targetsid, "kiwi");
10270 size = MAX_PATH;
10271 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10272 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10273 &context, targetsid, &size);
10274 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10275 ok(!lstrcmpA(patchcode, "apple"),
10276 "Expected patchcode to be unchanged, got %s\n", patchcode);
10277 ok(!lstrcmpA(targetprod, "banana"),
10278 "Expected targetprod to be unchanged, got %s\n", targetprod);
10279 ok(context == 0xdeadbeef,
10280 "Expected context to be unchanged, got %d\n", context);
10281 ok(!lstrcmpA(targetsid, "kiwi"),
10282 "Expected targetsid to be unchanged, got %s\n", targetsid);
10283 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10284
10285 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10286 (const BYTE *)patch_squashed,
10287 lstrlenA(patch_squashed) + 1);
10288 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10289
10290 /* Patches value exists, is not REG_MULTI_SZ */
10291 lstrcpyA(patchcode, "apple");
10292 lstrcpyA(targetprod, "banana");
10293 context = 0xdeadbeef;
10294 lstrcpyA(targetsid, "kiwi");
10295 size = MAX_PATH;
10296 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10297 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10298 &context, targetsid, &size);
10299 ok(r == ERROR_BAD_CONFIGURATION,
10300 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10301 ok(!lstrcmpA(patchcode, "apple"),
10302 "Expected patchcode to be unchanged, got %s\n", patchcode);
10303 ok(!lstrcmpA(targetprod, "banana"),
10304 "Expected targetprod to be unchanged, got %s\n", targetprod);
10305 ok(context == 0xdeadbeef,
10306 "Expected context to be unchanged, got %d\n", context);
10307 ok(!lstrcmpA(targetsid, "kiwi"),
10308 "Expected targetsid to be unchanged, got %s\n", targetsid);
10309 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10310
10311 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10312 (const BYTE *)"a\0b\0c\0\0", 7);
10313 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10314
10315 /* Patches value exists, is not a squashed guid */
10316 lstrcpyA(patchcode, "apple");
10317 lstrcpyA(targetprod, "banana");
10318 context = 0xdeadbeef;
10319 lstrcpyA(targetsid, "kiwi");
10320 size = MAX_PATH;
10321 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10322 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10323 &context, targetsid, &size);
10324 ok(r == ERROR_BAD_CONFIGURATION,
10325 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10326 ok(!lstrcmpA(patchcode, "apple"),
10327 "Expected patchcode to be unchanged, got %s\n", patchcode);
10328 ok(!lstrcmpA(targetprod, "banana"),
10329 "Expected targetprod to be unchanged, got %s\n", targetprod);
10330 ok(context == 0xdeadbeef,
10331 "Expected context to be unchanged, got %d\n", context);
10332 ok(!lstrcmpA(targetsid, "kiwi"),
10333 "Expected targetsid to be unchanged, got %s\n", targetsid);
10334 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10335
10336 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10337 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10338 (const BYTE *)patch_squashed,
10339 lstrlenA(patch_squashed) + 2);
10340 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10341
10342 /* Patches value exists */
10343 lstrcpyA(patchcode, "apple");
10344 lstrcpyA(targetprod, "banana");
10345 context = 0xdeadbeef;
10346 lstrcpyA(targetsid, "kiwi");
10347 size = MAX_PATH;
10348 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10349 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10350 &context, targetsid, &size);
10351 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10352 ok(!lstrcmpA(patchcode, "apple"),
10353 "Expected patchcode to be unchanged, got %s\n", patchcode);
10354 ok(!lstrcmpA(targetprod, "banana"),
10355 "Expected targetprod to be unchanged, got %s\n", targetprod);
10356 ok(context == 0xdeadbeef,
10357 "Expected context to be unchanged, got %d\n", context);
10358 ok(!lstrcmpA(targetsid, "kiwi"),
10359 "Expected targetsid to be unchanged, got %s\n", targetsid);
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 code value exists */
10367 lstrcpyA(patchcode, "apple");
10368 lstrcpyA(targetprod, "banana");
10369 context = 0xdeadbeef;
10370 lstrcpyA(targetsid, "kiwi");
10371 size = MAX_PATH;
10372 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10373 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10374 &context, targetsid, &size);
10375 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10376 ok(!lstrcmpA(patchcode, patch),
10377 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10378 ok(!lstrcmpA(targetprod, prodcode),
10379 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10380 ok(context == MSIINSTALLCONTEXT_MACHINE,
10381 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10382 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10383 ok(size == 0, "Expected 0, got %d\n", size);
10384
10385 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10386 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10387 lstrcatA(keypath, prod_squashed);
10388
10389 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10390 if (res == ERROR_ACCESS_DENIED)
10391 {
10392 skip("Not enough rights to perform tests\n");
10393 goto done;
10394 }
10395 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10396
10397 /* local UserData product key exists */
10398 lstrcpyA(patchcode, "apple");
10399 lstrcpyA(targetprod, "banana");
10400 context = 0xdeadbeef;
10401 lstrcpyA(targetsid, "kiwi");
10402 size = MAX_PATH;
10403 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10404 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10405 &context, targetsid, &size);
10406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10407 ok(!lstrcmpA(patchcode, patch),
10408 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10409 ok(!lstrcmpA(targetprod, prodcode),
10410 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10411 ok(context == MSIINSTALLCONTEXT_MACHINE,
10412 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10413 ok(!lstrcmpA(targetsid, ""),
10414 "Expected \"\", got \"%s\"\n", targetsid);
10415 ok(size == 0, "Expected 0, got %d\n", size);
10416
10417 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10418 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10419
10420 /* local UserData Patches key exists */
10421 lstrcpyA(patchcode, "apple");
10422 lstrcpyA(targetprod, "banana");
10423 context = 0xdeadbeef;
10424 lstrcpyA(targetsid, "kiwi");
10425 size = MAX_PATH;
10426 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10427 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10428 &context, targetsid, &size);
10429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10430 ok(!lstrcmpA(patchcode, patch),
10431 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10432 ok(!lstrcmpA(targetprod, prodcode),
10433 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10434 ok(context == MSIINSTALLCONTEXT_MACHINE,
10435 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10436 ok(!lstrcmpA(targetsid, ""),
10437 "Expected \"\", got \"%s\"\n", targetsid);
10438 ok(size == 0, "Expected 0, got %d\n", size);
10439
10440 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10442
10443 /* local UserData Product patch key exists */
10444 lstrcpyA(patchcode, "apple");
10445 lstrcpyA(targetprod, "banana");
10446 context = 0xdeadbeef;
10447 lstrcpyA(targetsid, "kiwi");
10448 size = MAX_PATH;
10449 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10450 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10451 &context, targetsid, &size);
10452 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10453 ok(!lstrcmpA(patchcode, "apple"),
10454 "Expected patchcode to be unchanged, got %s\n", patchcode);
10455 ok(!lstrcmpA(targetprod, "banana"),
10456 "Expected targetprod to be unchanged, got %s\n", targetprod);
10457 ok(context == 0xdeadbeef,
10458 "Expected context to be unchanged, got %d\n", context);
10459 ok(!lstrcmpA(targetsid, "kiwi"),
10460 "Expected targetsid to be unchanged, got %s\n", targetsid);
10461 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10462
10463 data = MSIPATCHSTATE_APPLIED;
10464 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10465 (const BYTE *)&data, sizeof(DWORD));
10466 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10467
10468 /* State value exists */
10469 lstrcpyA(patchcode, "apple");
10470 lstrcpyA(targetprod, "banana");
10471 context = 0xdeadbeef;
10472 lstrcpyA(targetsid, "kiwi");
10473 size = MAX_PATH;
10474 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10475 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10476 &context, targetsid, &size);
10477 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10478 ok(!lstrcmpA(patchcode, patch),
10479 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10480 ok(!lstrcmpA(targetprod, prodcode),
10481 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10482 ok(context == MSIINSTALLCONTEXT_MACHINE,
10483 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10484 ok(!lstrcmpA(targetsid, ""),
10485 "Expected \"\", got \"%s\"\n", targetsid);
10486 ok(size == 0, "Expected 0, got %d\n", size);
10487
10488 /* MSIPATCHSTATE_SUPERSEDED */
10489
10490 lstrcpyA(patchcode, "apple");
10491 lstrcpyA(targetprod, "banana");
10492 context = 0xdeadbeef;
10493 lstrcpyA(targetsid, "kiwi");
10494 size = MAX_PATH;
10495 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10496 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10497 &context, targetsid, &size);
10498 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10499 ok(!lstrcmpA(patchcode, "apple"),
10500 "Expected patchcode to be unchanged, got %s\n", patchcode);
10501 ok(!lstrcmpA(targetprod, "banana"),
10502 "Expected targetprod to be unchanged, got %s\n", targetprod);
10503 ok(context == 0xdeadbeef,
10504 "Expected context to be unchanged, got %d\n", context);
10505 ok(!lstrcmpA(targetsid, "kiwi"),
10506 "Expected targetsid to be unchanged, got %s\n", targetsid);
10507 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10508
10509 data = MSIPATCHSTATE_SUPERSEDED;
10510 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10511 (const BYTE *)&data, sizeof(DWORD));
10512 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10513
10514 /* State value is MSIPATCHSTATE_SUPERSEDED */
10515 lstrcpyA(patchcode, "apple");
10516 lstrcpyA(targetprod, "banana");
10517 context = 0xdeadbeef;
10518 lstrcpyA(targetsid, "kiwi");
10519 size = MAX_PATH;
10520 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10521 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10522 &context, targetsid, &size);
10523 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10524 ok(!lstrcmpA(patchcode, patch),
10525 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10526 ok(!lstrcmpA(targetprod, prodcode),
10527 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10528 ok(context == MSIINSTALLCONTEXT_MACHINE,
10529 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10530 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10531 ok(size == 0, "Expected 0, got %d\n", size);
10532
10533 /* MSIPATCHSTATE_OBSOLETED */
10534
10535 lstrcpyA(patchcode, "apple");
10536 lstrcpyA(targetprod, "banana");
10537 context = 0xdeadbeef;
10538 lstrcpyA(targetsid, "kiwi");
10539 size = MAX_PATH;
10540 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10541 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10542 &context, targetsid, &size);
10543 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10544 ok(!lstrcmpA(patchcode, "apple"),
10545 "Expected patchcode to be unchanged, got %s\n", patchcode);
10546 ok(!lstrcmpA(targetprod, "banana"),
10547 "Expected targetprod to be unchanged, got %s\n", targetprod);
10548 ok(context == 0xdeadbeef,
10549 "Expected context to be unchanged, got %d\n", context);
10550 ok(!lstrcmpA(targetsid, "kiwi"),
10551 "Expected targetsid to be unchanged, got %s\n", targetsid);
10552 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10553
10554 data = MSIPATCHSTATE_OBSOLETED;
10555 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10556 (const BYTE *)&data, sizeof(DWORD));
10557 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10558
10559 /* State value is obsoleted */
10560 lstrcpyA(patchcode, "apple");
10561 lstrcpyA(targetprod, "banana");
10562 context = 0xdeadbeef;
10563 lstrcpyA(targetsid, "kiwi");
10564 size = MAX_PATH;
10565 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10566 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10567 &context, targetsid, &size);
10568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10569 ok(!lstrcmpA(patchcode, patch),
10570 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10571 ok(!lstrcmpA(targetprod, prodcode),
10572 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10573 ok(context == MSIINSTALLCONTEXT_MACHINE,
10574 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10575 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10576 ok(size == 0, "Expected 0, got %d\n", size);
10577
10578 /* MSIPATCHSTATE_REGISTERED */
10579 /* FIXME */
10580
10581 /* MSIPATCHSTATE_ALL */
10582
10583 /* 1st */
10584 lstrcpyA(patchcode, "apple");
10585 lstrcpyA(targetprod, "banana");
10586 context = 0xdeadbeef;
10587 lstrcpyA(targetsid, "kiwi");
10588 size = MAX_PATH;
10589 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10590 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10591 &context, targetsid, &size);
10592 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10593 ok(!lstrcmpA(patchcode, patch),
10594 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10595 ok(!lstrcmpA(targetprod, prodcode),
10596 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10597 ok(context == MSIINSTALLCONTEXT_MACHINE,
10598 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10599 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10600 ok(size == 0, "Expected 0, got %d\n", size);
10601
10602 /* same patch in multiple places, only one is enumerated */
10603 lstrcpyA(patchcode, "apple");
10604 lstrcpyA(targetprod, "banana");
10605 context = 0xdeadbeef;
10606 lstrcpyA(targetsid, "kiwi");
10607 size = MAX_PATH;
10608 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10609 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10610 &context, targetsid, &size);
10611 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10612 ok(!lstrcmpA(patchcode, "apple"),
10613 "Expected patchcode to be unchanged, got %s\n", patchcode);
10614 ok(!lstrcmpA(targetprod, "banana"),
10615 "Expected targetprod to be unchanged, got %s\n", targetprod);
10616 ok(context == 0xdeadbeef,
10617 "Expected context to be unchanged, got %d\n", context);
10618 ok(!lstrcmpA(targetsid, "kiwi"),
10619 "Expected targetsid to be unchanged, got %s\n", targetsid);
10620 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10621
10622 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10623 RegCloseKey(hpatch);
10624 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10625 RegCloseKey(udpatch);
10626
10627 done:
10628 RegDeleteValueA(patches, patch_squashed);
10629 RegDeleteValueA(patches, "Patches");
10630 delete_key(patches, "", access & KEY_WOW64_64KEY);
10631 RegCloseKey(patches);
10632 RegDeleteValueA(hpatch, "State");
10633 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10634 RegCloseKey(udprod);
10635 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10636 RegCloseKey(prodkey);
10637 }
10638
10639 static void test_MsiEnumPatchesEx(void)
10640 {
10641 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10642 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10643 CHAR patchcode[MAX_PATH];
10644 MSIINSTALLCONTEXT context;
10645 LPSTR usersid;
10646 DWORD size;
10647 UINT r;
10648
10649 if (!pMsiEnumPatchesExA)
10650 {
10651 win_skip("MsiEnumPatchesExA not implemented\n");
10652 return;
10653 }
10654
10655 create_test_guid(prodcode, prod_squashed);
10656 usersid = get_user_sid();
10657
10658 /* empty szProductCode */
10659 lstrcpyA(patchcode, "apple");
10660 lstrcpyA(targetprod, "banana");
10661 context = 0xdeadbeef;
10662 lstrcpyA(targetsid, "kiwi");
10663 size = MAX_PATH;
10664 r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10665 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10666 targetsid, &size);
10667 ok(r == ERROR_INVALID_PARAMETER,
10668 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10669 ok(!lstrcmpA(patchcode, "apple"),
10670 "Expected patchcode to be unchanged, got %s\n", patchcode);
10671 ok(!lstrcmpA(targetprod, "banana"),
10672 "Expected targetprod to be unchanged, got %s\n", targetprod);
10673 ok(context == 0xdeadbeef,
10674 "Expected context to be unchanged, got %d\n", context);
10675 ok(!lstrcmpA(targetsid, "kiwi"),
10676 "Expected targetsid to be unchanged, got %s\n", targetsid);
10677 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10678
10679 /* garbage szProductCode */
10680 lstrcpyA(patchcode, "apple");
10681 lstrcpyA(targetprod, "banana");
10682 context = 0xdeadbeef;
10683 lstrcpyA(targetsid, "kiwi");
10684 size = MAX_PATH;
10685 r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10686 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10687 targetsid, &size);
10688 ok(r == ERROR_INVALID_PARAMETER,
10689 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10690 ok(!lstrcmpA(patchcode, "apple"),
10691 "Expected patchcode to be unchanged, got %s\n", patchcode);
10692 ok(!lstrcmpA(targetprod, "banana"),
10693 "Expected targetprod to be unchanged, got %s\n", targetprod);
10694 ok(context == 0xdeadbeef,
10695 "Expected context to be unchanged, got %d\n", context);
10696 ok(!lstrcmpA(targetsid, "kiwi"),
10697 "Expected targetsid to be unchanged, got %s\n", targetsid);
10698 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10699
10700 /* guid without brackets */
10701 lstrcpyA(patchcode, "apple");
10702 lstrcpyA(targetprod, "banana");
10703 context = 0xdeadbeef;
10704 lstrcpyA(targetsid, "kiwi");
10705 size = MAX_PATH;
10706 r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
10707 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10708 0, patchcode, targetprod, &context,
10709 targetsid, &size);
10710 ok(r == ERROR_INVALID_PARAMETER,
10711 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10712 ok(!lstrcmpA(patchcode, "apple"),
10713 "Expected patchcode to be unchanged, got %s\n", patchcode);
10714 ok(!lstrcmpA(targetprod, "banana"),
10715 "Expected targetprod to be unchanged, got %s\n", targetprod);
10716 ok(context == 0xdeadbeef,
10717 "Expected context to be unchanged, got %d\n", context);
10718 ok(!lstrcmpA(targetsid, "kiwi"),
10719 "Expected targetsid to be unchanged, got %s\n", targetsid);
10720 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10721
10722 /* guid with brackets */
10723 lstrcpyA(patchcode, "apple");
10724 lstrcpyA(targetprod, "banana");
10725 context = 0xdeadbeef;
10726 lstrcpyA(targetsid, "kiwi");
10727 size = MAX_PATH;
10728 r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
10729 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10730 0, patchcode, targetprod, &context,
10731 targetsid, &size);
10732 ok(r == ERROR_NO_MORE_ITEMS,
10733 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10734 ok(!lstrcmpA(patchcode, "apple"),
10735 "Expected patchcode to be unchanged, got %s\n", patchcode);
10736 ok(!lstrcmpA(targetprod, "banana"),
10737 "Expected targetprod to be unchanged, got %s\n", targetprod);
10738 ok(context == 0xdeadbeef,
10739 "Expected context to be unchanged, got %d\n", context);
10740 ok(!lstrcmpA(targetsid, "kiwi"),
10741 "Expected targetsid to be unchanged, got %s\n", targetsid);
10742 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10743
10744 /* szUserSid is S-1-5-18 */
10745 lstrcpyA(patchcode, "apple");
10746 lstrcpyA(targetprod, "banana");
10747 context = 0xdeadbeef;
10748 lstrcpyA(targetsid, "kiwi");
10749 size = MAX_PATH;
10750 r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
10751 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10752 0, patchcode, targetprod, &context,
10753 targetsid, &size);
10754 ok(r == ERROR_INVALID_PARAMETER,
10755 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10756 ok(!lstrcmpA(patchcode, "apple"),
10757 "Expected patchcode to be unchanged, got %s\n", patchcode);
10758 ok(!lstrcmpA(targetprod, "banana"),
10759 "Expected targetprod to be unchanged, got %s\n", targetprod);
10760 ok(context == 0xdeadbeef,
10761 "Expected context to be unchanged, got %d\n", context);
10762 ok(!lstrcmpA(targetsid, "kiwi"),
10763 "Expected targetsid to be unchanged, got %s\n", targetsid);
10764 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10765
10766 /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
10767 lstrcpyA(patchcode, "apple");
10768 lstrcpyA(targetprod, "banana");
10769 context = 0xdeadbeef;
10770 lstrcpyA(targetsid, "kiwi");
10771 size = MAX_PATH;
10772 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
10773 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10774 &context, targetsid, &size);
10775 ok(r == ERROR_INVALID_PARAMETER,
10776 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10777 ok(!lstrcmpA(patchcode, "apple"),
10778 "Expected patchcode to be unchanged, got %s\n", patchcode);
10779 ok(!lstrcmpA(targetprod, "banana"),
10780 "Expected targetprod to be unchanged, got %s\n", targetprod);
10781 ok(context == 0xdeadbeef,
10782 "Expected context to be unchanged, got %d\n", context);
10783 ok(!lstrcmpA(targetsid, "kiwi"),
10784 "Expected targetsid to be unchanged, got %s\n", targetsid);
10785 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10786
10787 /* dwContext is out of bounds */
10788 lstrcpyA(patchcode, "apple");
10789 lstrcpyA(targetprod, "banana");
10790 context = 0xdeadbeef;
10791 lstrcpyA(targetsid, "kiwi");
10792 size = MAX_PATH;
10793 r = pMsiEnumPatchesExA(prodcode, usersid, 0,
10794 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10795 &context, targetsid, &size);
10796 ok(r == ERROR_INVALID_PARAMETER,
10797 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10798 ok(!lstrcmpA(patchcode, "apple"),
10799 "Expected patchcode to be unchanged, got %s\n", patchcode);
10800 ok(!lstrcmpA(targetprod, "banana"),
10801 "Expected targetprod to be unchanged, got %s\n", targetprod);
10802 ok(context == 0xdeadbeef,
10803 "Expected context to be unchanged, got %d\n", context);
10804 ok(!lstrcmpA(targetsid, "kiwi"),
10805 "Expected targetsid to be unchanged, got %s\n", targetsid);
10806 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10807
10808 /* dwContext is out of bounds */
10809 lstrcpyA(patchcode, "apple");
10810 lstrcpyA(targetprod, "banana");
10811 context = 0xdeadbeef;
10812 lstrcpyA(targetsid, "kiwi");
10813 size = MAX_PATH;
10814 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
10815 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10816 &context, targetsid, &size);
10817 ok(r == ERROR_INVALID_PARAMETER,
10818 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10819 ok(!lstrcmpA(patchcode, "apple"),
10820 "Expected patchcode to be unchanged, got %s\n", patchcode);
10821 ok(!lstrcmpA(targetprod, "banana"),
10822 "Expected targetprod to be unchanged, got %s\n", targetprod);
10823 ok(context == 0xdeadbeef,
10824 "Expected context to be unchanged, got %d\n", context);
10825 ok(!lstrcmpA(targetsid, "kiwi"),
10826 "Expected targetsid to be unchanged, got %s\n", targetsid);
10827 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10828
10829 /* dwFilter is out of bounds */
10830 lstrcpyA(patchcode, "apple");
10831 lstrcpyA(targetprod, "banana");
10832 context = 0xdeadbeef;
10833 lstrcpyA(targetsid, "kiwi");
10834 size = MAX_PATH;
10835 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10836 MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
10837 &context, targetsid, &size);
10838 ok(r == ERROR_INVALID_PARAMETER,
10839 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10840 ok(!lstrcmpA(patchcode, "apple"),
10841 "Expected patchcode to be unchanged, got %s\n", patchcode);
10842 ok(!lstrcmpA(targetprod, "banana"),
10843 "Expected targetprod to be unchanged, got %s\n", targetprod);
10844 ok(context == 0xdeadbeef,
10845 "Expected context to be unchanged, got %d\n", context);
10846 ok(!lstrcmpA(targetsid, "kiwi"),
10847 "Expected targetsid to be unchanged, got %s\n", targetsid);
10848 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10849
10850 /* dwFilter is out of bounds */
10851 lstrcpyA(patchcode, "apple");
10852 lstrcpyA(targetprod, "banana");
10853 context = 0xdeadbeef;
10854 lstrcpyA(targetsid, "kiwi");
10855 size = MAX_PATH;
10856 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10857 MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
10858 &context, targetsid, &size);
10859 ok(r == ERROR_INVALID_PARAMETER,
10860 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10861 ok(!lstrcmpA(patchcode, "apple"),
10862 "Expected patchcode to be unchanged, got %s\n", patchcode);
10863 ok(!lstrcmpA(targetprod, "banana"),
10864 "Expected targetprod to be unchanged, got %s\n", targetprod);
10865 ok(context == 0xdeadbeef,
10866 "Expected context to be unchanged, got %d\n", context);
10867 ok(!lstrcmpA(targetsid, "kiwi"),
10868 "Expected targetsid to be unchanged, got %s\n", targetsid);
10869 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10870
10871 /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
10872 lstrcpyA(patchcode, "apple");
10873 lstrcpyA(targetprod, "banana");
10874 context = 0xdeadbeef;
10875 lstrcpyA(targetsid, "kiwi");
10876 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10877 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10878 &context, targetsid, NULL);
10879 ok(r == ERROR_INVALID_PARAMETER,
10880 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10881 ok(!lstrcmpA(patchcode, "apple"),
10882 "Expected patchcode to be unchanged, got %s\n", patchcode);
10883 ok(!lstrcmpA(targetprod, "banana"),
10884 "Expected targetprod to be unchanged, got %s\n", targetprod);
10885 ok(context == 0xdeadbeef,
10886 "Expected context to be unchanged, got %d\n", context);
10887 ok(!lstrcmpA(targetsid, "kiwi"),
10888 "Expected targetsid to be unchanged, got %s\n", targetsid);
10889
10890 test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
10891 test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
10892 test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
10893 test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
10894 test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
10895 /* FIXME: Successfully test userunmanaged with a different user */
10896 test_MsiEnumPatchesEx_machine();
10897 LocalFree(usersid);
10898 }
10899
10900 static void test_MsiEnumPatches(void)
10901 {
10902 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10903 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10904 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10905 CHAR transforms[MAX_PATH];
10906 WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
10907 HKEY prodkey, patches, udprod;
10908 HKEY userkey, hpatch, udpatch;
10909 DWORD size, data;
10910 LPSTR usersid;
10911 LONG res;
10912 UINT r;
10913 REGSAM access = KEY_ALL_ACCESS;
10914
10915 create_test_guid(prodcode, prod_squashed);
10916 create_test_guid(patchcode, patch_squashed);
10917 usersid = get_user_sid();
10918
10919 if (is_wow64)
10920 access |= KEY_WOW64_64KEY;
10921
10922 /* NULL szProduct */
10923 size = MAX_PATH;
10924 lstrcpyA(patch, "apple");
10925 lstrcpyA(transforms, "banana");
10926 r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
10927 ok(r == ERROR_INVALID_PARAMETER,
10928 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10929 ok(!lstrcmpA(patch, "apple"),
10930 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10931 ok(!lstrcmpA(transforms, "banana"),
10932 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10933 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10934
10935 /* empty szProduct */
10936 size = MAX_PATH;
10937 lstrcpyA(patch, "apple");
10938 lstrcpyA(transforms, "banana");
10939 r = MsiEnumPatchesA("", 0, patch, transforms, &size);
10940 ok(r == ERROR_INVALID_PARAMETER,
10941 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10942 ok(!lstrcmpA(patch, "apple"),
10943 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10944 ok(!lstrcmpA(transforms, "banana"),
10945 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10946 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10947
10948 /* garbage szProduct */
10949 size = MAX_PATH;
10950 lstrcpyA(patch, "apple");
10951 lstrcpyA(transforms, "banana");
10952 r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
10953 ok(r == ERROR_INVALID_PARAMETER,
10954 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10955 ok(!lstrcmpA(patch, "apple"),
10956 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10957 ok(!lstrcmpA(transforms, "banana"),
10958 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10959 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10960
10961 /* guid without brackets */
10962 size = MAX_PATH;
10963 lstrcpyA(patch, "apple");
10964 lstrcpyA(transforms, "banana");
10965 r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
10966 transforms, &size);
10967 ok(r == ERROR_INVALID_PARAMETER,
10968 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10969 ok(!lstrcmpA(patch, "apple"),
10970 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10971 ok(!lstrcmpA(transforms, "banana"),
10972 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10973 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10974
10975 /* guid with brackets */
10976 size = MAX_PATH;
10977 lstrcpyA(patch, "apple");
10978 lstrcpyA(transforms, "banana");
10979 r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
10980 transforms, &size);
10981 ok(r == ERROR_UNKNOWN_PRODUCT,
10982 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10983 ok(!lstrcmpA(patch, "apple"),
10984 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10985 ok(!lstrcmpA(transforms, "banana"),
10986 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10987 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10988
10989 /* same length as guid, but random */
10990 size = MAX_PATH;
10991 lstrcpyA(patch, "apple");
10992 lstrcpyA(transforms, "banana");
10993 r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
10994 transforms, &size);
10995 ok(r == ERROR_INVALID_PARAMETER,
10996 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10997 ok(!lstrcmpA(patch, "apple"),
10998 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10999 ok(!lstrcmpA(transforms, "banana"),
11000 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11001 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11002
11003 /* MSIINSTALLCONTEXT_USERMANAGED */
11004
11005 size = MAX_PATH;
11006 lstrcpyA(patch, "apple");
11007 lstrcpyA(transforms, "banana");
11008 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11009 ok(r == ERROR_UNKNOWN_PRODUCT,
11010 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11011 ok(!lstrcmpA(patch, "apple"),
11012 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11013 ok(!lstrcmpA(transforms, "banana"),
11014 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11015 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11016
11017 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11018 lstrcatA(keypath, usersid);
11019 lstrcatA(keypath, "\\Installer\\Products\\");
11020 lstrcatA(keypath, prod_squashed);
11021
11022 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11023 if (res == ERROR_ACCESS_DENIED)
11024 {
11025 skip("Not enough rights to perform tests\n");
11026 LocalFree(usersid);
11027 return;
11028 }
11029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11030
11031 /* managed product key exists */
11032 size = MAX_PATH;
11033 lstrcpyA(patch, "apple");
11034 lstrcpyA(transforms, "banana");
11035 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11036 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11037 ok(!lstrcmpA(patch, "apple"),
11038 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11039 ok(!lstrcmpA(transforms, "banana"),
11040 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11041 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11042
11043 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11044 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11045
11046 /* patches key exists */
11047 size = MAX_PATH;
11048 lstrcpyA(patch, "apple");
11049 lstrcpyA(transforms, "banana");
11050 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11051 ok(r == ERROR_NO_MORE_ITEMS ||
11052 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11053 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11054 ok(!lstrcmpA(patch, "apple"),
11055 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11056 ok(!lstrcmpA(transforms, "banana"),
11057 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11058 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11059
11060 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11061 (const BYTE *)patch_squashed,
11062 lstrlenA(patch_squashed) + 1);
11063 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11064
11065 /* Patches value exists, is not REG_MULTI_SZ */
11066 size = MAX_PATH;
11067 lstrcpyA(patch, "apple");
11068 lstrcpyA(transforms, "banana");
11069 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11070 ok(r == ERROR_BAD_CONFIGURATION ||
11071 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11072 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11073 ok(!lstrcmpA(patch, "apple"),
11074 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11075 ok(!lstrcmpA(transforms, "banana"),
11076 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11077 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11078
11079 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11080 (const BYTE *)"a\0b\0c\0\0", 7);
11081 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11082
11083 /* Patches value exists, is not a squashed guid */
11084 size = MAX_PATH;
11085 lstrcpyA(patch, "apple");
11086 lstrcpyA(transforms, "banana");
11087 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11088 ok(r == ERROR_BAD_CONFIGURATION,
11089 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11090 ok(!lstrcmpA(patch, "apple"),
11091 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11092 ok(!lstrcmpA(transforms, "banana"),
11093 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11094 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11095
11096 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11097 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11098 (const BYTE *)patch_squashed,
11099 lstrlenA(patch_squashed) + 2);
11100 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11101
11102 /* Patches value exists */
11103 size = MAX_PATH;
11104 lstrcpyA(patch, "apple");
11105 lstrcpyA(transforms, "banana");
11106 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11107 ok(r == ERROR_NO_MORE_ITEMS ||
11108 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11109 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11110 ok(!lstrcmpA(patch, "apple") ||
11111 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11112 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11113 ok(!lstrcmpA(transforms, "banana"),
11114 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11115 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11116
11117 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11118 (const BYTE *)"whatever", 9);
11119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11120
11121 /* patch squashed value exists */
11122 size = MAX_PATH;
11123 lstrcpyA(patch, "apple");
11124 lstrcpyA(transforms, "banana");
11125 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11126 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11127 ok(!lstrcmpA(patch, patchcode),
11128 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11129 ok(!lstrcmpA(transforms, "whatever"),
11130 "Expected \"whatever\", got \"%s\"\n", transforms);
11131 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11132
11133 /* lpPatchBuf is NULL */
11134 size = MAX_PATH;
11135 lstrcpyA(transforms, "banana");
11136 r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
11137 ok(r == ERROR_INVALID_PARAMETER,
11138 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11139 ok(!lstrcmpA(transforms, "banana"),
11140 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11141 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11142
11143 /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
11144 size = MAX_PATH;
11145 lstrcpyA(patch, "apple");
11146 r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
11147 ok(r == ERROR_INVALID_PARAMETER,
11148 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11149 ok(!lstrcmpA(patch, "apple"),
11150 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11151 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11152
11153 /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
11154 lstrcpyA(patch, "apple");
11155 lstrcpyA(transforms, "banana");
11156 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
11157 ok(r == ERROR_INVALID_PARAMETER,
11158 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11159 ok(!lstrcmpA(patch, "apple"),
11160 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11161 ok(!lstrcmpA(transforms, "banana"),
11162 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11163
11164 /* pcchTransformsBuf is too small */
11165 size = 6;
11166 lstrcpyA(patch, "apple");
11167 lstrcpyA(transforms, "banana");
11168 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11169 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11170 ok(!lstrcmpA(patch, patchcode),
11171 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11172 ok(!lstrcmpA(transforms, "whate") ||
11173 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11174 "Expected \"whate\", got \"%s\"\n", transforms);
11175 ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
11176
11177 /* increase the index */
11178 size = MAX_PATH;
11179 lstrcpyA(patch, "apple");
11180 lstrcpyA(transforms, "banana");
11181 r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
11182 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11183 ok(!lstrcmpA(patch, "apple"),
11184 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11185 ok(!lstrcmpA(transforms, "banana"),
11186 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11187 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11188
11189 /* increase again */
11190 size = MAX_PATH;
11191 lstrcpyA(patch, "apple");
11192 lstrcpyA(transforms, "banana");
11193 r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
11194 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11195 ok(!lstrcmpA(patch, "apple"),
11196 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11197 ok(!lstrcmpA(transforms, "banana"),
11198 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11199 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11200
11201 RegDeleteValueA(patches, "Patches");
11202 delete_key(patches, "", access & KEY_WOW64_64KEY);
11203 RegCloseKey(patches);
11204 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11205 RegCloseKey(prodkey);
11206
11207 /* MSIINSTALLCONTEXT_USERUNMANAGED */
11208
11209 size = MAX_PATH;
11210 lstrcpyA(patch, "apple");
11211 lstrcpyA(transforms, "banana");
11212 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11213 ok(r == ERROR_UNKNOWN_PRODUCT,
11214 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11215 ok(!lstrcmpA(patch, "apple"),
11216 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11217 ok(!lstrcmpA(transforms, "banana"),
11218 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11219 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11220
11221 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11222 lstrcatA(keypath, prod_squashed);
11223
11224 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11225 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11226
11227 /* current user product key exists */
11228 size = MAX_PATH;
11229 lstrcpyA(patch, "apple");
11230 lstrcpyA(transforms, "banana");
11231 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11232 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11233 ok(!lstrcmpA(patch, "apple"),
11234 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11235 ok(!lstrcmpA(transforms, "banana"),
11236 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11237 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11238
11239 res = RegCreateKeyA(prodkey, "Patches", &patches);
11240 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11241
11242 /* Patches key exists */
11243 size = MAX_PATH;
11244 lstrcpyA(patch, "apple");
11245 lstrcpyA(transforms, "banana");
11246 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11247 ok(r == ERROR_NO_MORE_ITEMS ||
11248 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11249 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11250 ok(!lstrcmpA(patch, "apple"),
11251 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11252 ok(!lstrcmpA(transforms, "banana"),
11253 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11254 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11255
11256 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11257 (const BYTE *)patch_squashed,
11258 lstrlenA(patch_squashed) + 1);
11259 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11260
11261 /* Patches value exists, is not REG_MULTI_SZ */
11262 size = MAX_PATH;
11263 lstrcpyA(patch, "apple");
11264 lstrcpyA(transforms, "banana");
11265 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11266 ok(r == ERROR_BAD_CONFIGURATION ||
11267 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11268 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11269 ok(!lstrcmpA(patch, "apple"),
11270 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11271 ok(!lstrcmpA(transforms, "banana"),
11272 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11273 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11274
11275 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11276 (const BYTE *)"a\0b\0c\0\0", 7);
11277 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11278
11279 /* Patches value exists, is not a squashed guid */
11280 size = MAX_PATH;
11281 lstrcpyA(patch, "apple");
11282 lstrcpyA(transforms, "banana");
11283 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11284 ok(r == ERROR_BAD_CONFIGURATION,
11285 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11286 ok(!lstrcmpA(patch, "apple"),
11287 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11288 ok(!lstrcmpA(transforms, "banana"),
11289 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11290 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11291
11292 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11293 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11294 (const BYTE *)patch_squashed,
11295 lstrlenA(patch_squashed) + 2);
11296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11297
11298 /* Patches value exists */
11299 size = MAX_PATH;
11300 lstrcpyA(patch, "apple");
11301 lstrcpyA(transforms, "banana");
11302 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11303 ok(r == ERROR_NO_MORE_ITEMS ||
11304 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11305 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11306 ok(!lstrcmpA(patch, "apple") ||
11307 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11308 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11309 ok(!lstrcmpA(transforms, "banana"),
11310 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11311 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11312
11313 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11314 (const BYTE *)"whatever", 9);
11315 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11316
11317 /* patch code value exists */
11318 size = MAX_PATH;
11319 lstrcpyA(patch, "apple");
11320 lstrcpyA(transforms, "banana");
11321 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11322 ok(r == ERROR_NO_MORE_ITEMS ||
11323 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11324 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11325 ok(!lstrcmpA(patch, "apple") ||
11326 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11327 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11328 ok(!lstrcmpA(transforms, "banana") ||
11329 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11330 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11331 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11332
11333 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11334 lstrcatA(keypath, usersid);
11335 lstrcatA(keypath, "\\Patches\\");
11336 lstrcatA(keypath, patch_squashed);
11337
11338 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
11339 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11340
11341 /* userdata patch key exists */
11342 size = MAX_PATH;
11343 lstrcpyA(patch, "apple");
11344 lstrcpyA(transforms, "banana");
11345 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11347 ok(!lstrcmpA(patch, patchcode),
11348 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11349 ok(!lstrcmpA(transforms, "whatever"),
11350 "Expected \"whatever\", got \"%s\"\n", transforms);
11351 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11352
11353 delete_key(userkey, "", access & KEY_WOW64_64KEY);
11354 RegCloseKey(userkey);
11355 RegDeleteValueA(patches, patch_squashed);
11356 RegDeleteValueA(patches, "Patches");
11357 RegDeleteKeyA(patches, "");
11358 RegCloseKey(patches);
11359 RegDeleteKeyA(prodkey, "");
11360 RegCloseKey(prodkey);
11361
11362 /* MSIINSTALLCONTEXT_MACHINE */
11363
11364 size = MAX_PATH;
11365 lstrcpyA(patch, "apple");
11366 lstrcpyA(transforms, "banana");
11367 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11368 ok(r == ERROR_UNKNOWN_PRODUCT,
11369 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11370 ok(!lstrcmpA(patch, "apple"),
11371 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11372 ok(!lstrcmpA(transforms, "banana"),
11373 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11374 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11375
11376 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11377 lstrcatA(keypath, prod_squashed);
11378
11379 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11380 if (res == ERROR_ACCESS_DENIED)
11381 {
11382 skip("Not enough rights to perform tests\n");
11383 LocalFree(usersid);
11384 return;
11385 }
11386 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11387
11388 /* local product key exists */
11389 size = MAX_PATH;
11390 lstrcpyA(patch, "apple");
11391 lstrcpyA(transforms, "banana");
11392 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11393 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11394 ok(!lstrcmpA(patch, "apple"),
11395 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11396 ok(!lstrcmpA(transforms, "banana"),
11397 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11398 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11399
11400 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11401 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11402
11403 /* Patches key exists */
11404 size = MAX_PATH;
11405 lstrcpyA(patch, "apple");
11406 lstrcpyA(transforms, "banana");
11407 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11408 ok(r == ERROR_NO_MORE_ITEMS ||
11409 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11410 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11411 ok(!lstrcmpA(patch, "apple"),
11412 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11413 ok(!lstrcmpA(transforms, "banana"),
11414 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11415 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11416
11417 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11418 (const BYTE *)patch_squashed,
11419 lstrlenA(patch_squashed) + 1);
11420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11421
11422 /* Patches value exists, is not REG_MULTI_SZ */
11423 size = MAX_PATH;
11424 lstrcpyA(patch, "apple");
11425 lstrcpyA(transforms, "banana");
11426 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11427 ok(r == ERROR_BAD_CONFIGURATION ||
11428 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11429 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11430 ok(!lstrcmpA(patch, "apple"),
11431 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11432 ok(!lstrcmpA(transforms, "banana"),
11433 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11434 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11435
11436 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11437 (const BYTE *)"a\0b\0c\0\0", 7);
11438 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11439
11440 /* Patches value exists, is not a squashed guid */
11441 size = MAX_PATH;
11442 lstrcpyA(patch, "apple");
11443 lstrcpyA(transforms, "banana");
11444 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11445 ok(r == ERROR_BAD_CONFIGURATION,
11446 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11447 ok(!lstrcmpA(patch, "apple"),
11448 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11449 ok(!lstrcmpA(transforms, "banana"),
11450 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11451 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11452
11453 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11454 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11455 (const BYTE *)patch_squashed,
11456 lstrlenA(patch_squashed) + 2);
11457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11458
11459 /* Patches value exists */
11460 size = MAX_PATH;
11461 lstrcpyA(patch, "apple");
11462 lstrcpyA(transforms, "banana");
11463 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11464 ok(r == ERROR_NO_MORE_ITEMS ||
11465 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11466 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11467 ok(!lstrcmpA(patch, "apple") ||
11468 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11469 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11470 ok(!lstrcmpA(transforms, "banana"),
11471 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11472 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11473
11474 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11475 (const BYTE *)"whatever", 9);
11476 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11477
11478 /* patch code value exists */
11479 size = MAX_PATH;
11480 lstrcpyA(patch, "apple");
11481 lstrcpyA(transforms, "banana");
11482 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11483 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11484 ok(!lstrcmpA(patch, patchcode),
11485 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11486 ok(!lstrcmpA(transforms, "whatever"),
11487 "Expected \"whatever\", got \"%s\"\n", transforms);
11488 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11489
11490 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
11491 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
11492 lstrcatA(keypath, prod_squashed);
11493
11494 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11496
11497 /* local UserData product key exists */
11498 size = MAX_PATH;
11499 lstrcpyA(patch, "apple");
11500 lstrcpyA(transforms, "banana");
11501 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11502 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11503 ok(!lstrcmpA(patch, patchcode),
11504 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11505 ok(!lstrcmpA(transforms, "whatever"),
11506 "Expected \"whatever\", got \"%s\"\n", transforms);
11507 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11508
11509 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
11510 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11511
11512 /* local UserData Patches key exists */
11513 size = MAX_PATH;
11514 lstrcpyA(patch, "apple");
11515 lstrcpyA(transforms, "banana");
11516 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11518 ok(!lstrcmpA(patch, patchcode),
11519 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11520 ok(!lstrcmpA(transforms, "whatever"),
11521 "Expected \"whatever\", got \"%s\"\n", transforms);
11522 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11523
11524 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11526
11527 /* local UserData Product patch key exists */
11528 size = MAX_PATH;
11529 lstrcpyA(patch, "apple");
11530 lstrcpyA(transforms, "banana");
11531 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11532 ok(r == ERROR_NO_MORE_ITEMS ||
11533 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11534 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11535 ok(!lstrcmpA(patch, "apple") ||
11536 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11537 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11538 ok(!lstrcmpA(transforms, "banana") ||
11539 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11540 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11541 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11542
11543 data = MSIPATCHSTATE_APPLIED;
11544 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11545 (const BYTE *)&data, sizeof(DWORD));
11546 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11547
11548 /* State value exists */
11549 size = MAX_PATH;
11550 lstrcpyA(patch, "apple");
11551 lstrcpyA(transforms, "banana");
11552 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11554 ok(!lstrcmpA(patch, patchcode),
11555 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11556 ok(!lstrcmpA(transforms, "whatever"),
11557 "Expected \"whatever\", got \"%s\"\n", transforms);
11558 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11559
11560 /* now duplicate some of the tests for the W version */
11561
11562 /* pcchTransformsBuf is too small */
11563 size = 6;
11564 MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
11565 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11566 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11567 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11568 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11569 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11570 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11571 ok(!lstrcmpA(patch, patchcode),
11572 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11573 ok(!lstrcmpA(transforms, "whate") ||
11574 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11575 "Expected \"whate\", got \"%s\"\n", transforms);
11576 ok(size == 8, "Expected 8, got %d\n", size);
11577
11578 /* patch code value exists */
11579 size = MAX_PATH;
11580 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11581 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11582 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11584 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11585 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11586 ok(!lstrcmpA(patch, patchcode),
11587 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11588 ok(!lstrcmpA(transforms, "whatever"),
11589 "Expected \"whatever\", got \"%s\"\n", transforms);
11590 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11591
11592 RegDeleteValueA(patches, patch_squashed);
11593 RegDeleteValueA(patches, "Patches");
11594 delete_key(patches, "", access & KEY_WOW64_64KEY);
11595 RegCloseKey(patches);
11596 RegDeleteValueA(hpatch, "State");
11597 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11598 RegCloseKey(hpatch);
11599 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11600 RegCloseKey(udpatch);
11601 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11602 RegCloseKey(udprod);
11603 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11604 RegCloseKey(prodkey);
11605 LocalFree(usersid);
11606 }
11607
11608 static void test_MsiGetPatchInfoEx(void)
11609 {
11610 CHAR keypath[MAX_PATH], val[MAX_PATH];
11611 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
11612 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11613 HKEY prodkey, patches, udprod, props;
11614 HKEY hpatch, udpatch, prodpatches;
11615 LPSTR usersid;
11616 DWORD size;
11617 LONG res;
11618 UINT r;
11619 REGSAM access = KEY_ALL_ACCESS;
11620
11621 if (!pMsiGetPatchInfoExA)
11622 {
11623 win_skip("MsiGetPatchInfoEx not implemented\n");
11624 return;
11625 }
11626
11627 create_test_guid(prodcode, prod_squashed);
11628 create_test_guid(patchcode, patch_squashed);
11629 usersid = get_user_sid();
11630
11631 if (is_wow64)
11632 access |= KEY_WOW64_64KEY;
11633
11634 /* NULL szPatchCode */
11635 lstrcpyA(val, "apple");
11636 size = MAX_PATH;
11637 r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11638 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11639 ok(r == ERROR_INVALID_PARAMETER,
11640 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11641 ok(!lstrcmpA(val, "apple"),
11642 "Expected val to be unchanged, got \"%s\"\n", val);
11643 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11644
11645 /* empty szPatchCode */
11646 size = MAX_PATH;
11647 lstrcpyA(val, "apple");
11648 r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11649 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11650 ok(r == ERROR_INVALID_PARAMETER,
11651 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11652 ok(!lstrcmpA(val, "apple"),
11653 "Expected val to be unchanged, got \"%s\"\n", val);
11654 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11655
11656 /* garbage szPatchCode */
11657 size = MAX_PATH;
11658 lstrcpyA(val, "apple");
11659 r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
11660 MSIINSTALLCONTEXT_USERMANAGED,
11661 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11662 ok(r == ERROR_INVALID_PARAMETER,
11663 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11664 ok(!lstrcmpA(val, "apple"),
11665 "Expected val to be unchanged, got \"%s\"\n", val);
11666 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11667
11668 /* guid without brackets */
11669 size = MAX_PATH;
11670 lstrcpyA(val, "apple");
11671 r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
11672 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11673 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11674 ok(r == ERROR_INVALID_PARAMETER,
11675 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11676 ok(!lstrcmpA(val, "apple"),
11677 "Expected val to be unchanged, got \"%s\"\n", val);
11678 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11679
11680 /* guid with brackets */
11681 size = MAX_PATH;
11682 lstrcpyA(val, "apple");
11683 r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
11684 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11685 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11686 ok(r == ERROR_UNKNOWN_PRODUCT,
11687 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11688 ok(!lstrcmpA(val, "apple"),
11689 "Expected val to be unchanged, got \"%s\"\n", val);
11690 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11691
11692 /* same length as guid, but random */
11693 size = MAX_PATH;
11694 lstrcpyA(val, "apple");
11695 r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
11696 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11697 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11698 ok(r == ERROR_INVALID_PARAMETER,
11699 "Expected ERROR_INVALID_PARAMETER, 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 /* NULL szProductCode */
11705 lstrcpyA(val, "apple");
11706 size = MAX_PATH;
11707 r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11708 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11709 ok(r == ERROR_INVALID_PARAMETER,
11710 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11711 ok(!lstrcmpA(val, "apple"),
11712 "Expected val to be unchanged, got \"%s\"\n", val);
11713 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11714
11715 /* empty szProductCode */
11716 size = MAX_PATH;
11717 lstrcpyA(val, "apple");
11718 r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
11719 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11720 ok(r == ERROR_INVALID_PARAMETER,
11721 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11722 ok(!lstrcmpA(val, "apple"),
11723 "Expected val to be unchanged, got \"%s\"\n", val);
11724 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11725
11726 /* garbage szProductCode */
11727 size = MAX_PATH;
11728 lstrcpyA(val, "apple");
11729 r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
11730 MSIINSTALLCONTEXT_USERMANAGED,
11731 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11732 ok(r == ERROR_INVALID_PARAMETER,
11733 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11734 ok(!lstrcmpA(val, "apple"),
11735 "Expected val to be unchanged, got \"%s\"\n", val);
11736 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11737
11738 /* guid without brackets */
11739 size = MAX_PATH;
11740 lstrcpyA(val, "apple");
11741 r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
11742 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11743 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11744 ok(r == ERROR_INVALID_PARAMETER,
11745 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11746 ok(!lstrcmpA(val, "apple"),
11747 "Expected val to be unchanged, got \"%s\"\n", val);
11748 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11749
11750 /* guid with brackets */
11751 size = MAX_PATH;
11752 lstrcpyA(val, "apple");
11753 r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
11754 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11755 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11756 ok(r == ERROR_UNKNOWN_PRODUCT,
11757 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11758 ok(!lstrcmpA(val, "apple"),
11759 "Expected val to be unchanged, got \"%s\"\n", val);
11760 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11761
11762 /* same length as guid, but random */
11763 size = MAX_PATH;
11764 lstrcpyA(val, "apple");
11765 r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
11766 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11767 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11768 ok(r == ERROR_INVALID_PARAMETER,
11769 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11770 ok(!lstrcmpA(val, "apple"),
11771 "Expected val to be unchanged, got \"%s\"\n", val);
11772 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11773
11774 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
11775 size = MAX_PATH;
11776 lstrcpyA(val, "apple");
11777 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11778 MSIINSTALLCONTEXT_USERMANAGED,
11779 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11780 ok(r == ERROR_INVALID_PARAMETER,
11781 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11782 ok(!lstrcmpA(val, "apple"),
11783 "Expected val to be unchanged, got \"%s\"\n", val);
11784 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11785
11786 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
11787 size = MAX_PATH;
11788 lstrcpyA(val, "apple");
11789 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11790 MSIINSTALLCONTEXT_USERUNMANAGED,
11791 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11792 ok(r == ERROR_INVALID_PARAMETER,
11793 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11794 ok(!lstrcmpA(val, "apple"),
11795 "Expected val to be unchanged, got \"%s\"\n", val);
11796 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11797
11798 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
11799 size = MAX_PATH;
11800 lstrcpyA(val, "apple");
11801 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11802 MSIINSTALLCONTEXT_MACHINE,
11803 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11804 ok(r == ERROR_INVALID_PARAMETER,
11805 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11806 ok(!lstrcmpA(val, "apple"),
11807 "Expected val to be unchanged, got \"%s\"\n", val);
11808 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11809
11810 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
11811 size = MAX_PATH;
11812 lstrcpyA(val, "apple");
11813 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11814 MSIINSTALLCONTEXT_MACHINE,
11815 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11816 ok(r == ERROR_INVALID_PARAMETER,
11817 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11818 ok(!lstrcmpA(val, "apple"),
11819 "Expected val to be unchanged, got \"%s\"\n", val);
11820 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11821
11822 /* dwContext is out of range */
11823 size = MAX_PATH;
11824 lstrcpyA(val, "apple");
11825 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11826 MSIINSTALLCONTEXT_NONE,
11827 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11828 ok(r == ERROR_INVALID_PARAMETER,
11829 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11830 ok(!lstrcmpA(val, "apple"),
11831 "Expected val to be unchanged, got \"%s\"\n", val);
11832 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11833
11834 /* dwContext is out of range */
11835 size = MAX_PATH;
11836 lstrcpyA(val, "apple");
11837 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11838 MSIINSTALLCONTEXT_ALL,
11839 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11840 ok(r == ERROR_INVALID_PARAMETER,
11841 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11842 ok(!lstrcmpA(val, "apple"),
11843 "Expected val to be unchanged, got \"%s\"\n", val);
11844 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11845
11846 /* dwContext is invalid */
11847 size = MAX_PATH;
11848 lstrcpyA(val, "apple");
11849 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
11850 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11851 ok(r == ERROR_INVALID_PARAMETER,
11852 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11853 ok(!lstrcmpA(val, "apple"),
11854 "Expected val to be unchanged, got \"%s\"\n", val);
11855 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11856
11857 /* MSIINSTALLCONTEXT_USERMANAGED */
11858
11859 size = MAX_PATH;
11860 lstrcpyA(val, "apple");
11861 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11862 MSIINSTALLCONTEXT_USERMANAGED,
11863 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11864 ok(r == ERROR_UNKNOWN_PRODUCT,
11865 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11866 ok(!lstrcmpA(val, "apple"),
11867 "Expected val to be unchanged, got \"%s\"\n", val);
11868 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11869
11870 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11871 lstrcatA(keypath, usersid);
11872 lstrcatA(keypath, "\\Products\\");
11873 lstrcatA(keypath, prod_squashed);
11874
11875 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11876 if (res == ERROR_ACCESS_DENIED)
11877 {
11878 skip("Not enough rights to perform tests\n");
11879 LocalFree(usersid);
11880 return;
11881 }
11882 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11883
11884 /* local UserData product key exists */
11885 size = MAX_PATH;
11886 lstrcpyA(val, "apple");
11887 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11888 MSIINSTALLCONTEXT_USERMANAGED,
11889 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11890 ok(r == ERROR_UNKNOWN_PRODUCT,
11891 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11892 ok(!lstrcmpA(val, "apple"),
11893 "Expected val to be unchanged, got \"%s\"\n", val);
11894 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11895
11896 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11897 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11898
11899 /* InstallProperties key exists */
11900 size = MAX_PATH;
11901 lstrcpyA(val, "apple");
11902 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11903 MSIINSTALLCONTEXT_USERMANAGED,
11904 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11905 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11906 ok(!lstrcmpA(val, "apple"),
11907 "Expected val to be unchanged, got \"%s\"\n", val);
11908 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11909
11910 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11911 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11912
11913 /* Patches key exists */
11914 size = MAX_PATH;
11915 lstrcpyA(val, "apple");
11916 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11917 MSIINSTALLCONTEXT_USERMANAGED,
11918 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11919 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCHA, got %d\n", r);
11920 ok(!lstrcmpA(val, "apple"),
11921 "Expected val to be unchanged, got \"%s\"\n", val);
11922 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11923
11924 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11925 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11926
11927 /* Patches key exists */
11928 size = MAX_PATH;
11929 lstrcpyA(val, "apple");
11930 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11931 MSIINSTALLCONTEXT_USERMANAGED,
11932 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11933 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11934 ok(!lstrcmpA(val, "apple"),
11935 "Expected val to be unchanged, got \"%s\"\n", val);
11936 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11937
11938 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11939 lstrcatA(keypath, usersid);
11940 lstrcatA(keypath, "\\Installer\\Products\\");
11941 lstrcatA(keypath, prod_squashed);
11942
11943 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11944 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11945
11946 /* managed product key exists */
11947 size = MAX_PATH;
11948 lstrcpyA(val, "apple");
11949 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11950 MSIINSTALLCONTEXT_USERMANAGED,
11951 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11952 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11953 ok(!lstrcmpA(val, "apple"),
11954 "Expected val to be unchanged, got \"%s\"\n", val);
11955 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11956
11957 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11958 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11959
11960 /* Patches key exists */
11961 size = MAX_PATH;
11962 lstrcpyA(val, "apple");
11963 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11964 MSIINSTALLCONTEXT_USERMANAGED,
11965 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11966 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11967 ok(!lstrcmpA(val, "apple"),
11968 "Expected val to be unchanged, got \"%s\"\n", val);
11969 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11970
11971 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11972 (const BYTE *)"transforms", 11);
11973 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11974
11975 /* specific patch value exists */
11976 size = MAX_PATH;
11977 lstrcpyA(val, "apple");
11978 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11979 MSIINSTALLCONTEXT_USERMANAGED,
11980 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11981 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11982 ok(!lstrcmpA(val, "apple"),
11983 "Expected val to be unchanged, got \"%s\"\n", val);
11984 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11985
11986 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11987 lstrcatA(keypath, usersid);
11988 lstrcatA(keypath, "\\Patches\\");
11989 lstrcatA(keypath, patch_squashed);
11990
11991 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11992 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11993
11994 /* UserData Patches key exists */
11995 size = MAX_PATH;
11996 lstrcpyA(val, "apple");
11997 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11998 MSIINSTALLCONTEXT_USERMANAGED,
11999 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12000 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12001 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12002 ok(size == 0, "Expected 0, got %d\n", size);
12003
12004 res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
12005 (const BYTE *)"pack", 5);
12006 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12007
12008 /* ManagedLocalPatch value exists */
12009 size = MAX_PATH;
12010 lstrcpyA(val, "apple");
12011 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12012 MSIINSTALLCONTEXT_USERMANAGED,
12013 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12015 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12016 ok(size == 4, "Expected 4, got %d\n", size);
12017
12018 size = MAX_PATH;
12019 lstrcpyA(val, "apple");
12020 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12021 MSIINSTALLCONTEXT_USERMANAGED,
12022 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12023 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12024 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12025 ok(size == 10, "Expected 10, got %d\n", size);
12026
12027 res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
12028 (const BYTE *)"mydate", 7);
12029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12030
12031 /* Installed value exists */
12032 size = MAX_PATH;
12033 lstrcpyA(val, "apple");
12034 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12035 MSIINSTALLCONTEXT_USERMANAGED,
12036 INSTALLPROPERTY_INSTALLDATEA, val, &size);
12037 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12038 ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
12039 ok(size == 6, "Expected 6, got %d\n", size);
12040
12041 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
12042 (const BYTE *)"yes", 4);
12043 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12044
12045 /* Uninstallable value exists */
12046 size = MAX_PATH;
12047 lstrcpyA(val, "apple");
12048 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12049 MSIINSTALLCONTEXT_USERMANAGED,
12050 INSTALLPROPERTY_UNINSTALLABLEA, val, &size);
12051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12052 ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
12053 ok(size == 3, "Expected 3, got %d\n", size);
12054
12055 res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
12056 (const BYTE *)"good", 5);
12057 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12058
12059 /* State value exists */
12060 size = MAX_PATH;
12061 lstrcpyA(val, "apple");
12062 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12063 MSIINSTALLCONTEXT_USERMANAGED,
12064 INSTALLPROPERTY_PATCHSTATEA, val, &size);
12065 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12066 ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
12067 ok(size == 4, "Expected 4, got %d\n", size);
12068
12069 size = 1;
12070 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
12071 (const BYTE *)&size, sizeof(DWORD));
12072 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12073
12074 /* State value exists */
12075 size = MAX_PATH;
12076 lstrcpyA(val, "apple");
12077 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12078 MSIINSTALLCONTEXT_USERMANAGED,
12079 INSTALLPROPERTY_PATCHSTATEA, val, &size);
12080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12081 todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
12082 ok(size == 1, "Expected 1, got %d\n", size);
12083
12084 res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
12085 (const BYTE *)"display", 8);
12086 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12087
12088 /* DisplayName value exists */
12089 size = MAX_PATH;
12090 lstrcpyA(val, "apple");
12091 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12092 MSIINSTALLCONTEXT_USERMANAGED,
12093 INSTALLPROPERTY_DISPLAYNAMEA, val, &size);
12094 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12095 ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
12096 ok(size == 7, "Expected 7, got %d\n", size);
12097
12098 res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
12099 (const BYTE *)"moreinfo", 9);
12100 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12101
12102 /* MoreInfoURL value exists */
12103 size = MAX_PATH;
12104 lstrcpyA(val, "apple");
12105 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12106 MSIINSTALLCONTEXT_USERMANAGED,
12107 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12108 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12109 ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
12110 ok(size == 8, "Expected 8, got %d\n", size);
12111
12112 /* szProperty is invalid */
12113 size = MAX_PATH;
12114 lstrcpyA(val, "apple");
12115 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12116 MSIINSTALLCONTEXT_USERMANAGED,
12117 "IDontExist", val, &size);
12118 ok(r == ERROR_UNKNOWN_PROPERTY,
12119 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
12120 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12121 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12122
12123 /* lpValue is NULL, while pcchValue is non-NULL */
12124 size = MAX_PATH;
12125 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12126 MSIINSTALLCONTEXT_USERMANAGED,
12127 INSTALLPROPERTY_MOREINFOURLA, NULL, &size);
12128 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12129 ok(size == 16, "Expected 16, got %d\n", size);
12130
12131 /* pcchValue is NULL, while lpValue is non-NULL */
12132 lstrcpyA(val, "apple");
12133 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12134 MSIINSTALLCONTEXT_USERMANAGED,
12135 INSTALLPROPERTY_MOREINFOURLA, val, NULL);
12136 ok(r == ERROR_INVALID_PARAMETER,
12137 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12138 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12139
12140 /* both lpValue and pcchValue are NULL */
12141 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12142 MSIINSTALLCONTEXT_USERMANAGED,
12143 INSTALLPROPERTY_MOREINFOURLA, NULL, NULL);
12144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12145
12146 /* pcchValue doesn't have enough room for NULL terminator */
12147 size = 8;
12148 lstrcpyA(val, "apple");
12149 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12150 MSIINSTALLCONTEXT_USERMANAGED,
12151 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12152 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
12153 ok(!lstrcmpA(val, "moreinf"),
12154 "Expected \"moreinf\", got \"%s\"\n", val);
12155 ok(size == 16, "Expected 16, got %d\n", size);
12156
12157 /* pcchValue has exactly enough room for NULL terminator */
12158 size = 9;
12159 lstrcpyA(val, "apple");
12160 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12161 MSIINSTALLCONTEXT_USERMANAGED,
12162 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12164 ok(!lstrcmpA(val, "moreinfo"),
12165 "Expected \"moreinfo\", got \"%s\"\n", val);
12166 ok(size == 8, "Expected 8, got %d\n", size);
12167
12168 /* pcchValue is too small, lpValue is NULL */
12169 size = 0;
12170 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12171 MSIINSTALLCONTEXT_USERMANAGED,
12172 INSTALLPROPERTY_MOREINFOURLA, NULL, &size);
12173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12174 ok(size == 16, "Expected 16, got %d\n", size);
12175
12176 RegDeleteValueA(prodpatches, patch_squashed);
12177 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12178 RegCloseKey(prodpatches);
12179 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12180 RegCloseKey(prodkey);
12181
12182 /* UserData is sufficient for all properties
12183 * except INSTALLPROPERTY_TRANSFORMS
12184 */
12185 size = MAX_PATH;
12186 lstrcpyA(val, "apple");
12187 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12188 MSIINSTALLCONTEXT_USERMANAGED,
12189 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12191 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12192 ok(size == 4, "Expected 4, got %d\n", size);
12193
12194 /* UserData is sufficient for all properties
12195 * except INSTALLPROPERTY_TRANSFORMS
12196 */
12197 size = MAX_PATH;
12198 lstrcpyA(val, "apple");
12199 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12200 MSIINSTALLCONTEXT_USERMANAGED,
12201 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12202 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12203 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12204 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12205
12206 RegDeleteValueA(hpatch, "MoreInfoURL");
12207 RegDeleteValueA(hpatch, "Display");
12208 RegDeleteValueA(hpatch, "State");
12209 RegDeleteValueA(hpatch, "Uninstallable");
12210 RegDeleteValueA(hpatch, "Installed");
12211 RegDeleteValueA(udpatch, "ManagedLocalPackage");
12212 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12213 RegCloseKey(udpatch);
12214 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12215 RegCloseKey(hpatch);
12216 delete_key(patches, "", access & KEY_WOW64_64KEY);
12217 RegCloseKey(patches);
12218 delete_key(props, "", access & KEY_WOW64_64KEY);
12219 RegCloseKey(props);
12220 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12221 RegCloseKey(udprod);
12222
12223 /* MSIINSTALLCONTEXT_USERUNMANAGED */
12224
12225 size = MAX_PATH;
12226 lstrcpyA(val, "apple");
12227 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12228 MSIINSTALLCONTEXT_USERUNMANAGED,
12229 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12230 ok(r == ERROR_UNKNOWN_PRODUCT,
12231 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12232 ok(!lstrcmpA(val, "apple"),
12233 "Expected val to be unchanged, got \"%s\"\n", val);
12234 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12235
12236 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12237 lstrcatA(keypath, usersid);
12238 lstrcatA(keypath, "\\Products\\");
12239 lstrcatA(keypath, prod_squashed);
12240
12241 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12242 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12243
12244 /* local UserData product key exists */
12245 size = MAX_PATH;
12246 lstrcpyA(val, "apple");
12247 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12248 MSIINSTALLCONTEXT_USERUNMANAGED,
12249 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12250 ok(r == ERROR_UNKNOWN_PRODUCT,
12251 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12252 ok(!lstrcmpA(val, "apple"),
12253 "Expected val to be unchanged, got \"%s\"\n", val);
12254 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12255
12256 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12258
12259 /* InstallProperties key exists */
12260 size = MAX_PATH;
12261 lstrcpyA(val, "apple");
12262 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12263 MSIINSTALLCONTEXT_USERUNMANAGED,
12264 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12265 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12266 ok(!lstrcmpA(val, "apple"),
12267 "Expected val to be unchanged, got \"%s\"\n", val);
12268 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12269
12270 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12272
12273 /* Patches key exists */
12274 size = MAX_PATH;
12275 lstrcpyA(val, "apple");
12276 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12277 MSIINSTALLCONTEXT_USERUNMANAGED,
12278 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12279 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12280 ok(!lstrcmpA(val, "apple"),
12281 "Expected val to be unchanged, got \"%s\"\n", val);
12282 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12283
12284 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12285 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12286
12287 /* Patches key exists */
12288 size = MAX_PATH;
12289 lstrcpyA(val, "apple");
12290 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12291 MSIINSTALLCONTEXT_USERUNMANAGED,
12292 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12293 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12294 ok(!lstrcmpA(val, "apple"),
12295 "Expected val to be unchanged, got \"%s\"\n", val);
12296 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12297
12298 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
12299 lstrcatA(keypath, prod_squashed);
12300
12301 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
12302 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12303
12304 /* current user product key exists */
12305 size = MAX_PATH;
12306 lstrcpyA(val, "apple");
12307 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12308 MSIINSTALLCONTEXT_USERUNMANAGED,
12309 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12310 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12311 ok(!lstrcmpA(val, "apple"),
12312 "Expected val to be unchanged, got \"%s\"\n", val);
12313 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12314
12315 res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
12316 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12317
12318 /* Patches key exists */
12319 size = MAX_PATH;
12320 lstrcpyA(val, "apple");
12321 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12322 MSIINSTALLCONTEXT_USERUNMANAGED,
12323 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12324 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12325 ok(!lstrcmpA(val, "apple"),
12326 "Expected val to be unchanged, got \"%s\"\n", val);
12327 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12328
12329 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12330 (const BYTE *)"transforms", 11);
12331 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12332
12333 /* specific patch value exists */
12334 size = MAX_PATH;
12335 lstrcpyA(val, "apple");
12336 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12337 MSIINSTALLCONTEXT_USERUNMANAGED,
12338 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12339 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12340 ok(!lstrcmpA(val, "apple"),
12341 "Expected val to be unchanged, got \"%s\"\n", val);
12342 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12343
12344 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12345 lstrcatA(keypath, usersid);
12346 lstrcatA(keypath, "\\Patches\\");
12347 lstrcatA(keypath, patch_squashed);
12348
12349 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12350 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12351
12352 /* UserData Patches key exists */
12353 size = MAX_PATH;
12354 lstrcpyA(val, "apple");
12355 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12356 MSIINSTALLCONTEXT_USERUNMANAGED,
12357 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12359 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12360 ok(size == 0, "Expected 0, got %d\n", size);
12361
12362 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12363 (const BYTE *)"pack", 5);
12364 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12365
12366 /* LocalPatch value exists */
12367 size = MAX_PATH;
12368 lstrcpyA(val, "apple");
12369 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12370 MSIINSTALLCONTEXT_USERUNMANAGED,
12371 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12372 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12373 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12374 ok(size == 4, "Expected 4, got %d\n", size);
12375
12376 size = MAX_PATH;
12377 lstrcpyA(val, "apple");
12378 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12379 MSIINSTALLCONTEXT_USERUNMANAGED,
12380 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12382 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12383 ok(size == 10, "Expected 10, got %d\n", size);
12384
12385 RegDeleteValueA(prodpatches, patch_squashed);
12386 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12387 RegCloseKey(prodpatches);
12388 RegDeleteKeyA(prodkey, "");
12389 RegCloseKey(prodkey);
12390
12391 /* UserData is sufficient for all properties
12392 * except INSTALLPROPERTY_TRANSFORMS
12393 */
12394 size = MAX_PATH;
12395 lstrcpyA(val, "apple");
12396 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12397 MSIINSTALLCONTEXT_USERUNMANAGED,
12398 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12399 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12400 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12401 ok(size == 4, "Expected 4, got %d\n", size);
12402
12403 /* UserData is sufficient for all properties
12404 * except INSTALLPROPERTY_TRANSFORMS
12405 */
12406 size = MAX_PATH;
12407 lstrcpyA(val, "apple");
12408 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12409 MSIINSTALLCONTEXT_USERUNMANAGED,
12410 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12411 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12412 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12413 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12414
12415 RegDeleteValueA(udpatch, "LocalPackage");
12416 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12417 RegCloseKey(udpatch);
12418 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12419 RegCloseKey(hpatch);
12420 delete_key(patches, "", access & KEY_WOW64_64KEY);
12421 RegCloseKey(patches);
12422 delete_key(props, "", access & KEY_WOW64_64KEY);
12423 RegCloseKey(props);
12424 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12425 RegCloseKey(udprod);
12426
12427 /* MSIINSTALLCONTEXT_MACHINE */
12428
12429 size = MAX_PATH;
12430 lstrcpyA(val, "apple");
12431 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12432 MSIINSTALLCONTEXT_MACHINE,
12433 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12434 ok(r == ERROR_UNKNOWN_PRODUCT,
12435 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12436 ok(!lstrcmpA(val, "apple"),
12437 "Expected val to be unchanged, got \"%s\"\n", val);
12438 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12439
12440 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12441 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
12442 lstrcatA(keypath, prod_squashed);
12443
12444 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12445 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12446
12447 /* local UserData product key exists */
12448 size = MAX_PATH;
12449 lstrcpyA(val, "apple");
12450 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12451 MSIINSTALLCONTEXT_MACHINE,
12452 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12453 ok(r == ERROR_UNKNOWN_PRODUCT,
12454 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12455 ok(!lstrcmpA(val, "apple"),
12456 "Expected val to be unchanged, got \"%s\"\n", val);
12457 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12458
12459 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12460 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12461
12462 /* InstallProperties key exists */
12463 size = MAX_PATH;
12464 lstrcpyA(val, "apple");
12465 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12466 MSIINSTALLCONTEXT_MACHINE,
12467 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12468 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12469 ok(!lstrcmpA(val, "apple"),
12470 "Expected val to be unchanged, got \"%s\"\n", val);
12471 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12472
12473 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12474 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12475
12476 /* Patches key exists */
12477 size = MAX_PATH;
12478 lstrcpyA(val, "apple");
12479 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12480 MSIINSTALLCONTEXT_MACHINE,
12481 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12482 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12483 ok(!lstrcmpA(val, "apple"),
12484 "Expected val to be unchanged, got \"%s\"\n", val);
12485 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12486
12487 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12488 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12489
12490 /* Patches key exists */
12491 size = MAX_PATH;
12492 lstrcpyA(val, "apple");
12493 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12494 MSIINSTALLCONTEXT_MACHINE,
12495 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12496 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12497 ok(!lstrcmpA(val, "apple"),
12498 "Expected val to be unchanged, got \"%s\"\n", val);
12499 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12500
12501 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
12502 lstrcatA(keypath, prod_squashed);
12503
12504 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
12505 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12506
12507 /* local product key exists */
12508 size = MAX_PATH;
12509 lstrcpyA(val, "apple");
12510 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12511 MSIINSTALLCONTEXT_MACHINE,
12512 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12513 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12514 ok(!lstrcmpA(val, "apple"),
12515 "Expected val to be unchanged, got \"%s\"\n", val);
12516 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12517
12518 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
12519 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12520
12521 /* Patches key exists */
12522 size = MAX_PATH;
12523 lstrcpyA(val, "apple");
12524 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12525 MSIINSTALLCONTEXT_MACHINE,
12526 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12527 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12528 ok(!lstrcmpA(val, "apple"),
12529 "Expected val to be unchanged, got \"%s\"\n", val);
12530 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12531
12532 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12533 (const BYTE *)"transforms", 11);
12534 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12535
12536 /* specific patch value exists */
12537 size = MAX_PATH;
12538 lstrcpyA(val, "apple");
12539 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12540 MSIINSTALLCONTEXT_MACHINE,
12541 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12542 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12543 ok(!lstrcmpA(val, "apple"),
12544 "Expected val to be unchanged, got \"%s\"\n", val);
12545 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12546
12547 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12548 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
12549 lstrcatA(keypath, patch_squashed);
12550
12551 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12552 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12553
12554 /* UserData Patches key exists */
12555 size = MAX_PATH;
12556 lstrcpyA(val, "apple");
12557 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12558 MSIINSTALLCONTEXT_MACHINE,
12559 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12560 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12561 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12562 ok(size == 0, "Expected 0, got %d\n", size);
12563
12564 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12565 (const BYTE *)"pack", 5);
12566 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12567
12568 /* LocalPatch value exists */
12569 size = MAX_PATH;
12570 lstrcpyA(val, "apple");
12571 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12572 MSIINSTALLCONTEXT_MACHINE,
12573 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12575 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12576 ok(size == 4, "Expected 4, got %d\n", size);
12577
12578 size = MAX_PATH;
12579 lstrcpyA(val, "apple");
12580 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12581 MSIINSTALLCONTEXT_MACHINE,
12582 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12584 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12585 ok(size == 10, "Expected 10, got %d\n", size);
12586
12587 RegDeleteValueA(prodpatches, patch_squashed);
12588 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12589 RegCloseKey(prodpatches);
12590 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12591 RegCloseKey(prodkey);
12592
12593 /* UserData is sufficient for all properties
12594 * except INSTALLPROPERTY_TRANSFORMS
12595 */
12596 size = MAX_PATH;
12597 lstrcpyA(val, "apple");
12598 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12599 MSIINSTALLCONTEXT_MACHINE,
12600 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12601 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12602 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12603 ok(size == 4, "Expected 4, got %d\n", size);
12604
12605 /* UserData is sufficient for all properties
12606 * except INSTALLPROPERTY_TRANSFORMS
12607 */
12608 size = MAX_PATH;
12609 lstrcpyA(val, "apple");
12610 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12611 MSIINSTALLCONTEXT_MACHINE,
12612 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12613 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12614 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12615 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12616
12617 RegDeleteValueA(udpatch, "LocalPackage");
12618 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12619 RegCloseKey(udpatch);
12620 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12621 RegCloseKey(hpatch);
12622 delete_key(patches, "", access & KEY_WOW64_64KEY);
12623 RegCloseKey(patches);
12624 delete_key(props, "", access & KEY_WOW64_64KEY);
12625 RegCloseKey(props);
12626 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12627 RegCloseKey(udprod);
12628 LocalFree(usersid);
12629 }
12630
12631 static void test_MsiGetPatchInfo(void)
12632 {
12633 UINT r;
12634 char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
12635 char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
12636 WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
12637 HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
12638 HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
12639 DWORD size;
12640 LONG res;
12641 REGSAM access = KEY_ALL_ACCESS;
12642
12643 create_test_guid(patch_code, patch_squashed);
12644 create_test_guid(prod_code, prod_squashed);
12645 MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
12646
12647 if (is_wow64)
12648 access |= KEY_WOW64_64KEY;
12649
12650 r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
12651 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12652
12653 r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
12654 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12655
12656 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
12657 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
12658
12659 size = 0;
12660 r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
12661 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12662
12663 r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
12664 ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
12665
12666 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
12667 lstrcatA(keypath, prod_squashed);
12668
12669 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
12670 if (res == ERROR_ACCESS_DENIED)
12671 {
12672 skip("Not enough rights to perform tests\n");
12673 return;
12674 }
12675 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12676
12677 /* product key exists */
12678 size = MAX_PATH;
12679 lstrcpyA(val, "apple");
12680 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12681 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12682 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
12683 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12684
12685 res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
12686 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12687
12688 /* patches key exists */
12689 size = MAX_PATH;
12690 lstrcpyA(val, "apple");
12691 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12692 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12693 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12694 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12695
12696 res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
12697 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12698
12699 /* patch key exists */
12700 size = MAX_PATH;
12701 lstrcpyA(val, "apple");
12702 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12703 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12704 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12705 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12706
12707 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12708 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
12709 lstrcatA(keypath, prod_squashed);
12710
12711 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
12712 if (res == ERROR_ACCESS_DENIED)
12713 {
12714 skip("Not enough rights to perform tests\n");
12715 goto done;
12716 }
12717 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
12718
12719 /* UserData product key exists */
12720 size = MAX_PATH;
12721 lstrcpyA(val, "apple");
12722 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12723 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12724 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12725 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12726
12727 res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
12728 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12729
12730 /* InstallProperties key exists */
12731 size = MAX_PATH;
12732 lstrcpyA(val, "apple");
12733 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12734 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12735 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
12736 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12737
12738 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
12739 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12740
12741 /* UserData Patches key exists */
12742 size = MAX_PATH;
12743 lstrcpyA(val, "apple");
12744 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12745 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12746 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12747 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12748
12749 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
12750 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12751
12752 res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
12753 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12754
12755 /* UserData product patch key exists */
12756 size = MAX_PATH;
12757 lstrcpyA(val, "apple");
12758 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12759 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12760 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12761 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12762
12763 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12764 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
12765 lstrcatA(keypath, patch_squashed);
12766
12767 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
12768 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12769
12770 res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
12771 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12772
12773 /* UserData Patch key exists */
12774 size = 0;
12775 lstrcpyA(val, "apple");
12776 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12777 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
12778 ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
12779 ok(size == 11, "expected 11 got %u\n", size);
12780
12781 size = MAX_PATH;
12782 lstrcpyA(val, "apple");
12783 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12784 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
12785 ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
12786 ok(size == 11, "expected 11 got %u\n", size);
12787
12788 size = 0;
12789 valW[0] = 0;
12790 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
12791 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
12792 ok(!valW[0], "expected 0 got %u\n", valW[0]);
12793 ok(size == 11, "expected 11 got %u\n", size);
12794
12795 size = MAX_PATH;
12796 valW[0] = 0;
12797 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
12798 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
12799 ok(valW[0], "expected > 0 got %u\n", valW[0]);
12800 ok(size == 11, "expected 11 got %u\n", size);
12801
12802 delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
12803 RegCloseKey(hkey_udproductpatch);
12804 delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
12805 RegCloseKey(hkey_udproductpatches);
12806 delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
12807 RegCloseKey(hkey_udpatch);
12808 delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
12809 RegCloseKey(hkey_udpatches);
12810 delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
12811 RegCloseKey(hkey_udprops);
12812 delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
12813 RegCloseKey(hkey_udproduct);
12814
12815 done:
12816 delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
12817 RegCloseKey(hkey_patches);
12818 delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
12819 RegCloseKey(hkey_product);
12820 delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
12821 RegCloseKey(hkey_patch);
12822 }
12823
12824 static void test_MsiEnumProducts(void)
12825 {
12826 UINT r;
12827 BOOL found1, found2, found3;
12828 DWORD index;
12829 char product1[39], product2[39], product3[39], guid[39];
12830 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
12831 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
12832 char *usersid;
12833 HKEY key1, key2, key3;
12834 REGSAM access = KEY_ALL_ACCESS;
12835
12836 create_test_guid(product1, product_squashed1);
12837 create_test_guid(product2, product_squashed2);
12838 create_test_guid(product3, product_squashed3);
12839 usersid = get_user_sid();
12840
12841 if (is_wow64)
12842 access |= KEY_WOW64_64KEY;
12843
12844 strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
12845 strcat(keypath2, usersid);
12846 strcat(keypath2, "\\Installer\\Products\\");
12847 strcat(keypath2, product_squashed2);
12848
12849 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
12850 if (r == ERROR_ACCESS_DENIED)
12851 {
12852 skip("Not enough rights to perform tests\n");
12853 LocalFree(usersid);
12854 return;
12855 }
12856 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12857
12858 strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
12859 strcat(keypath1, product_squashed1);
12860
12861 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
12862 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12863
12864 strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
12865 strcat(keypath3, product_squashed3);
12866
12867 r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
12868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12869
12870 index = 0;
12871 r = MsiEnumProductsA(index, guid);
12872 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12873
12874 r = MsiEnumProductsA(index, NULL);
12875 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12876
12877 index = 2;
12878 r = MsiEnumProductsA(index, guid);
12879 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12880
12881 index = 0;
12882 r = MsiEnumProductsA(index, guid);
12883 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12884
12885 found1 = found2 = found3 = FALSE;
12886 while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
12887 {
12888 if (!strcmp(product1, guid)) found1 = TRUE;
12889 if (!strcmp(product2, guid)) found2 = TRUE;
12890 if (!strcmp(product3, guid)) found3 = TRUE;
12891 index++;
12892 }
12893 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
12894 ok(found1, "product1 not found\n");
12895 ok(found2, "product2 not found\n");
12896 ok(found3, "product3 not found\n");
12897
12898 delete_key(key1, "", access & KEY_WOW64_64KEY);
12899 delete_key(key2, "", access & KEY_WOW64_64KEY);
12900 RegDeleteKeyA(key3, "");
12901 RegCloseKey(key1);
12902 RegCloseKey(key2);
12903 RegCloseKey(key3);
12904 LocalFree(usersid);
12905 }
12906
12907 static void test_MsiGetFileSignatureInformation(void)
12908 {
12909 HRESULT hr;
12910 const CERT_CONTEXT *cert;
12911 DWORD len;
12912
12913 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
12914 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12915
12916 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
12917 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12918
12919 hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
12920 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12921
12922 hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
12923 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12924
12925 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
12926 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12927
12928 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
12929 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12930
12931 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
12932 todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
12933
12934 create_file( "signature.bin", "signature", sizeof("signature") );
12935
12936 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
12937 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12938
12939 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
12940 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12941
12942 cert = (const CERT_CONTEXT *)0xdeadbeef;
12943 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
12944 todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
12945 ok(cert == NULL, "got %p\n", cert);
12946
12947 DeleteFileA( "signature.bin" );
12948 }
12949
12950 static void test_MsiEnumProductsEx(void)
12951 {
12952 UINT r;
12953 DWORD len, index;
12954 MSIINSTALLCONTEXT context;
12955 char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
12956 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
12957 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
12958 HKEY key1 = NULL, key2 = NULL, key3 = NULL;
12959 REGSAM access = KEY_ALL_ACCESS;
12960 char *usersid = get_user_sid();
12961
12962 if (!pMsiEnumProductsExA)
12963 {
12964 win_skip("MsiEnumProductsExA not implemented\n");
12965 return;
12966 }
12967
12968 create_test_guid( product0, NULL );
12969 create_test_guid( product1, product_squashed1 );
12970 create_test_guid( product2, product_squashed2 );
12971 create_test_guid( product3, product_squashed3 );
12972
12973 if (is_wow64) access |= KEY_WOW64_64KEY;
12974
12975 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
12976 strcat( keypath2, usersid );
12977 strcat( keypath2, "\\Installer\\Products\\" );
12978 strcat( keypath2, product_squashed2 );
12979
12980 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12981 if (r == ERROR_ACCESS_DENIED)
12982 {
12983 skip( "insufficient rights\n" );
12984 goto done;
12985 }
12986 ok( r == ERROR_SUCCESS, "got %u\n", r );
12987
12988 strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
12989 strcat( keypath1, product_squashed1 );
12990
12991 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12992 ok( r == ERROR_SUCCESS, "got %u\n", r );
12993
12994 strcpy( keypath3, usersid );
12995 strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
12996 strcat( keypath3, product_squashed3 );
12997
12998 r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
12999 ok( r == ERROR_SUCCESS, "got %u\n", r );
13000
13001 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
13002 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13003
13004 len = sizeof(sid);
13005 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
13006 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13007 ok( len == sizeof(sid), "got %u\n", len );
13008
13009 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
13010 ok( r == ERROR_SUCCESS, "got %u\n", r );
13011
13012 sid[0] = 0;
13013 len = sizeof(sid);
13014 r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
13015 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
13016 ok( len == sizeof(sid), "got %u\n", len );
13017 ok( !sid[0], "got %s\n", sid );
13018
13019 sid[0] = 0;
13020 len = sizeof(sid);
13021 r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
13022 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
13023 ok( len == sizeof(sid), "got %u\n", len );
13024 ok( !sid[0], "got %s\n", sid );
13025
13026 sid[0] = 0;
13027 len = 0;
13028 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
13029 ok( r == ERROR_MORE_DATA, "got %u\n", r );
13030 ok( len, "length unchanged\n" );
13031 ok( !sid[0], "got %s\n", sid );
13032
13033 guid[0] = 0;
13034 context = 0xdeadbeef;
13035 sid[0] = 0;
13036 len = sizeof(sid);
13037 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13038 ok( r == ERROR_SUCCESS, "got %u\n", r );
13039 ok( guid[0], "empty guid\n" );
13040 ok( context != 0xdeadbeef, "context unchanged\n" );
13041 ok( !len, "got %u\n", len );
13042 ok( !sid[0], "got %s\n", sid );
13043
13044 guid[0] = 0;
13045 context = 0xdeadbeef;
13046 sid[0] = 0;
13047 len = sizeof(sid);
13048 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13049 ok( r == ERROR_SUCCESS, "got %u\n", r );
13050 ok( guid[0], "empty guid\n" );
13051 ok( context != 0xdeadbeef, "context unchanged\n" );
13052 ok( !len, "got %u\n", len );
13053 ok( !sid[0], "got %s\n", sid );
13054
13055 guid[0] = 0;
13056 context = 0xdeadbeef;
13057 sid[0] = 0;
13058 len = sizeof(sid);
13059 r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13060 if (r == ERROR_ACCESS_DENIED)
13061 {
13062 skip( "insufficient rights\n" );
13063 goto done;
13064 }
13065 ok( r == ERROR_SUCCESS, "got %u\n", r );
13066 ok( guid[0], "empty guid\n" );
13067 ok( context != 0xdeadbeef, "context unchanged\n" );
13068 ok( !len, "got %u\n", len );
13069 ok( !sid[0], "got %s\n", sid );
13070
13071 index = 0;
13072 guid[0] = 0;
13073 context = 0xdeadbeef;
13074 sid[0] = 0;
13075 len = sizeof(sid);
13076 while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13077 {
13078 if (!strcmp( product1, guid ))
13079 {
13080 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13081 ok( !sid[0], "got \"%s\"\n", sid );
13082 ok( !len, "unexpected length %u\n", len );
13083 }
13084 if (!strcmp( product2, guid ))
13085 {
13086 ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
13087 ok( sid[0], "empty sid\n" );
13088 ok( len == strlen(sid), "unexpected length %u\n", len );
13089 }
13090 if (!strcmp( product3, guid ))
13091 {
13092 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13093 ok( sid[0], "empty sid\n" );
13094 ok( len == strlen(sid), "unexpected length %u\n", len );
13095 }
13096 index++;
13097 guid[0] = 0;
13098 context = 0xdeadbeef;
13099 sid[0] = 0;
13100 len = sizeof(sid);
13101 }
13102
13103 done:
13104 delete_key( key1, "", access );
13105 delete_key( key2, "", access );
13106 delete_key( key3, "", access );
13107 RegCloseKey( key1 );
13108 RegCloseKey( key2 );
13109 RegCloseKey( key3 );
13110 LocalFree( usersid );
13111 }
13112
13113 static void test_MsiEnumComponents(void)
13114 {
13115 UINT r;
13116 BOOL found1, found2;
13117 DWORD index;
13118 char comp1[39], comp2[39], guid[39];
13119 char comp_squashed1[33], comp_squashed2[33];
13120 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13121 REGSAM access = KEY_ALL_ACCESS;
13122 char *usersid = get_user_sid();
13123 HKEY key1 = NULL, key2 = NULL;
13124
13125 create_test_guid( comp1, comp_squashed1 );
13126 create_test_guid( comp2, comp_squashed2 );
13127
13128 if (is_wow64) access |= KEY_WOW64_64KEY;
13129
13130 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13131 strcat( keypath1, "S-1-5-18\\Components\\" );
13132 strcat( keypath1, comp_squashed1 );
13133
13134 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13135 if (r == ERROR_ACCESS_DENIED)
13136 {
13137 skip( "insufficient rights\n" );
13138 goto done;
13139 }
13140 ok( r == ERROR_SUCCESS, "got %u\n", r );
13141
13142 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13143 strcat( keypath2, usersid );
13144 strcat( keypath2, "\\Components\\" );
13145 strcat( keypath2, comp_squashed2 );
13146
13147 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13148 if (r == ERROR_ACCESS_DENIED)
13149 {
13150 skip( "insufficient rights\n" );
13151 goto done;
13152 }
13153
13154 r = MsiEnumComponentsA( 0, NULL );
13155 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13156
13157 index = 0;
13158 guid[0] = 0;
13159 found1 = found2 = FALSE;
13160 while (!MsiEnumComponentsA( index, guid ))
13161 {
13162 if (!strcmp( guid, comp1 )) found1 = TRUE;
13163 if (!strcmp( guid, comp2 )) found2 = TRUE;
13164 ok( guid[0], "empty guid\n" );
13165 guid[0] = 0;
13166 index++;
13167 }
13168 ok( found1, "comp1 not found\n" );
13169 ok( found2, "comp2 not found\n" );
13170
13171 done:
13172 delete_key( key1, "", access );
13173 delete_key( key2, "", access );
13174 RegCloseKey( key1 );
13175 RegCloseKey( key2 );
13176 LocalFree( usersid );
13177 }
13178
13179 static void test_MsiEnumComponentsEx(void)
13180 {
13181 UINT r;
13182 BOOL found1, found2;
13183 DWORD len, index;
13184 MSIINSTALLCONTEXT context;
13185 char comp1[39], comp2[39], guid[39], sid[128];
13186 char comp_squashed1[33], comp_squashed2[33];
13187 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13188 HKEY key1 = NULL, key2 = NULL;
13189 REGSAM access = KEY_ALL_ACCESS;
13190 char *usersid = get_user_sid();
13191
13192 if (!pMsiEnumComponentsExA)
13193 {
13194 win_skip( "MsiEnumComponentsExA not implemented\n" );
13195 return;
13196 }
13197 create_test_guid( comp1, comp_squashed1 );
13198 create_test_guid( comp2, comp_squashed2 );
13199
13200 if (is_wow64) access |= KEY_WOW64_64KEY;
13201
13202 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13203 strcat( keypath1, "S-1-5-18\\Components\\" );
13204 strcat( keypath1, comp_squashed1 );
13205
13206 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13207 if (r == ERROR_ACCESS_DENIED)
13208 {
13209 skip( "insufficient rights\n" );
13210 goto done;
13211 }
13212 ok( r == ERROR_SUCCESS, "got %u\n", r );
13213
13214 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13215 strcat( keypath2, usersid );
13216 strcat( keypath2, "\\Components\\" );
13217 strcat( keypath2, comp_squashed2 );
13218
13219 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13220 if (r == ERROR_ACCESS_DENIED)
13221 {
13222 skip( "insufficient rights\n" );
13223 goto done;
13224 }
13225 ok( r == ERROR_SUCCESS, "got %u\n", r );
13226 r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
13227 sizeof("c:\\doesnotexist"));
13228 ok( r == ERROR_SUCCESS, "got %u\n", r );
13229
13230 index = 0;
13231 guid[0] = 0;
13232 context = 0xdeadbeef;
13233 sid[0] = 0;
13234 len = sizeof(sid);
13235 found1 = found2 = FALSE;
13236 while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13237 {
13238 if (!strcmp( comp1, guid ))
13239 {
13240 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13241 ok( !sid[0], "got \"%s\"\n", sid );
13242 ok( !len, "unexpected length %u\n", len );
13243 found1 = TRUE;
13244 }
13245 if (!strcmp( comp2, guid ))
13246 {
13247 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13248 ok( sid[0], "empty sid\n" );
13249 ok( len == strlen(sid), "unexpected length %u\n", len );
13250 found2 = TRUE;
13251 }
13252 index++;
13253 guid[0] = 0;
13254 context = 0xdeadbeef;
13255 sid[0] = 0;
13256 len = sizeof(sid);
13257 }
13258 ok( found1, "comp1 not found\n" );
13259 ok( found2, "comp2 not found\n" );
13260
13261 r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
13262 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13263
13264 r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
13265 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13266
13267 done:
13268 RegDeleteValueA( key2, comp_squashed2 );
13269 delete_key( key1, "", access );
13270 delete_key( key2, "", access );
13271 RegCloseKey( key1 );
13272 RegCloseKey( key2 );
13273 LocalFree( usersid );
13274 }
13275
13276 static void test_MsiConfigureProductEx(void)
13277 {
13278 UINT r;
13279 LONG res;
13280 DWORD type, size;
13281 HKEY props, source;
13282 CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
13283 REGSAM access = KEY_ALL_ACCESS;
13284
13285 if (is_process_limited())
13286 {
13287 skip("process is limited\n");
13288 return;
13289 }
13290
13291 CreateDirectoryA("msitest", NULL);
13292 create_file("msitest\\hydrogen", "hydrogen", 500);
13293 create_file("msitest\\helium", "helium", 500);
13294 create_file("msitest\\lithium", "lithium", 500);
13295
13296 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13297
13298 if (is_wow64)
13299 access |= KEY_WOW64_64KEY;
13300
13301 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13302
13303 /* NULL szProduct */
13304 r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
13305 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13306 ok(r == ERROR_INVALID_PARAMETER,
13307 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13308
13309 /* empty szProduct */
13310 r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
13311 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13312 ok(r == ERROR_INVALID_PARAMETER,
13313 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13314
13315 /* garbage szProduct */
13316 r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
13317 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13318 ok(r == ERROR_INVALID_PARAMETER,
13319 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13320
13321 /* guid without brackets */
13322 r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
13323 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13324 "PROPVAR=42");
13325 ok(r == ERROR_INVALID_PARAMETER,
13326 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13327
13328 /* guid with brackets */
13329 r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
13330 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13331 "PROPVAR=42");
13332 ok(r == ERROR_UNKNOWN_PRODUCT,
13333 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13334
13335 /* same length as guid, but random */
13336 r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
13337 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13338 "PROPVAR=42");
13339 ok(r == ERROR_UNKNOWN_PRODUCT,
13340 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13341
13342 /* product not installed yet */
13343 r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
13344 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13345 "PROPVAR=42");
13346 ok(r == ERROR_UNKNOWN_PRODUCT,
13347 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13348
13349 /* install the product, per-user unmanaged */
13350 r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
13351 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13352 {
13353 skip("Not enough rights to perform tests\n");
13354 goto error;
13355 }
13356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13357 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13358 ok(pf_exists("msitest\\helium"), "File not installed\n");
13359 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13360 ok(pf_exists("msitest"), "File not installed\n");
13361
13362 /* product is installed per-user managed, remove it */
13363 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13364 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13365 "PROPVAR=42");
13366 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13367 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13368 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13369 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13370 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13371
13372 /* product has been removed */
13373 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13374 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13375 "PROPVAR=42");
13376 ok(r == ERROR_UNKNOWN_PRODUCT,
13377 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13378
13379 /* install the product, machine */
13380 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13382 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13383 ok(pf_exists("msitest\\helium"), "File not installed\n");
13384 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13385 ok(pf_exists("msitest"), "File not installed\n");
13386
13387 /* product is installed machine, remove it */
13388 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13389 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13390 "PROPVAR=42");
13391 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13392 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13393 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13394 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13395 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13396
13397 /* product has been removed */
13398 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13399 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13400 "PROPVAR=42");
13401 ok(r == ERROR_UNKNOWN_PRODUCT,
13402 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13403
13404 /* install the product, machine */
13405 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13407 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13408 ok(pf_exists("msitest\\helium"), "File not installed\n");
13409 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13410 ok(pf_exists("msitest"), "File not installed\n");
13411
13412 DeleteFileA(msifile);
13413
13414 /* msifile is removed */
13415 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13416 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13417 "PROPVAR=42");
13418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13419 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13420 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13421 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13422 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13423
13424 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13425
13426 /* install the product, machine */
13427 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13429 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13430 ok(pf_exists("msitest\\helium"), "File not installed\n");
13431 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13432 ok(pf_exists("msitest"), "File not installed\n");
13433
13434 DeleteFileA(msifile);
13435
13436 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13437 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13438 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13439
13440 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
13441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13442
13443 type = REG_SZ;
13444 size = MAX_PATH;
13445 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13446 (LPBYTE)localpackage, &size);
13447 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13448
13449 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13450 (const BYTE *)"C:\\idontexist.msi", 18);
13451 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13452
13453 /* LocalPackage is used to find the cached msi package */
13454 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13455 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13456 "PROPVAR=42");
13457 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
13458 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13459 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13460 ok(pf_exists("msitest\\helium"), "File not installed\n");
13461 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13462 ok(pf_exists("msitest"), "File not installed\n");
13463
13464 RegCloseKey(props);
13465 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13466
13467 /* LastUsedSource can be used as a last resort */
13468 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13469 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13470 "PROPVAR=42");
13471 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13472 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13473 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13474 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13475 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13476 DeleteFileA( localpackage );
13477
13478 /* install the product, machine */
13479 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13481 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13482 ok(pf_exists("msitest\\helium"), "File not installed\n");
13483 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13484 ok(pf_exists("msitest"), "File not installed\n");
13485
13486 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13487 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13488 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13489
13490 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
13491 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13492
13493 type = REG_SZ;
13494 size = MAX_PATH;
13495 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13496 (LPBYTE)localpackage, &size);
13497 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13498
13499 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13500 (const BYTE *)"C:\\idontexist.msi", 18);
13501 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13502
13503 lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
13504 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\SourceList");
13505
13506 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source);
13507 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13508
13509 type = REG_SZ;
13510 size = MAX_PATH;
13511 res = RegQueryValueExA(source, "PackageName", NULL, &type,
13512 (LPBYTE)packagename, &size);
13513 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13514
13515 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13516 (const BYTE *)"idontexist.msi", 15);
13517 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13518
13519 /* SourceList is altered */
13520 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13521 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13522 "PROPVAR=42");
13523 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
13524 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13525 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13526 ok(pf_exists("msitest\\helium"), "File not installed\n");
13527 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13528 ok(pf_exists("msitest"), "File not installed\n");
13529
13530 /* restore PackageName */
13531 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13532 (const BYTE *)packagename, lstrlenA(packagename) + 1);
13533 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13534
13535 /* restore LocalPackage */
13536 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13537 (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
13538 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13539
13540 /* finally remove the product */
13541 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13542 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13543 "PROPVAR=42");
13544 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13545 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13546 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13547 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13548 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13549
13550 RegCloseKey(source);
13551 RegCloseKey(props);
13552
13553 error:
13554 DeleteFileA("msitest\\hydrogen");
13555 DeleteFileA("msitest\\helium");
13556 DeleteFileA("msitest\\lithium");
13557 RemoveDirectoryA("msitest");
13558 DeleteFileA(msifile);
13559 }
13560
13561 static void test_MsiSetFeatureAttributes(void)
13562 {
13563 UINT r;
13564 DWORD attrs;
13565 char path[MAX_PATH];
13566 MSIHANDLE package;
13567
13568 if (is_process_limited())
13569 {
13570 skip("process is limited\n");
13571 return;
13572 }
13573 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
13574
13575 strcpy( path, CURR_DIR );
13576 strcat( path, "\\" );
13577 strcat( path, msifile );
13578
13579 r = MsiOpenPackageA( path, &package );
13580 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13581 {
13582 skip("Not enough rights to perform tests\n");
13583 DeleteFileA( msifile );
13584 return;
13585 }
13586 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13587
13588 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13589 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r);
13590
13591 r = MsiDoActionA( package, "CostInitialize" );
13592 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13593
13594 r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13595 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
13596
13597 r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13598 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13599
13600 r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13601 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13602
13603 r = MsiSetFeatureAttributesA( package, "One", 0 );
13604 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13605
13606 attrs = 0xdeadbeef;
13607 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13608 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13609 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
13610 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
13611
13612 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13613 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13614
13615 attrs = 0;
13616 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13617 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13618 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
13619 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
13620
13621 r = MsiDoActionA( package, "FileCost" );
13622 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13623
13624 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE );
13625 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13626
13627 attrs = 0;
13628 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13629 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13630 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE,
13631 "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs);
13632
13633 r = MsiDoActionA( package, "CostFinalize" );
13634 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13635
13636 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13637 ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r);
13638
13639 MsiCloseHandle( package );
13640 DeleteFileA( msifile );
13641 }
13642
13643 static void test_MsiGetFeatureInfo(void)
13644 {
13645 UINT r;
13646 MSIHANDLE package;
13647 char title[32], help[32], path[MAX_PATH];
13648 DWORD attrs, title_len, help_len;
13649
13650 if (is_process_limited())
13651 {
13652 skip("process is limited\n");
13653 return;
13654 }
13655 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
13656
13657 strcpy( path, CURR_DIR );
13658 strcat( path, "\\" );
13659 strcat( path, msifile );
13660
13661 r = MsiOpenPackageA( path, &package );
13662 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13663 {
13664 skip("Not enough rights to perform tests\n");
13665 DeleteFileA( msifile );
13666 return;
13667 }
13668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13669
13670 r = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL );
13671 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13672
13673 r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
13674 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13675
13676 r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
13677 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13678
13679 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
13680 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13681
13682 r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
13683 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
13684
13685 title_len = help_len = 0;
13686 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
13687 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13688 ok(title_len == 3, "expected 3, got %u\n", title_len);
13689 ok(help_len == 3, "expected 3, got %u\n", help_len);
13690
13691 title[0] = help[0] = 0;
13692 title_len = help_len = 0;
13693 r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
13694 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
13695 ok(title_len == 3, "expected 3, got %u\n", title_len);
13696 ok(help_len == 3, "expected 3, got %u\n", help_len);
13697
13698 attrs = 0;
13699 title[0] = help[0] = 0;
13700 title_len = sizeof(title);
13701 help_len = sizeof(help);
13702 r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
13703 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13704 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
13705 ok(title_len == 3, "expected 3, got %u\n", title_len);
13706 ok(help_len == 3, "expected 3, got %u\n", help_len);
13707 ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
13708 ok(!strcmp(help, "One"), "expected \"One\", got \"%s\"\n", help);
13709
13710 attrs = 0;
13711 title[0] = help[0] = 0;
13712 title_len = sizeof(title);
13713 help_len = sizeof(help);
13714 r = MsiGetFeatureInfoA( package, "Two", &attrs, title, &title_len, help, &help_len );
13715 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13716 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
13717 ok(!title_len, "expected 0, got %u\n", title_len);
13718 ok(!help_len, "expected 0, got %u\n", help_len);
13719 ok(!title[0], "expected \"\", got \"%s\"\n", title);
13720 ok(!help[0], "expected \"\", got \"%s\"\n", help);
13721
13722 MsiCloseHandle( package );
13723 DeleteFileA( msifile );
13724 }
13725
13726 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
13727 {
13728 return IDOK;
13729 }
13730
13731 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
13732 {
13733 return IDOK;
13734 }
13735
13736 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
13737 {
13738 return IDOK;
13739 }
13740
13741 static void test_MsiSetExternalUI(void)
13742 {
13743 INSTALLUI_HANDLERA ret_a;
13744 INSTALLUI_HANDLERW ret_w;
13745 INSTALLUI_HANDLER_RECORD prev;
13746 UINT error;
13747
13748 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
13749 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13750
13751 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
13752 ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
13753
13754 /* Not present before Installer 3.1 */
13755 if (!pMsiSetExternalUIRecord) {
13756 win_skip("MsiSetExternalUIRecord is not available\n");
13757 return;
13758 }
13759
13760 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
13761 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13762 ok(prev == NULL, "expected NULL, got %p\n", prev);
13763
13764 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13765 error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
13766 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13767 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
13768
13769 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
13770 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13771
13772 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
13773 ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
13774
13775 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
13776 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13777
13778 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
13779 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13780
13781 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13782 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
13783 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13784 ok(prev == NULL, "expected NULL, got %p\n", prev);
13785
13786 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
13787 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13788
13789 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
13790 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13791
13792 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13793 error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
13794 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13795 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
13796
13797 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
13798 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13799
13800 error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
13801 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13802 }
13803
13804 static void test_lastusedsource(void)
13805 {
13806 static const char prodcode[] = "{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}";
13807 char value[MAX_PATH], path[MAX_PATH];
13808 DWORD size;
13809 UINT r;
13810
13811 if (!pMsiSourceListGetInfoA)
13812 {
13813 win_skip("MsiSourceListGetInfoA is not available\n");
13814 return;
13815 }
13816
13817 CreateDirectoryA("msitest", NULL);
13818 create_file("maximus", "maximus", 500);
13819 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
13820 DeleteFileA("maximus");
13821
13822 create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
13823 create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
13824 create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
13825
13826 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13827
13828 /* no cabinet file */
13829
13830 size = MAX_PATH;
13831 lstrcpyA(value, "aaa");
13832 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13833 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13834 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13835 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13836
13837 r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
13838 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13839 {
13840 skip("Not enough rights to perform tests\n");
13841 goto error;
13842 }
13843 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13844
13845 lstrcpyA(path, CURR_DIR);
13846 lstrcatA(path, "\\");
13847
13848 size = MAX_PATH;
13849 lstrcpyA(value, "aaa");
13850 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13851 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13852 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13853 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13854 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
13855
13856 r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
13857 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13858
13859 /* separate cabinet file */
13860
13861 size = MAX_PATH;
13862 lstrcpyA(value, "aaa");
13863 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13864 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13865 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13866 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13867
13868 r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
13869 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13870
13871 lstrcpyA(path, CURR_DIR);
13872 lstrcatA(path, "\\");
13873
13874 size = MAX_PATH;
13875 lstrcpyA(value, "aaa");
13876 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13877 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13878 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13879 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13880 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
13881
13882 r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
13883 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13884
13885 size = MAX_PATH;
13886 lstrcpyA(value, "aaa");
13887 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13888 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13889 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13890 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13891
13892 /* embedded cabinet stream */
13893
13894 add_cabinet_storage("msifile2.msi", "test1.cab");
13895
13896 r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
13897 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13898
13899 size = MAX_PATH;
13900 lstrcpyA(value, "aaa");
13901 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13902 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13903 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13904 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13905 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
13906
13907 r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
13908 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13909
13910 size = MAX_PATH;
13911 lstrcpyA(value, "aaa");
13912 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13913 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13914 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13915 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13916
13917 error:
13918 delete_cab_files();
13919 DeleteFileA("msitest\\maximus");
13920 RemoveDirectoryA("msitest");
13921 DeleteFileA("msifile0.msi");
13922 DeleteFileA("msifile1.msi");
13923 DeleteFileA("msifile2.msi");
13924 }
13925
13926 static void test_setpropertyfolder(void)
13927 {
13928 UINT r;
13929 CHAR path[MAX_PATH];
13930 DWORD attr;
13931
13932 if (is_process_limited())
13933 {
13934 skip("process is limited\n");
13935 return;
13936 }
13937
13938 lstrcpyA(path, PROG_FILES_DIR);
13939 lstrcatA(path, "\\msitest\\added");
13940
13941 CreateDirectoryA("msitest", NULL);
13942 create_file("msitest\\maximus", "msitest\\maximus", 500);
13943
13944 create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
13945
13946 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
13947
13948 r = MsiInstallProductA(msifile, NULL);
13949 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13950 {
13951 skip("Not enough rights to perform tests\n");
13952 goto error;
13953 }
13954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13955 attr = GetFileAttributesA(path);
13956 if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
13957 {
13958 ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
13959 ok(delete_pf("msitest\\added", FALSE), "Directory not created\n");
13960 ok(delete_pf("msitest", FALSE), "Directory not created\n");
13961 }
13962 else
13963 {
13964 trace("changing folder property not supported\n");
13965 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
13966 ok(delete_pf("msitest", FALSE), "Directory not created\n");
13967 }
13968
13969 error:
13970 DeleteFileA(msifile);
13971 DeleteFileA("msitest\\maximus");
13972 RemoveDirectoryA("msitest");
13973 }
13974
13975 static void test_sourcedir_props(void)
13976 {
13977 UINT r;
13978
13979 if (is_process_limited())
13980 {
13981 skip("process is limited\n");
13982 return;
13983 }
13984
13985 create_test_files();
13986 create_file("msitest\\sourcedir.txt", "msitest\\sourcedir.txt", 1000);
13987 create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
13988
13989 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
13990
13991 /* full UI, no ResolveSource action */
13992 r = MsiInstallProductA(msifile, NULL);
13993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13994
13995 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13996 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13997
13998 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13999 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14000
14001 /* full UI, ResolveSource action */
14002 r = MsiInstallProductA(msifile, "ResolveSource=1");
14003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14004
14005 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14006 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14007
14008 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14009 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14010
14011 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14012
14013 /* no UI, no ResolveSource action */
14014 r = MsiInstallProductA(msifile, NULL);
14015 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14016
14017 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14019
14020 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14021 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14022
14023 /* no UI, ResolveSource action */
14024 r = MsiInstallProductA(msifile, "ResolveSource=1");
14025 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14026
14027 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14028 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14029
14030 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14031 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14032
14033 DeleteFileA("msitest\\sourcedir.txt");
14034 delete_test_files();
14035 DeleteFileA(msifile);
14036 }
14037
14038 static void test_concurrentinstall(void)
14039 {
14040 UINT r;
14041 CHAR path[MAX_PATH];
14042
14043 if (is_process_limited())
14044 {
14045 skip("process is limited\n");
14046 return;
14047 }
14048
14049 CreateDirectoryA("msitest", NULL);
14050 CreateDirectoryA("msitest\\msitest", NULL);
14051 create_file("msitest\\maximus", "msitest\\maximus", 500);
14052 create_file("msitest\\msitest\\augustus", "msitest\\msitest\\augustus", 500);
14053
14054 create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
14055
14056 lstrcpyA(path, CURR_DIR);
14057 lstrcatA(path, "\\msitest\\concurrent.msi");
14058 create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
14059
14060 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14061
14062 r = MsiInstallProductA(msifile, NULL);
14063 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14064 {
14065 skip("Not enough rights to perform tests\n");
14066 DeleteFileA(path);
14067 goto error;
14068 }
14069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14070 if (!delete_pf("msitest\\augustus", TRUE))
14071 trace("concurrent installs not supported\n");
14072 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14073 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14074
14075 r = MsiConfigureProductA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", INSTALLLEVEL_DEFAULT,
14076 INSTALLSTATE_ABSENT);
14077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14078
14079 DeleteFileA(path);
14080
14081 error:
14082 DeleteFileA(msifile);
14083 DeleteFileA("msitest\\msitest\\augustus");
14084 DeleteFileA("msitest\\maximus");
14085 RemoveDirectoryA("msitest\\msitest");
14086 RemoveDirectoryA("msitest");
14087 }
14088
14089 static void test_command_line_parsing(void)
14090 {
14091 UINT r;
14092 const char *cmd;
14093
14094 if (is_process_limited())
14095 {
14096 skip("process is limited\n");
14097 return;
14098 }
14099
14100 create_test_files();
14101 create_database(msifile, cl_tables, sizeof(cl_tables)/sizeof(msi_table));
14102
14103 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14104
14105 cmd = " ";
14106 r = MsiInstallProductA(msifile, cmd);
14107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14108
14109 cmd = "=";
14110 r = MsiInstallProductA(msifile, cmd);
14111 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14112
14113 cmd = "==";
14114 r = MsiInstallProductA(msifile, cmd);
14115 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14116
14117 cmd = "one";
14118 r = MsiInstallProductA(msifile, cmd);
14119 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14120
14121 cmd = "=one";
14122 r = MsiInstallProductA(msifile, cmd);
14123 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14124
14125 cmd = "P=";
14126 r = MsiInstallProductA(msifile, cmd);
14127 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14128
14129 cmd = " P=";
14130 r = MsiInstallProductA(msifile, cmd);
14131 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14132
14133 cmd = "P= ";
14134 r = MsiInstallProductA(msifile, cmd);
14135 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14136
14137 cmd = "P=\"";
14138 r = MsiInstallProductA(msifile, cmd);
14139 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14140
14141 cmd = "P=\"\"";
14142 r = MsiInstallProductA(msifile, cmd);
14143 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14144
14145 cmd = "P=\"\"\"";
14146 r = MsiInstallProductA(msifile, cmd);
14147 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14148
14149 cmd = "P=\"\"\"\"";
14150 r = MsiInstallProductA(msifile, cmd);
14151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14152
14153 cmd = "P=\" ";
14154 r = MsiInstallProductA(msifile, cmd);
14155 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14156
14157 cmd = "P= \"";
14158 r = MsiInstallProductA(msifile, cmd);
14159 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14160
14161 cmd = "P= \"\" ";
14162 r = MsiInstallProductA(msifile, cmd);
14163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14164
14165 cmd = "P=\" \"";
14166 r = MsiInstallProductA(msifile, cmd);
14167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14168
14169 cmd = "P=one";
14170 r = MsiInstallProductA(msifile, cmd);
14171 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14172
14173 cmd = "P= one";
14174 r = MsiInstallProductA(msifile, cmd);
14175 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14176
14177 cmd = "P=\"one";
14178 r = MsiInstallProductA(msifile, cmd);
14179 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14180
14181 cmd = "P=one\"";
14182 r = MsiInstallProductA(msifile, cmd);
14183 todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14184
14185 cmd = "P=\"one\"";
14186 r = MsiInstallProductA(msifile, cmd);
14187 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14188
14189 cmd = "P= \"one\" ";
14190 r = MsiInstallProductA(msifile, cmd);
14191 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14192
14193 cmd = "P=\"one\"\"";
14194 r = MsiInstallProductA(msifile, cmd);
14195 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14196
14197 cmd = "P=\"\"one\"";
14198 r = MsiInstallProductA(msifile, cmd);
14199 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14200
14201 cmd = "P=\"\"one\"\"";
14202 r = MsiInstallProductA(msifile, cmd);
14203 todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14204
14205 cmd = "P=\"one two\"";
14206 r = MsiInstallProductA(msifile, cmd);
14207 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14208
14209 cmd = "P=\"\"\"one\"\" two\"";
14210 r = MsiInstallProductA(msifile, cmd);
14211 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14212
14213 cmd = "P=\"\"\"one\"\" two\" Q=three";
14214 r = MsiInstallProductA(msifile, cmd);
14215 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14216
14217 cmd = "P=\"\" Q=\"two\"";
14218 r = MsiInstallProductA(msifile, cmd);
14219 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14220
14221 cmd = "P=\"one\" Q=\"two\"";
14222 r = MsiInstallProductA(msifile, cmd);
14223 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14224
14225 cmd = "P=\"one=two\"";
14226 r = MsiInstallProductA(msifile, cmd);
14227 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14228
14229 cmd = "Q=\"\" P=\"one\"";
14230 r = MsiInstallProductA(msifile, cmd);
14231 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14232
14233 cmd = "P=\"\"\"one\"\"\" Q=\"two\"";
14234 r = MsiInstallProductA(msifile, cmd);
14235 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14236
14237 cmd = "P=\"one \"\"two\"\"\" Q=\"three\"";
14238 r = MsiInstallProductA(msifile, cmd);
14239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14240
14241 cmd = "P=\"\"\"one\"\" two\" Q=\"three\"";
14242 r = MsiInstallProductA(msifile, cmd);
14243 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14244
14245 DeleteFileA(msifile);
14246 delete_test_files();
14247 }
14248
14249 START_TEST(msi)
14250 {
14251 DWORD len;
14252 char temp_path[MAX_PATH], prev_path[MAX_PATH];
14253
14254 init_functionpointers();
14255
14256 if (pIsWow64Process)
14257 pIsWow64Process(GetCurrentProcess(), &is_wow64);
14258
14259 GetCurrentDirectoryA(MAX_PATH, prev_path);
14260 GetTempPathA(MAX_PATH, temp_path);
14261 SetCurrentDirectoryA(temp_path);
14262
14263 lstrcpyA(CURR_DIR, temp_path);
14264 len = lstrlenA(CURR_DIR);
14265
14266 if(len && (CURR_DIR[len - 1] == '\\'))
14267 CURR_DIR[len - 1] = 0;
14268
14269 ok(get_system_dirs(), "failed to retrieve system dirs\n");
14270
14271 test_usefeature();
14272 test_null();
14273 test_getcomponentpath();
14274 test_MsiGetFileHash();
14275
14276 if (!pConvertSidToStringSidA)
14277 win_skip("ConvertSidToStringSidA not implemented\n");
14278 else
14279 {
14280 /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
14281 test_MsiQueryProductState();
14282 test_MsiQueryFeatureState();
14283 test_MsiQueryComponentState();
14284 test_MsiGetComponentPath();
14285 test_MsiGetProductCode();
14286 test_MsiEnumClients();
14287 test_MsiGetProductInfo();
14288 test_MsiGetProductInfoEx();
14289 test_MsiGetUserInfo();
14290 test_MsiOpenProduct();
14291 test_MsiEnumPatchesEx();
14292 test_MsiEnumPatches();
14293 test_MsiGetPatchInfoEx();
14294 test_MsiGetPatchInfo();
14295 test_MsiEnumProducts();
14296 test_MsiEnumProductsEx();
14297 test_MsiEnumComponents();
14298 test_MsiEnumComponentsEx();
14299 }
14300 test_MsiGetFileVersion();
14301 test_MsiGetFileSignatureInformation();
14302 test_MsiConfigureProductEx();
14303 test_MsiSetFeatureAttributes();
14304 test_MsiGetFeatureInfo();
14305 test_MsiSetExternalUI();
14306 test_lastusedsource();
14307 test_setpropertyfolder();
14308 test_sourcedir_props();
14309 test_concurrentinstall();
14310 test_command_line_parsing();
14311
14312 SetCurrentDirectoryA(prev_path);
14313 }