[MSI_WINETEST] Sync with Wine Staging 1.9.23. CORE-12409
[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 INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
52 (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
53 static INSTALLSTATE (WINAPI *pMsiProvideComponentA)
54 (LPCSTR, LPCSTR, LPCSTR, DWORD, LPSTR, LPDWORD);
55 static INSTALLSTATE (WINAPI *pMsiProvideComponentW)
56 (LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPWSTR, LPDWORD);
57 static UINT (WINAPI *pMsiGetFileHashA)
58 (LPCSTR, DWORD, PMSIFILEHASHINFO);
59 static UINT (WINAPI *pMsiGetProductInfoExA)
60 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
61 static UINT (WINAPI *pMsiOpenPackageExA)
62 (LPCSTR, DWORD, MSIHANDLE*);
63 static UINT (WINAPI *pMsiOpenPackageExW)
64 (LPCWSTR, DWORD, MSIHANDLE*);
65 static UINT (WINAPI *pMsiEnumPatchesExA)
66 (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
67 MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
68 static UINT (WINAPI *pMsiQueryComponentStateA)
69 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
70 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
71 (LPCSTR, LPCSTR ,DWORD, DWORD);
72 static UINT (WINAPI *pMsiGetPatchInfoExA)
73 (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
74 static UINT (WINAPI *pMsiEnumProductsExA)
75 (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
76 static UINT (WINAPI *pMsiEnumComponentsExA)
77 (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
78 static UINT (WINAPI *pMsiSetExternalUIRecord)
79 (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
80 static UINT (WINAPI *pMsiSourceListGetInfoA)
81 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
82
83 static void init_functionpointers(void)
84 {
85 HMODULE hmsi = GetModuleHandleA("msi.dll");
86 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
87 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
88
89 #define GET_PROC(dll, func) \
90 p ## func = (void *)GetProcAddress(dll, #func); \
91 if(!p ## func) \
92 trace("GetProcAddress(%s) failed\n", #func);
93
94 GET_PROC(hmsi, MsiGetComponentPathA)
95 GET_PROC(hmsi, MsiGetComponentPathExA);
96 GET_PROC(hmsi, MsiProvideComponentA)
97 GET_PROC(hmsi, MsiProvideComponentW)
98 GET_PROC(hmsi, MsiGetFileHashA)
99 GET_PROC(hmsi, MsiGetProductInfoExA)
100 GET_PROC(hmsi, MsiOpenPackageExA)
101 GET_PROC(hmsi, MsiOpenPackageExW)
102 GET_PROC(hmsi, MsiEnumPatchesExA)
103 GET_PROC(hmsi, MsiQueryComponentStateA)
104 GET_PROC(hmsi, MsiSetExternalUIRecord)
105 GET_PROC(hmsi, MsiUseFeatureExA)
106 GET_PROC(hmsi, MsiGetPatchInfoExA)
107 GET_PROC(hmsi, MsiEnumProductsExA)
108 GET_PROC(hmsi, MsiEnumComponentsExA)
109 GET_PROC(hmsi, MsiSourceListGetInfoA)
110
111 GET_PROC(hadvapi32, CheckTokenMembership);
112 GET_PROC(hadvapi32, ConvertSidToStringSidA)
113 GET_PROC(hadvapi32, OpenProcessToken);
114 GET_PROC(hadvapi32, RegDeleteKeyExA)
115 GET_PROC(hkernel32, IsWow64Process)
116
117 #undef GET_PROC
118 }
119
120 static BOOL get_system_dirs(void)
121 {
122 HKEY hkey;
123 DWORD type, size;
124
125 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
126 return FALSE;
127
128 size = MAX_PATH;
129 if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
130 RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
131 {
132 RegCloseKey(hkey);
133 return FALSE;
134 }
135 size = MAX_PATH;
136 if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
137 RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
138 {
139 RegCloseKey(hkey);
140 return FALSE;
141 }
142 size = MAX_PATH;
143 if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR_NATIVE, &size))
144 {
145 RegCloseKey(hkey);
146 return FALSE;
147 }
148 RegCloseKey(hkey);
149 if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH)) return FALSE;
150 return TRUE;
151 }
152
153 static BOOL file_exists(const char *file)
154 {
155 return GetFileAttributesA(file) != INVALID_FILE_ATTRIBUTES;
156 }
157
158 static BOOL pf_exists(const char *file)
159 {
160 char path[MAX_PATH];
161
162 lstrcpyA(path, PROG_FILES_DIR);
163 lstrcatA(path, "\\");
164 lstrcatA(path, file);
165 return file_exists(path);
166 }
167
168 static BOOL delete_pf(const char *rel_path, BOOL is_file)
169 {
170 char path[MAX_PATH];
171
172 lstrcpyA(path, PROG_FILES_DIR);
173 lstrcatA(path, "\\");
174 lstrcatA(path, rel_path);
175
176 if (is_file)
177 return DeleteFileA(path);
178 else
179 return RemoveDirectoryA(path);
180 }
181
182 static BOOL is_process_limited(void)
183 {
184 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
185 PSID Group = NULL;
186 BOOL IsInGroup;
187 HANDLE token;
188
189 if (!pCheckTokenMembership || !pOpenProcessToken) return FALSE;
190
191 if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
192 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
193 !pCheckTokenMembership(NULL, Group, &IsInGroup))
194 {
195 trace("Could not check if the current user is an administrator\n");
196 FreeSid(Group);
197 return FALSE;
198 }
199 FreeSid(Group);
200
201 if (!IsInGroup)
202 {
203 /* Only administrators have enough privileges for these tests */
204 return TRUE;
205 }
206
207 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
208 {
209 BOOL ret;
210 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
211 DWORD size;
212
213 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
214 CloseHandle(token);
215 return (ret && type == TokenElevationTypeLimited);
216 }
217 return FALSE;
218 }
219
220 /* cabinet definitions */
221
222 /* make the max size large so there is only one cab file */
223 #define MEDIA_SIZE 0x7FFFFFFF
224 #define FOLDER_THRESHOLD 900000
225
226 /* the FCI callbacks */
227
228 static void * CDECL mem_alloc(ULONG cb)
229 {
230 return HeapAlloc(GetProcessHeap(), 0, cb);
231 }
232
233 static void CDECL mem_free(void *memory)
234 {
235 HeapFree(GetProcessHeap(), 0, memory);
236 }
237
238 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
239 {
240 sprintf(pccab->szCab, pv, pccab->iCab);
241 return TRUE;
242 }
243
244 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
245 {
246 return 0;
247 }
248
249 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
250 BOOL fContinuation, void *pv)
251 {
252 return 0;
253 }
254
255 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
256 {
257 HANDLE handle;
258 DWORD dwAccess = 0;
259 DWORD dwShareMode = 0;
260 DWORD dwCreateDisposition = OPEN_EXISTING;
261
262 dwAccess = GENERIC_READ | GENERIC_WRITE;
263 /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
264 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
265
266 if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
267 dwCreateDisposition = OPEN_EXISTING;
268 else
269 dwCreateDisposition = CREATE_NEW;
270
271 handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
272 dwCreateDisposition, 0, NULL);
273
274 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
275
276 return (INT_PTR)handle;
277 }
278
279 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
280 {
281 HANDLE handle = (HANDLE)hf;
282 DWORD dwRead;
283 BOOL res;
284
285 res = ReadFile(handle, memory, cb, &dwRead, NULL);
286 ok(res, "Failed to ReadFile\n");
287
288 return dwRead;
289 }
290
291 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
292 {
293 HANDLE handle = (HANDLE)hf;
294 DWORD dwWritten;
295 BOOL res;
296
297 res = WriteFile(handle, memory, cb, &dwWritten, NULL);
298 ok(res, "Failed to WriteFile\n");
299
300 return dwWritten;
301 }
302
303 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
304 {
305 HANDLE handle = (HANDLE)hf;
306 ok(CloseHandle(handle), "Failed to CloseHandle\n");
307
308 return 0;
309 }
310
311 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
312 {
313 HANDLE handle = (HANDLE)hf;
314 DWORD ret;
315
316 ret = SetFilePointer(handle, dist, NULL, seektype);
317 ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
318
319 return ret;
320 }
321
322 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
323 {
324 BOOL ret = DeleteFileA(pszFile);
325 ok(ret, "Failed to DeleteFile %s\n", pszFile);
326
327 return 0;
328 }
329
330 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
331 {
332 LPSTR tempname;
333
334 tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
335 GetTempFileNameA(".", "xx", 0, tempname);
336
337 if (tempname && (strlen(tempname) < (unsigned)cbTempName))
338 {
339 lstrcpyA(pszTempName, tempname);
340 HeapFree(GetProcessHeap(), 0, tempname);
341 return TRUE;
342 }
343
344 HeapFree(GetProcessHeap(), 0, tempname);
345
346 return FALSE;
347 }
348
349 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
350 USHORT *pattribs, int *err, void *pv)
351 {
352 BY_HANDLE_FILE_INFORMATION finfo;
353 FILETIME filetime;
354 HANDLE handle;
355 DWORD attrs;
356 BOOL res;
357
358 handle = CreateFileA(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
359 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
360 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
361
362 res = GetFileInformationByHandle(handle, &finfo);
363 ok(res, "Expected GetFileInformationByHandle to succeed\n");
364
365 FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
366 FileTimeToDosDateTime(&filetime, pdate, ptime);
367
368 attrs = GetFileAttributesA(pszName);
369 ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
370
371 return (INT_PTR)handle;
372 }
373
374 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
375 {
376 char path[MAX_PATH];
377 char filename[MAX_PATH];
378
379 lstrcpyA(path, CURR_DIR);
380 lstrcatA(path, "\\");
381 lstrcatA(path, file);
382
383 lstrcpyA(filename, file);
384
385 return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
386 progress, get_open_info, compress);
387 }
388
389 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
390 {
391 ZeroMemory(pCabParams, sizeof(CCAB));
392
393 pCabParams->cb = max_size;
394 pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
395 pCabParams->setID = 0xbeef;
396 pCabParams->iCab = 1;
397 lstrcpyA(pCabParams->szCabPath, CURR_DIR);
398 lstrcatA(pCabParams->szCabPath, "\\");
399 lstrcpyA(pCabParams->szCab, name);
400 }
401
402 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
403 {
404 CCAB cabParams;
405 LPCSTR ptr;
406 HFCI hfci;
407 ERF erf;
408 BOOL res;
409
410 set_cab_parameters(&cabParams, name, max_size);
411
412 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
413 fci_read, fci_write, fci_close, fci_seek, fci_delete,
414 get_temp_file, &cabParams, NULL);
415
416 ok(hfci != NULL, "Failed to create an FCI context\n");
417
418 ptr = files;
419 while (*ptr)
420 {
421 res = add_file(hfci, ptr, tcompTYPE_MSZIP);
422 ok(res, "Failed to add file: %s\n", ptr);
423 ptr += lstrlenA(ptr) + 1;
424 }
425
426 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
427 ok(res, "Failed to flush the cabinet\n");
428
429 res = FCIDestroy(hfci);
430 ok(res, "Failed to destroy the cabinet\n");
431 }
432
433 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
434 {
435 WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
436 IStorage *stg;
437 IStream *stm;
438 HRESULT hr;
439 HANDLE handle;
440
441 MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
442 hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
443 if (FAILED(hr))
444 return FALSE;
445
446 MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
447 hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
448 if (FAILED(hr))
449 {
450 IStorage_Release(stg);
451 return FALSE;
452 }
453
454 handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
455 if (handle != INVALID_HANDLE_VALUE)
456 {
457 DWORD count;
458 char buffer[1024];
459 if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
460 IStream_Write(stm, buffer, count, &count);
461 CloseHandle(handle);
462 }
463
464 IStream_Release(stm);
465 IStorage_Release(stg);
466
467 return TRUE;
468 }
469
470 static void delete_cab_files(void)
471 {
472 SHFILEOPSTRUCTA shfl;
473 CHAR path[MAX_PATH+10];
474
475 lstrcpyA(path, CURR_DIR);
476 lstrcatA(path, "\\*.cab");
477 path[strlen(path) + 1] = '\0';
478
479 shfl.hwnd = NULL;
480 shfl.wFunc = FO_DELETE;
481 shfl.pFrom = path;
482 shfl.pTo = NULL;
483 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
484
485 SHFileOperationA(&shfl);
486 }
487
488 /* msi database data */
489
490 static const char directory_dat[] =
491 "Directory\tDirectory_Parent\tDefaultDir\n"
492 "s72\tS72\tl255\n"
493 "Directory\tDirectory\n"
494 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
495 "ProgramFilesFolder\tTARGETDIR\t.\n"
496 "TARGETDIR\t\tSourceDir";
497
498 static const char component_dat[] =
499 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
500 "s72\tS38\ts72\ti2\tS255\tS72\n"
501 "Component\tComponent\n"
502 "One\t{8F5BAEEF-DD92-40AC-9397-BE3CF9F97C81}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n";
503
504 static const char feature_dat[] =
505 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
506 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
507 "Feature\tFeature\n"
508 "One\t\tOne\tOne\t1\t3\tMSITESTDIR\t0\n"
509 "Two\t\t\t\t2\t1\tTARGETDIR\t0\n";
510
511 static const char feature_comp_dat[] =
512 "Feature_\tComponent_\n"
513 "s38\ts72\n"
514 "FeatureComponents\tFeature_\tComponent_\n"
515 "One\tOne\n";
516
517 static const char file_dat[] =
518 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
519 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
520 "File\tFile\n"
521 "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n";
522
523 static const char install_exec_seq_dat[] =
524 "Action\tCondition\tSequence\n"
525 "s72\tS255\tI2\n"
526 "InstallExecuteSequence\tAction\n"
527 "ValidateProductID\t\t700\n"
528 "CostInitialize\t\t800\n"
529 "FileCost\t\t900\n"
530 "CostFinalize\t\t1000\n"
531 "InstallValidate\t\t1400\n"
532 "InstallInitialize\t\t1500\n"
533 "ProcessComponents\t\t1600\n"
534 "UnpublishFeatures\t\t1800\n"
535 "RemoveFiles\t\t3500\n"
536 "InstallFiles\t\t4000\n"
537 "RegisterProduct\t\t6100\n"
538 "PublishFeatures\t\t6300\n"
539 "PublishProduct\t\t6400\n"
540 "InstallFinalize\t\t6600";
541
542 static const char media_dat[] =
543 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
544 "i2\ti4\tL64\tS255\tS32\tS72\n"
545 "Media\tDiskId\n"
546 "1\t1\t\t\tDISK1\t\n";
547
548 static const char property_dat[] =
549 "Property\tValue\n"
550 "s72\tl0\n"
551 "Property\tProperty\n"
552 "INSTALLLEVEL\t3\n"
553 "Manufacturer\tWine\n"
554 "ProductCode\t{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}\n"
555 "ProductName\tMSITEST\n"
556 "ProductVersion\t1.1.1\n"
557 "UpgradeCode\t{9574448F-9B86-4E07-B6F6-8D199DA12127}\n"
558 "MSIFASTINSTALL\t1\n";
559
560 static const char ci2_property_dat[] =
561 "Property\tValue\n"
562 "s72\tl0\n"
563 "Property\tProperty\n"
564 "INSTALLLEVEL\t3\n"
565 "Manufacturer\tWine\n"
566 "ProductCode\t{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}\n"
567 "ProductName\tMSITEST2\n"
568 "ProductVersion\t1.1.1\n"
569 "UpgradeCode\t{6B60C3CA-B8CA-4FB7-A395-092D98FF5D2A}\n"
570 "MSIFASTINSTALL\t1\n";
571
572 static const char mcp_component_dat[] =
573 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
574 "s72\tS38\ts72\ti2\tS255\tS72\n"
575 "Component\tComponent\n"
576 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
577 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
578 "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
579
580 static const char mcp_feature_dat[] =
581 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
582 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
583 "Feature\tFeature\n"
584 "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
585 "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
586 "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
587
588 static const char mcp_feature_comp_dat[] =
589 "Feature_\tComponent_\n"
590 "s38\ts72\n"
591 "FeatureComponents\tFeature_\tComponent_\n"
592 "hydroxyl\thydrogen\n"
593 "heliox\thelium\n"
594 "lithia\tlithium";
595
596 static const char mcp_file_dat[] =
597 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
598 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
599 "File\tFile\n"
600 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
601 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
602 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
603
604 static const char lus_component_dat[] =
605 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
606 "s72\tS38\ts72\ti2\tS255\tS72\n"
607 "Component\tComponent\n"
608 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
609
610 static const char lus_feature_dat[] =
611 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
612 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
613 "Feature\tFeature\n"
614 "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
615 "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
616
617 static const char lus_file_dat[] =
618 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
619 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
620 "File\tFile\n"
621 "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
622
623 static const char lus_feature_comp_dat[] =
624 "Feature_\tComponent_\n"
625 "s38\ts72\n"
626 "FeatureComponents\tFeature_\tComponent_\n"
627 "feature\tmaximus\n"
628 "montecristo\tmaximus";
629
630 static const char lus_install_exec_seq_dat[] =
631 "Action\tCondition\tSequence\n"
632 "s72\tS255\tI2\n"
633 "InstallExecuteSequence\tAction\n"
634 "ValidateProductID\t\t700\n"
635 "CostInitialize\t\t800\n"
636 "FileCost\t\t900\n"
637 "CostFinalize\t\t1000\n"
638 "InstallValidate\t\t1400\n"
639 "InstallInitialize\t\t1500\n"
640 "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
641 "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
642 "RemoveFiles\t\t3500\n"
643 "InstallFiles\t\t4000\n"
644 "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
645 "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
646 "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
647 "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
648 "InstallFinalize\t\t6600";
649
650 static const char lus0_media_dat[] =
651 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
652 "i2\ti4\tL64\tS255\tS32\tS72\n"
653 "Media\tDiskId\n"
654 "1\t1\t\t\tDISK1\t\n";
655
656 static const char lus1_media_dat[] =
657 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
658 "i2\ti4\tL64\tS255\tS32\tS72\n"
659 "Media\tDiskId\n"
660 "1\t1\t\ttest1.cab\tDISK1\t\n";
661
662 static const char lus2_media_dat[] =
663 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
664 "i2\ti4\tL64\tS255\tS32\tS72\n"
665 "Media\tDiskId\n"
666 "1\t1\t\t#test1.cab\tDISK1\t\n";
667
668 static const char spf_custom_action_dat[] =
669 "Action\tType\tSource\tTarget\tISComments\n"
670 "s72\ti2\tS64\tS0\tS255\n"
671 "CustomAction\tAction\n"
672 "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
673
674 static const char spf_install_exec_seq_dat[] =
675 "Action\tCondition\tSequence\n"
676 "s72\tS255\tI2\n"
677 "InstallExecuteSequence\tAction\n"
678 "CostFinalize\t\t1000\n"
679 "CostInitialize\t\t800\n"
680 "FileCost\t\t900\n"
681 "SetFolderProp\t\t950\n"
682 "InstallFiles\t\t4000\n"
683 "InstallServices\t\t5000\n"
684 "InstallFinalize\t\t6600\n"
685 "InstallInitialize\t\t1500\n"
686 "InstallValidate\t\t1400\n"
687 "LaunchConditions\t\t100";
688
689 static const char spf_install_ui_seq_dat[] =
690 "Action\tCondition\tSequence\n"
691 "s72\tS255\tI2\n"
692 "InstallUISequence\tAction\n"
693 "CostInitialize\t\t800\n"
694 "FileCost\t\t900\n"
695 "CostFinalize\t\t1000\n"
696 "ExecuteAction\t\t1100\n";
697
698 static const char sd_file_dat[] =
699 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
700 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
701 "File\tFile\n"
702 "sourcedir.txt\tsourcedir\tsourcedir.txt\t1000\t\t\t8192\t1\n";
703
704 static const char sd_feature_dat[] =
705 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
706 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
707 "Feature\tFeature\n"
708 "sourcedir\t\t\tsourcedir feature\t1\t2\tMSITESTDIR\t0\n";
709
710 static const char sd_feature_comp_dat[] =
711 "Feature_\tComponent_\n"
712 "s38\ts72\n"
713 "FeatureComponents\tFeature_\tComponent_\n"
714 "sourcedir\tsourcedir\n";
715
716 static const char sd_component_dat[] =
717 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
718 "s72\tS38\ts72\ti2\tS255\tS72\n"
719 "Component\tComponent\n"
720 "sourcedir\t{DD422F92-3ED8-49B5-A0B7-F266F98357DF}\tMSITESTDIR\t0\t\tsourcedir.txt\n";
721
722 static const char sd_install_ui_seq_dat[] =
723 "Action\tCondition\tSequence\n"
724 "s72\tS255\tI2\n"
725 "InstallUISequence\tAction\n"
726 "TestSourceDirProp1\tnot SourceDir and not SOURCEDIR and not Installed\t99\n"
727 "AppSearch\t\t100\n"
728 "TestSourceDirProp2\tnot SourceDir and not SOURCEDIR and not Installed\t101\n"
729 "LaunchConditions\tnot Installed \t110\n"
730 "TestSourceDirProp3\tnot SourceDir and not SOURCEDIR and not Installed\t111\n"
731 "FindRelatedProducts\t\t120\n"
732 "TestSourceDirProp4\tnot SourceDir and not SOURCEDIR and not Installed\t121\n"
733 "CCPSearch\t\t130\n"
734 "TestSourceDirProp5\tnot SourceDir and not SOURCEDIR and not Installed\t131\n"
735 "RMCCPSearch\t\t140\n"
736 "TestSourceDirProp6\tnot SourceDir and not SOURCEDIR and not Installed\t141\n"
737 "ValidateProductID\t\t150\n"
738 "TestSourceDirProp7\tnot SourceDir and not SOURCEDIR and not Installed\t151\n"
739 "CostInitialize\t\t800\n"
740 "TestSourceDirProp8\tnot SourceDir and not SOURCEDIR and not Installed\t801\n"
741 "FileCost\t\t900\n"
742 "TestSourceDirProp9\tnot SourceDir and not SOURCEDIR and not Installed\t901\n"
743 "IsolateComponents\t\t1000\n"
744 "TestSourceDirProp10\tnot SourceDir and not SOURCEDIR and not Installed\t1001\n"
745 "CostFinalize\t\t1100\n"
746 "TestSourceDirProp11\tnot SourceDir and not SOURCEDIR and not Installed\t1101\n"
747 "MigrateFeatureStates\t\t1200\n"
748 "TestSourceDirProp12\tnot SourceDir and not SOURCEDIR and not Installed\t1201\n"
749 "ExecuteAction\t\t1300\n"
750 "TestSourceDirProp13\tnot SourceDir and not SOURCEDIR and not Installed\t1301\n";
751
752 static const char sd_install_exec_seq_dat[] =
753 "Action\tCondition\tSequence\n"
754 "s72\tS255\tI2\n"
755 "InstallExecuteSequence\tAction\n"
756 "TestSourceDirProp14\tSourceDir and SOURCEDIR and not Installed\t99\n"
757 "LaunchConditions\t\t100\n"
758 "TestSourceDirProp15\tSourceDir and SOURCEDIR and not Installed\t101\n"
759 "ValidateProductID\t\t700\n"
760 "TestSourceDirProp16\tSourceDir and SOURCEDIR and not Installed\t701\n"
761 "CostInitialize\t\t800\n"
762 "TestSourceDirProp17\tSourceDir and SOURCEDIR and not Installed\t801\n"
763 "ResolveSource\tResolveSource and not Installed\t850\n"
764 "TestSourceDirProp18\tResolveSource and not SourceDir and not SOURCEDIR and not Installed\t851\n"
765 "TestSourceDirProp19\tnot ResolveSource and SourceDir and SOURCEDIR and not Installed\t852\n"
766 "FileCost\t\t900\n"
767 "TestSourceDirProp20\tSourceDir and SOURCEDIR and not Installed\t901\n"
768 "IsolateComponents\t\t1000\n"
769 "TestSourceDirProp21\tSourceDir and SOURCEDIR and not Installed\t1001\n"
770 "CostFinalize\t\t1100\n"
771 "TestSourceDirProp22\tSourceDir and SOURCEDIR and not Installed\t1101\n"
772 "MigrateFeatureStates\t\t1200\n"
773 "TestSourceDirProp23\tSourceDir and SOURCEDIR and not Installed\t1201\n"
774 "InstallValidate\t\t1400\n"
775 "TestSourceDirProp24\tSourceDir and SOURCEDIR and not Installed\t1401\n"
776 "InstallInitialize\t\t1500\n"
777 "TestSourceDirProp25\tSourceDir and SOURCEDIR and not Installed\t1501\n"
778 "ProcessComponents\t\t1600\n"
779 "TestSourceDirProp26\tnot SourceDir and not SOURCEDIR and not Installed\t1601\n"
780 "UnpublishFeatures\t\t1800\n"
781 "TestSourceDirProp27\tnot SourceDir and not SOURCEDIR and not Installed\t1801\n"
782 "RemoveFiles\t\t3500\n"
783 "TestSourceDirProp28\tnot SourceDir and not SOURCEDIR and not Installed\t3501\n"
784 "InstallFiles\t\t4000\n"
785 "TestSourceDirProp29\tnot SourceDir and not SOURCEDIR and not Installed\t4001\n"
786 "RegisterUser\t\t6000\n"
787 "TestSourceDirProp30\tnot SourceDir and not SOURCEDIR and not Installed\t6001\n"
788 "RegisterProduct\t\t6100\n"
789 "TestSourceDirProp31\tnot SourceDir and not SOURCEDIR and not Installed\t6101\n"
790 "PublishFeatures\t\t6300\n"
791 "TestSourceDirProp32\tnot SourceDir and not SOURCEDIR and not Installed\t6301\n"
792 "PublishProduct\t\t6400\n"
793 "TestSourceDirProp33\tnot SourceDir and not SOURCEDIR and not Installed\t6401\n"
794 "InstallExecute\t\t6500\n"
795 "TestSourceDirProp34\tnot SourceDir and not SOURCEDIR and not Installed\t6501\n"
796 "InstallFinalize\t\t6600\n"
797 "TestSourceDirProp35\tnot SourceDir and not SOURCEDIR and not Installed\t6601\n";
798
799 static const char sd_custom_action_dat[] =
800 "Action\tType\tSource\tTarget\tISComments\n"
801 "s72\ti2\tS64\tS0\tS255\n"
802 "CustomAction\tAction\n"
803 "TestSourceDirProp1\t19\t\tTest 1 failed\t\n"
804 "TestSourceDirProp2\t19\t\tTest 2 failed\t\n"
805 "TestSourceDirProp3\t19\t\tTest 3 failed\t\n"
806 "TestSourceDirProp4\t19\t\tTest 4 failed\t\n"
807 "TestSourceDirProp5\t19\t\tTest 5 failed\t\n"
808 "TestSourceDirProp6\t19\t\tTest 6 failed\t\n"
809 "TestSourceDirProp7\t19\t\tTest 7 failed\t\n"
810 "TestSourceDirProp8\t19\t\tTest 8 failed\t\n"
811 "TestSourceDirProp9\t19\t\tTest 9 failed\t\n"
812 "TestSourceDirProp10\t19\t\tTest 10 failed\t\n"
813 "TestSourceDirProp11\t19\t\tTest 11 failed\t\n"
814 "TestSourceDirProp12\t19\t\tTest 12 failed\t\n"
815 "TestSourceDirProp13\t19\t\tTest 13 failed\t\n"
816 "TestSourceDirProp14\t19\t\tTest 14 failed\t\n"
817 "TestSourceDirProp15\t19\t\tTest 15 failed\t\n"
818 "TestSourceDirProp16\t19\t\tTest 16 failed\t\n"
819 "TestSourceDirProp17\t19\t\tTest 17 failed\t\n"
820 "TestSourceDirProp18\t19\t\tTest 18 failed\t\n"
821 "TestSourceDirProp19\t19\t\tTest 19 failed\t\n"
822 "TestSourceDirProp20\t19\t\tTest 20 failed\t\n"
823 "TestSourceDirProp21\t19\t\tTest 21 failed\t\n"
824 "TestSourceDirProp22\t19\t\tTest 22 failed\t\n"
825 "TestSourceDirProp23\t19\t\tTest 23 failed\t\n"
826 "TestSourceDirProp24\t19\t\tTest 24 failed\t\n"
827 "TestSourceDirProp25\t19\t\tTest 25 failed\t\n"
828 "TestSourceDirProp26\t19\t\tTest 26 failed\t\n"
829 "TestSourceDirProp27\t19\t\tTest 27 failed\t\n"
830 "TestSourceDirProp28\t19\t\tTest 28 failed\t\n"
831 "TestSourceDirProp29\t19\t\tTest 29 failed\t\n"
832 "TestSourceDirProp30\t19\t\tTest 30 failed\t\n"
833 "TestSourceDirProp31\t19\t\tTest 31 failed\t\n"
834 "TestSourceDirProp32\t19\t\tTest 32 failed\t\n"
835 "TestSourceDirProp33\t19\t\tTest 33 failed\t\n"
836 "TestSourceDirProp34\t19\t\tTest 34 failed\t\n"
837 "TestSourceDirProp35\t19\t\tTest 35 failed\t\n";
838
839 static const char ci_install_exec_seq_dat[] =
840 "Action\tCondition\tSequence\n"
841 "s72\tS255\tI2\n"
842 "InstallExecuteSequence\tAction\n"
843 "CostInitialize\t\t800\n"
844 "FileCost\t\t900\n"
845 "CostFinalize\t\t1000\n"
846 "InstallValidate\t\t1400\n"
847 "InstallInitialize\t\t1500\n"
848 "RunInstall\tnot Installed\t1550\n"
849 "ProcessComponents\t\t1600\n"
850 "UnpublishFeatures\t\t1800\n"
851 "RemoveFiles\t\t3500\n"
852 "InstallFiles\t\t4000\n"
853 "RegisterProduct\t\t6100\n"
854 "PublishFeatures\t\t6300\n"
855 "PublishProduct\t\t6400\n"
856 "InstallFinalize\t\t6600\n";
857
858 static const char ci_custom_action_dat[] =
859 "Action\tType\tSource\tTarget\tISComments\n"
860 "s72\ti2\tS64\tS0\tS255\n"
861 "CustomAction\tAction\n"
862 "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
863
864 static const char ci_component_dat[] =
865 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
866 "s72\tS38\ts72\ti2\tS255\tS72\n"
867 "Component\tComponent\n"
868 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
869
870 static const char ci2_component_dat[] =
871 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
872 "s72\tS38\ts72\ti2\tS255\tS72\n"
873 "Component\tComponent\n"
874 "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
875
876 static const char ci2_feature_comp_dat[] =
877 "Feature_\tComponent_\n"
878 "s38\ts72\n"
879 "FeatureComponents\tFeature_\tComponent_\n"
880 "feature\taugustus";
881
882 static const char ci2_file_dat[] =
883 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
884 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
885 "File\tFile\n"
886 "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
887
888 static const char cl_custom_action_dat[] =
889 "Action\tType\tSource\tTarget\tISComments\n"
890 "s72\ti2\tS64\tS0\tS255\n"
891 "CustomAction\tAction\n"
892 "TestCommandlineProp\t19\t\tTest1\t\n";
893
894 static const char cl_install_exec_seq_dat[] =
895 "Action\tCondition\tSequence\n"
896 "s72\tS255\tI2\n"
897 "InstallExecuteSequence\tAction\n"
898 "LaunchConditions\t\t100\n"
899 "ValidateProductID\t\t700\n"
900 "CostInitialize\t\t800\n"
901 "FileCost\t\t900\n"
902 "CostFinalize\t\t1000\n"
903 "TestCommandlineProp\tP=\"one\"\t1100\n"
904 "InstallInitialize\t\t1500\n"
905 "ProcessComponents\t\t1600\n"
906 "InstallValidate\t\t1400\n"
907 "InstallFinalize\t\t5000\n";
908
909 typedef struct _msi_table
910 {
911 const CHAR *filename;
912 const CHAR *data;
913 int size;
914 } msi_table;
915
916 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
917
918 static const msi_table tables[] =
919 {
920 ADD_TABLE(directory),
921 ADD_TABLE(component),
922 ADD_TABLE(feature),
923 ADD_TABLE(feature_comp),
924 ADD_TABLE(file),
925 ADD_TABLE(install_exec_seq),
926 ADD_TABLE(media),
927 ADD_TABLE(property),
928 };
929
930 static const msi_table mcp_tables[] =
931 {
932 ADD_TABLE(directory),
933 ADD_TABLE(mcp_component),
934 ADD_TABLE(mcp_feature),
935 ADD_TABLE(mcp_feature_comp),
936 ADD_TABLE(mcp_file),
937 ADD_TABLE(install_exec_seq),
938 ADD_TABLE(media),
939 ADD_TABLE(property)
940 };
941
942 static const msi_table lus0_tables[] =
943 {
944 ADD_TABLE(lus_component),
945 ADD_TABLE(directory),
946 ADD_TABLE(lus_feature),
947 ADD_TABLE(lus_feature_comp),
948 ADD_TABLE(lus_file),
949 ADD_TABLE(lus_install_exec_seq),
950 ADD_TABLE(lus0_media),
951 ADD_TABLE(property)
952 };
953
954 static const msi_table lus1_tables[] =
955 {
956 ADD_TABLE(lus_component),
957 ADD_TABLE(directory),
958 ADD_TABLE(lus_feature),
959 ADD_TABLE(lus_feature_comp),
960 ADD_TABLE(lus_file),
961 ADD_TABLE(lus_install_exec_seq),
962 ADD_TABLE(lus1_media),
963 ADD_TABLE(property)
964 };
965
966 static const msi_table lus2_tables[] =
967 {
968 ADD_TABLE(lus_component),
969 ADD_TABLE(directory),
970 ADD_TABLE(lus_feature),
971 ADD_TABLE(lus_feature_comp),
972 ADD_TABLE(lus_file),
973 ADD_TABLE(lus_install_exec_seq),
974 ADD_TABLE(lus2_media),
975 ADD_TABLE(property)
976 };
977
978 static const msi_table spf_tables[] =
979 {
980 ADD_TABLE(lus_component),
981 ADD_TABLE(directory),
982 ADD_TABLE(lus_feature),
983 ADD_TABLE(lus_feature_comp),
984 ADD_TABLE(lus_file),
985 ADD_TABLE(lus0_media),
986 ADD_TABLE(property),
987 ADD_TABLE(spf_custom_action),
988 ADD_TABLE(spf_install_exec_seq),
989 ADD_TABLE(spf_install_ui_seq)
990 };
991
992 static const msi_table sd_tables[] =
993 {
994 ADD_TABLE(directory),
995 ADD_TABLE(sd_component),
996 ADD_TABLE(sd_feature),
997 ADD_TABLE(sd_feature_comp),
998 ADD_TABLE(sd_file),
999 ADD_TABLE(sd_install_exec_seq),
1000 ADD_TABLE(sd_install_ui_seq),
1001 ADD_TABLE(sd_custom_action),
1002 ADD_TABLE(media),
1003 ADD_TABLE(property)
1004 };
1005
1006 static const msi_table ci_tables[] =
1007 {
1008 ADD_TABLE(ci_component),
1009 ADD_TABLE(directory),
1010 ADD_TABLE(lus_feature),
1011 ADD_TABLE(lus_feature_comp),
1012 ADD_TABLE(lus_file),
1013 ADD_TABLE(ci_install_exec_seq),
1014 ADD_TABLE(lus0_media),
1015 ADD_TABLE(property),
1016 ADD_TABLE(ci_custom_action),
1017 };
1018
1019 static const msi_table ci2_tables[] =
1020 {
1021 ADD_TABLE(ci2_component),
1022 ADD_TABLE(directory),
1023 ADD_TABLE(lus_feature),
1024 ADD_TABLE(ci2_feature_comp),
1025 ADD_TABLE(ci2_file),
1026 ADD_TABLE(install_exec_seq),
1027 ADD_TABLE(lus0_media),
1028 ADD_TABLE(ci2_property),
1029 };
1030
1031 static const msi_table cl_tables[] =
1032 {
1033 ADD_TABLE(component),
1034 ADD_TABLE(directory),
1035 ADD_TABLE(feature),
1036 ADD_TABLE(feature_comp),
1037 ADD_TABLE(file),
1038 ADD_TABLE(cl_custom_action),
1039 ADD_TABLE(cl_install_exec_seq),
1040 ADD_TABLE(media),
1041 ADD_TABLE(property)
1042 };
1043
1044 static void write_file(const CHAR *filename, const char *data, int data_size)
1045 {
1046 DWORD size;
1047
1048 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
1049 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1050 WriteFile(hf, data, data_size, &size, NULL);
1051 CloseHandle(hf);
1052 }
1053
1054 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
1055 {
1056 MSIHANDLE summary;
1057 UINT r;
1058
1059 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1061
1062 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
1063 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1064
1065 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1066 "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
1067 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1068
1069 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
1070 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1071
1072 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
1073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1074
1075 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1076 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1077
1078 /* write the summary changes back to the stream */
1079 r = MsiSummaryInfoPersist(summary);
1080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1081
1082 MsiCloseHandle(summary);
1083 }
1084
1085 #define create_database(name, tables, num_tables) \
1086 create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
1087
1088 #define create_database_template(name, tables, num_tables, version, template) \
1089 create_database_wordcount(name, tables, num_tables, version, 0, template);
1090
1091 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
1092 int num_tables, INT version, INT wordcount,
1093 const char *template)
1094 {
1095 MSIHANDLE db;
1096 UINT r;
1097 WCHAR *nameW;
1098 int j, len;
1099
1100 len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
1101 if (!(nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return;
1102 MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
1103
1104 r = MsiOpenDatabaseW(nameW, MSIDBOPEN_CREATE, &db);
1105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1106
1107 /* import the tables into the database */
1108 for (j = 0; j < num_tables; j++)
1109 {
1110 const msi_table *table = &tables[j];
1111
1112 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1113
1114 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1115 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1116
1117 DeleteFileA(table->filename);
1118 }
1119
1120 write_msi_summary_info(db, version, wordcount, template);
1121
1122 r = MsiDatabaseCommit(db);
1123 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1124
1125 MsiCloseHandle(db);
1126 HeapFree( GetProcessHeap(), 0, nameW );
1127 }
1128
1129 static UINT run_query(MSIHANDLE hdb, const char *query)
1130 {
1131 MSIHANDLE hview = 0;
1132 UINT r;
1133
1134 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1135 if (r != ERROR_SUCCESS)
1136 return r;
1137
1138 r = MsiViewExecute(hview, 0);
1139 if (r == ERROR_SUCCESS)
1140 r = MsiViewClose(hview);
1141 MsiCloseHandle(hview);
1142 return r;
1143 }
1144
1145 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
1146 {
1147 UINT res;
1148 MSIHANDLE suminfo;
1149
1150 /* build summary info */
1151 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
1152 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
1153
1154 res = MsiSummaryInfoSetPropertyA(suminfo, 2, VT_LPSTR, 0, NULL,
1155 "Installation Database");
1156 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1157
1158 res = MsiSummaryInfoSetPropertyA(suminfo, 3, VT_LPSTR, 0, NULL,
1159 "Installation Database");
1160 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1161
1162 res = MsiSummaryInfoSetPropertyA(suminfo, 4, VT_LPSTR, 0, NULL,
1163 "Wine Hackers");
1164 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1165
1166 res = MsiSummaryInfoSetPropertyA(suminfo, 7, VT_LPSTR, 0, NULL,
1167 ";1033");
1168 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1169
1170 res = MsiSummaryInfoSetPropertyA(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1171 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
1172 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1173
1174 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
1175 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1176
1177 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
1178 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1179
1180 res = MsiSummaryInfoPersist(suminfo);
1181 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
1182
1183 res = MsiCloseHandle(suminfo);
1184 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
1185
1186 return res;
1187 }
1188
1189 static MSIHANDLE create_package_db(LPSTR prodcode)
1190 {
1191 MSIHANDLE hdb = 0;
1192 CHAR query[MAX_PATH];
1193 UINT res;
1194
1195 DeleteFileA(msifile);
1196
1197 /* create an empty database */
1198 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
1199 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1200 if (res != ERROR_SUCCESS)
1201 return hdb;
1202
1203 res = MsiDatabaseCommit(hdb);
1204 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1205
1206 set_summary_info(hdb, prodcode);
1207
1208 res = run_query(hdb,
1209 "CREATE TABLE `Directory` ( "
1210 "`Directory` CHAR(255) NOT NULL, "
1211 "`Directory_Parent` CHAR(255), "
1212 "`DefaultDir` CHAR(255) NOT NULL "
1213 "PRIMARY KEY `Directory`)");
1214 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1215
1216 res = run_query(hdb,
1217 "CREATE TABLE `Property` ( "
1218 "`Property` CHAR(72) NOT NULL, "
1219 "`Value` CHAR(255) "
1220 "PRIMARY KEY `Property`)");
1221 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1222
1223 sprintf(query, "INSERT INTO `Property` "
1224 "(`Property`, `Value`) "
1225 "VALUES( 'ProductCode', '%s' )", prodcode);
1226 res = run_query(hdb, query);
1227 ok(res == ERROR_SUCCESS , "Failed\n");
1228
1229 res = MsiDatabaseCommit(hdb);
1230 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1231
1232 return hdb;
1233 }
1234
1235 static void test_usefeature(void)
1236 {
1237 INSTALLSTATE r;
1238
1239 if (!pMsiUseFeatureExA)
1240 {
1241 win_skip("MsiUseFeatureExA not implemented\n");
1242 return;
1243 }
1244
1245 r = MsiQueryFeatureStateA(NULL, NULL);
1246 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1247
1248 r = MsiQueryFeatureStateA("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
1249 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1250
1251 r = pMsiUseFeatureExA(NULL,NULL,0,0);
1252 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1253
1254 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
1255 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1256
1257 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1258 NULL, -2, 0 );
1259 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1260
1261 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
1262 "WORDVIEWFiles", -2, 0 );
1263 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1264
1265 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
1266 "WORDVIEWFiles", -2, 0 );
1267 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1268
1269 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1270 "WORDVIEWFiles", -2, 1 );
1271 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1272 }
1273
1274 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
1275 {
1276 if (pRegDeleteKeyExA)
1277 return pRegDeleteKeyExA( key, subkey, access, 0 );
1278 return RegDeleteKeyA( key, subkey );
1279 }
1280
1281 static void test_null(void)
1282 {
1283 MSIHANDLE hpkg;
1284 UINT r;
1285 HKEY hkey;
1286 DWORD dwType, cbData;
1287 LPBYTE lpData = NULL;
1288 INSTALLSTATE state;
1289 REGSAM access = KEY_ALL_ACCESS;
1290
1291 if (is_wow64)
1292 access |= KEY_WOW64_64KEY;
1293
1294 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
1295 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1296
1297 state = MsiQueryProductStateW(NULL);
1298 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
1299
1300 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
1301 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1302
1303 r = MsiConfigureFeatureW(NULL, NULL, 0);
1304 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1305
1306 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
1307 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1308
1309 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
1310 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1311
1312 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
1313 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
1314
1315 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
1316 * necessary registry values */
1317
1318 /* empty product string */
1319 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
1320 if (r == ERROR_ACCESS_DENIED)
1321 {
1322 skip("Not enough rights to perform tests\n");
1323 return;
1324 }
1325 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1326
1327 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1328 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
1329 if ( r == ERROR_SUCCESS )
1330 {
1331 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
1332 if (!lpData)
1333 skip("Out of memory\n");
1334 else
1335 {
1336 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1337 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1338 }
1339 }
1340
1341 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1342 if (r == ERROR_ACCESS_DENIED)
1343 {
1344 skip("Not enough rights to perform tests\n");
1345 HeapFree(GetProcessHeap(), 0, lpData);
1346 RegCloseKey(hkey);
1347 return;
1348 }
1349 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1350
1351 r = MsiGetProductInfoA("", "", NULL, NULL);
1352 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1353
1354 if (lpData)
1355 {
1356 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
1357 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1358
1359 HeapFree(GetProcessHeap(), 0, lpData);
1360 }
1361 else
1362 {
1363 r = RegDeleteValueA(hkey, NULL);
1364 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1365 }
1366
1367 r = RegCloseKey(hkey);
1368 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1369
1370 /* empty attribute */
1371 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1372 0, NULL, 0, access, NULL, &hkey, NULL);
1373 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1374
1375 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1376 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1377
1378 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
1379 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
1380
1381 r = RegCloseKey(hkey);
1382 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1383
1384 r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1385 access & KEY_WOW64_64KEY);
1386 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1387 }
1388
1389 static void test_getcomponentpath(void)
1390 {
1391 INSTALLSTATE r;
1392 char buffer[0x100];
1393 DWORD sz;
1394
1395 if(!pMsiGetComponentPathA)
1396 return;
1397
1398 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
1399 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1400
1401 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
1402 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1403
1404 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
1405 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1406
1407 sz = sizeof buffer;
1408 buffer[0]=0;
1409 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
1410 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1411
1412 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
1413 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
1414 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1415
1416 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1417 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
1418 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1419
1420 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1421 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
1422 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1423
1424 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
1425 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
1426 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1427 }
1428
1429 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
1430 {
1431 HANDLE file;
1432 DWORD written;
1433
1434 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1435 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1436 WriteFile(file, data, strlen(data), &written, NULL);
1437
1438 if (size)
1439 {
1440 SetFilePointer(file, size, NULL, FILE_BEGIN);
1441 SetEndOfFile(file);
1442 }
1443
1444 CloseHandle(file);
1445 }
1446
1447 static void create_test_files(void)
1448 {
1449 CreateDirectoryA("msitest", NULL);
1450 create_file("msitest\\one.txt", "msitest\\one.txt", 100);
1451 CreateDirectoryA("msitest\\first", NULL);
1452 create_file("msitest\\first\\two.txt", "msitest\\first\\two.txt", 100);
1453 CreateDirectoryA("msitest\\second", NULL);
1454 create_file("msitest\\second\\three.txt", "msitest\\second\\three.txt", 100);
1455
1456 create_file("four.txt", "four.txt", 100);
1457 create_file("five.txt", "five.txt", 100);
1458 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1459
1460 create_file("msitest\\filename", "msitest\\filename", 100);
1461 create_file("msitest\\service.exe", "msitest\\service.exe", 100);
1462
1463 DeleteFileA("four.txt");
1464 DeleteFileA("five.txt");
1465 }
1466
1467 static void delete_test_files(void)
1468 {
1469 DeleteFileA("msitest.msi");
1470 DeleteFileA("msitest.cab");
1471 DeleteFileA("msitest\\second\\three.txt");
1472 DeleteFileA("msitest\\first\\two.txt");
1473 DeleteFileA("msitest\\one.txt");
1474 DeleteFileA("msitest\\service.exe");
1475 DeleteFileA("msitest\\filename");
1476 RemoveDirectoryA("msitest\\second");
1477 RemoveDirectoryA("msitest\\first");
1478 RemoveDirectoryA("msitest");
1479 }
1480
1481 #define HASHSIZE sizeof(MSIFILEHASHINFO)
1482
1483 static const struct
1484 {
1485 LPCSTR data;
1486 DWORD size;
1487 MSIFILEHASHINFO hash;
1488 } hash_data[] =
1489 {
1490 { "", 0,
1491 { HASHSIZE,
1492 { 0, 0, 0, 0 },
1493 },
1494 },
1495
1496 { "abc", 0,
1497 { HASHSIZE,
1498 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
1499 },
1500 },
1501
1502 { "C:\\Program Files\\msitest\\caesar\n", 0,
1503 { HASHSIZE,
1504 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
1505 },
1506 },
1507
1508 { "C:\\Program Files\\msitest\\caesar\n", 500,
1509 { HASHSIZE,
1510 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
1511 },
1512 },
1513 };
1514
1515 static void test_MsiGetFileHash(void)
1516 {
1517 const char name[] = "msitest.bin";
1518 UINT r;
1519 MSIFILEHASHINFO hash;
1520 DWORD i;
1521
1522 if (!pMsiGetFileHashA)
1523 {
1524 win_skip("MsiGetFileHash not implemented\n");
1525 return;
1526 }
1527
1528 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1529
1530 /* szFilePath is NULL */
1531 r = pMsiGetFileHashA(NULL, 0, &hash);
1532 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1533
1534 /* szFilePath is empty */
1535 r = pMsiGetFileHashA("", 0, &hash);
1536 ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
1537 "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
1538
1539 /* szFilePath is nonexistent */
1540 r = pMsiGetFileHashA(name, 0, &hash);
1541 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
1542
1543 /* dwOptions is non-zero */
1544 r = pMsiGetFileHashA(name, 1, &hash);
1545 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1546
1547 /* pHash.dwFileHashInfoSize is not correct */
1548 hash.dwFileHashInfoSize = 0;
1549 r = pMsiGetFileHashA(name, 0, &hash);
1550 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1551
1552 /* pHash is NULL */
1553 r = pMsiGetFileHashA(name, 0, NULL);
1554 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1555
1556 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
1557 {
1558 int ret;
1559
1560 create_file(name, hash_data[i].data, hash_data[i].size);
1561
1562 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
1563 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1564
1565 r = pMsiGetFileHashA(name, 0, &hash);
1566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1567
1568 ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
1569 ok(!ret, "Hash incorrect\n");
1570
1571 DeleteFileA(name);
1572 }
1573 }
1574
1575 /* copied from dlls/msi/registry.c */
1576 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
1577 {
1578 DWORD i,n=1;
1579 GUID guid;
1580
1581 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
1582 return FALSE;
1583
1584 for(i=0; i<8; i++)
1585 out[7-i] = in[n++];
1586 n++;
1587 for(i=0; i<4; i++)
1588 out[11-i] = in[n++];
1589 n++;
1590 for(i=0; i<4; i++)
1591 out[15-i] = in[n++];
1592 n++;
1593 for(i=0; i<2; i++)
1594 {
1595 out[17+i*2] = in[n++];
1596 out[16+i*2] = in[n++];
1597 }
1598 n++;
1599 for( ; i<8; i++)
1600 {
1601 out[17+i*2] = in[n++];
1602 out[16+i*2] = in[n++];
1603 }
1604 out[32]=0;
1605 return TRUE;
1606 }
1607
1608 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
1609 {
1610 WCHAR guidW[MAX_PATH];
1611 WCHAR squashedW[MAX_PATH];
1612 GUID guid;
1613 HRESULT hr;
1614 int size;
1615
1616 hr = CoCreateGuid(&guid);
1617 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1618
1619 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1620 ok(size == 39, "Expected 39, got %d\n", hr);
1621
1622 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
1623 if (squashed)
1624 {
1625 squash_guid(guidW, squashedW);
1626 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1627 }
1628 }
1629
1630 static char *get_user_sid(void)
1631 {
1632 HANDLE token;
1633 DWORD size = 0;
1634 TOKEN_USER *user;
1635 char *usersid = NULL;
1636
1637 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1638 GetTokenInformation(token, TokenUser, NULL, size, &size);
1639
1640 user = HeapAlloc(GetProcessHeap(), 0, size);
1641 GetTokenInformation(token, TokenUser, user, size, &size);
1642 pConvertSidToStringSidA(user->User.Sid, &usersid);
1643 HeapFree(GetProcessHeap(), 0, user);
1644
1645 CloseHandle(token);
1646 return usersid;
1647 }
1648
1649 static void test_MsiQueryProductState(void)
1650 {
1651 CHAR prodcode[MAX_PATH];
1652 CHAR prod_squashed[MAX_PATH];
1653 CHAR keypath[MAX_PATH*2];
1654 LPSTR usersid;
1655 INSTALLSTATE state;
1656 LONG res;
1657 HKEY userkey, localkey, props;
1658 HKEY prodkey;
1659 DWORD data, error;
1660 REGSAM access = KEY_ALL_ACCESS;
1661
1662 create_test_guid(prodcode, prod_squashed);
1663 usersid = get_user_sid();
1664
1665 if (is_wow64)
1666 access |= KEY_WOW64_64KEY;
1667
1668 /* NULL prodcode */
1669 SetLastError(0xdeadbeef);
1670 state = MsiQueryProductStateA(NULL);
1671 error = GetLastError();
1672 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1673 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1674
1675 /* empty prodcode */
1676 SetLastError(0xdeadbeef);
1677 state = MsiQueryProductStateA("");
1678 error = GetLastError();
1679 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1680 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1681
1682 /* garbage prodcode */
1683 SetLastError(0xdeadbeef);
1684 state = MsiQueryProductStateA("garbage");
1685 error = GetLastError();
1686 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1687 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1688
1689 /* guid without brackets */
1690 SetLastError(0xdeadbeef);
1691 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
1692 error = GetLastError();
1693 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1694 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1695
1696 /* guid with brackets */
1697 SetLastError(0xdeadbeef);
1698 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
1699 error = GetLastError();
1700 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1701 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1702 "expected ERROR_SUCCESS, got %u\n", error);
1703
1704 /* same length as guid, but random */
1705 SetLastError(0xdeadbeef);
1706 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
1707 error = GetLastError();
1708 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1709 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1710
1711 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1712
1713 SetLastError(0xdeadbeef);
1714 state = MsiQueryProductStateA(prodcode);
1715 error = GetLastError();
1716 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1717 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1718 "expected ERROR_SUCCESS, got %u\n", error);
1719
1720 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1721 lstrcatA(keypath, prod_squashed);
1722
1723 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1724 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1725
1726 /* user product key exists */
1727 SetLastError(0xdeadbeef);
1728 state = MsiQueryProductStateA(prodcode);
1729 error = GetLastError();
1730 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1731 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1732 "expected ERROR_SUCCESS, got %u\n", error);
1733
1734 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
1735 lstrcatA(keypath, prodcode);
1736
1737 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1738 if (res == ERROR_ACCESS_DENIED)
1739 {
1740 skip("Not enough rights to perform tests\n");
1741 RegDeleteKeyA(userkey, "");
1742 RegCloseKey(userkey);
1743 LocalFree(usersid);
1744 return;
1745 }
1746 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1747
1748 /* local uninstall key exists */
1749 SetLastError(0xdeadbeef);
1750 state = MsiQueryProductStateA(prodcode);
1751 error = GetLastError();
1752 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1753 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1754 "expected ERROR_SUCCESS, got %u\n", error);
1755
1756 data = 1;
1757 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1758 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1759
1760 /* WindowsInstaller value 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 RegDeleteValueA(localkey, "WindowsInstaller");
1769 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1770
1771 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1772 lstrcatA(keypath, usersid);
1773 lstrcatA(keypath, "\\Products\\");
1774 lstrcatA(keypath, prod_squashed);
1775
1776 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1777 if (res == ERROR_ACCESS_DENIED)
1778 {
1779 skip("Not enough rights to perform tests\n");
1780 RegDeleteKeyA(userkey, "");
1781 RegCloseKey(userkey);
1782 LocalFree(usersid);
1783 return;
1784 }
1785 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1786
1787 /* local product key exists */
1788 SetLastError(0xdeadbeef);
1789 state = MsiQueryProductStateA(prodcode);
1790 error = GetLastError();
1791 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1792 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1793 "expected ERROR_SUCCESS, got %u\n", error);
1794
1795 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1796 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1797
1798 /* install properties key exists */
1799 SetLastError(0xdeadbeef);
1800 state = MsiQueryProductStateA(prodcode);
1801 error = GetLastError();
1802 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1803 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1804 "expected ERROR_SUCCESS, got %u\n", error);
1805
1806 data = 1;
1807 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1808 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1809
1810 /* WindowsInstaller value exists */
1811 SetLastError(0xdeadbeef);
1812 state = MsiQueryProductStateA(prodcode);
1813 error = GetLastError();
1814 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1815 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1816 "expected ERROR_SUCCESS, got %u\n", error);
1817
1818 data = 2;
1819 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1820 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1821
1822 /* WindowsInstaller value is not 1 */
1823 SetLastError(0xdeadbeef);
1824 state = MsiQueryProductStateA(prodcode);
1825 error = GetLastError();
1826 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1827 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1828 "expected ERROR_SUCCESS, got %u\n", error);
1829
1830 RegDeleteKeyA(userkey, "");
1831
1832 /* user product key does not exist */
1833 SetLastError(0xdeadbeef);
1834 state = MsiQueryProductStateA(prodcode);
1835 error = GetLastError();
1836 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1837 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1838 "expected ERROR_SUCCESS, got %u\n", error);
1839
1840 RegDeleteValueA(props, "WindowsInstaller");
1841 delete_key(props, "", access & KEY_WOW64_64KEY);
1842 RegCloseKey(props);
1843 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1844 RegCloseKey(localkey);
1845 RegDeleteKeyA(userkey, "");
1846 RegCloseKey(userkey);
1847
1848 /* MSIINSTALLCONTEXT_USERMANAGED */
1849
1850 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1851 lstrcatA(keypath, usersid);
1852 lstrcatA(keypath, "\\Installer\\Products\\");
1853 lstrcatA(keypath, prod_squashed);
1854
1855 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1857
1858 state = MsiQueryProductStateA(prodcode);
1859 ok(state == INSTALLSTATE_ADVERTISED,
1860 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1861
1862 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1863 lstrcatA(keypath, usersid);
1864 lstrcatA(keypath, "\\Products\\");
1865 lstrcatA(keypath, prod_squashed);
1866
1867 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1869
1870 state = MsiQueryProductStateA(prodcode);
1871 ok(state == INSTALLSTATE_ADVERTISED,
1872 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1873
1874 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1875 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1876
1877 state = MsiQueryProductStateA(prodcode);
1878 ok(state == INSTALLSTATE_ADVERTISED,
1879 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1880
1881 data = 1;
1882 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1883 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1884
1885 /* WindowsInstaller value exists */
1886 state = MsiQueryProductStateA(prodcode);
1887 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1888
1889 RegDeleteValueA(props, "WindowsInstaller");
1890 delete_key(props, "", access & KEY_WOW64_64KEY);
1891 RegCloseKey(props);
1892 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1893 RegCloseKey(localkey);
1894 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1895 RegCloseKey(prodkey);
1896
1897 /* MSIINSTALLCONTEXT_MACHINE */
1898
1899 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1900 lstrcatA(keypath, prod_squashed);
1901
1902 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1903 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1904
1905 state = MsiQueryProductStateA(prodcode);
1906 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1907
1908 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1909 lstrcatA(keypath, "S-1-5-18\\Products\\");
1910 lstrcatA(keypath, prod_squashed);
1911
1912 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1913 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1914
1915 state = MsiQueryProductStateA(prodcode);
1916 ok(state == INSTALLSTATE_ADVERTISED,
1917 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1918
1919 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1920 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1921
1922 state = MsiQueryProductStateA(prodcode);
1923 ok(state == INSTALLSTATE_ADVERTISED,
1924 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1925
1926 data = 1;
1927 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1928 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1929
1930 /* WindowsInstaller value exists */
1931 state = MsiQueryProductStateA(prodcode);
1932 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1933
1934 RegDeleteValueA(props, "WindowsInstaller");
1935 delete_key(props, "", access & KEY_WOW64_64KEY);
1936 RegCloseKey(props);
1937 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1938 RegCloseKey(localkey);
1939 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1940 RegCloseKey(prodkey);
1941
1942 LocalFree(usersid);
1943 }
1944
1945 static const char table_enc85[] =
1946 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
1947 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
1948 "yz{}~";
1949
1950 /*
1951 * Encodes a base85 guid given a GUID pointer
1952 * Caller should provide a 21 character buffer for the encoded string.
1953 */
1954 static void encode_base85_guid( GUID *guid, LPWSTR str )
1955 {
1956 unsigned int x, *p, i;
1957
1958 p = (unsigned int*) guid;
1959 for( i=0; i<4; i++ )
1960 {
1961 x = p[i];
1962 *str++ = table_enc85[x%85];
1963 x = x/85;
1964 *str++ = table_enc85[x%85];
1965 x = x/85;
1966 *str++ = table_enc85[x%85];
1967 x = x/85;
1968 *str++ = table_enc85[x%85];
1969 x = x/85;
1970 *str++ = table_enc85[x%85];
1971 }
1972 *str = 0;
1973 }
1974
1975 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
1976 {
1977 WCHAR guidW[MAX_PATH];
1978 WCHAR base85W[MAX_PATH];
1979 WCHAR squashedW[MAX_PATH];
1980 GUID guid;
1981 HRESULT hr;
1982 int size;
1983
1984 hr = CoCreateGuid(&guid);
1985 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1986
1987 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1988 ok(size == 39, "Expected 39, got %d\n", hr);
1989
1990 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1991 encode_base85_guid(&guid, base85W);
1992 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1993 squash_guid(guidW, squashedW);
1994 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1995 }
1996
1997 static void test_MsiQueryFeatureState(void)
1998 {
1999 HKEY userkey, localkey, compkey, compkey2;
2000 CHAR prodcode[MAX_PATH];
2001 CHAR prod_squashed[MAX_PATH];
2002 CHAR component[MAX_PATH];
2003 CHAR comp_base85[MAX_PATH];
2004 CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
2005 CHAR keypath[MAX_PATH*2];
2006 INSTALLSTATE state;
2007 LPSTR usersid;
2008 LONG res;
2009 REGSAM access = KEY_ALL_ACCESS;
2010 DWORD error;
2011
2012 create_test_guid(prodcode, prod_squashed);
2013 compose_base85_guid(component, comp_base85, comp_squashed);
2014 compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
2015 usersid = get_user_sid();
2016
2017 if (is_wow64)
2018 access |= KEY_WOW64_64KEY;
2019
2020 /* NULL prodcode */
2021 SetLastError(0xdeadbeef);
2022 state = MsiQueryFeatureStateA(NULL, "feature");
2023 error = GetLastError();
2024 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2025 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2026
2027 /* empty prodcode */
2028 SetLastError(0xdeadbeef);
2029 state = MsiQueryFeatureStateA("", "feature");
2030 error = GetLastError();
2031 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2032 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2033
2034 /* garbage prodcode */
2035 SetLastError(0xdeadbeef);
2036 state = MsiQueryFeatureStateA("garbage", "feature");
2037 error = GetLastError();
2038 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2039 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2040
2041 /* guid without brackets */
2042 SetLastError(0xdeadbeef);
2043 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
2044 error = GetLastError();
2045 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2046 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2047
2048 /* guid with brackets */
2049 SetLastError(0xdeadbeef);
2050 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
2051 error = GetLastError();
2052 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2053 ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
2054 "expected ERROR_SUCCESS, got %u\n", error);
2055
2056 /* same length as guid, but random */
2057 SetLastError(0xdeadbeef);
2058 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
2059 error = GetLastError();
2060 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2061 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2062
2063 /* NULL szFeature */
2064 SetLastError(0xdeadbeef);
2065 state = MsiQueryFeatureStateA(prodcode, NULL);
2066 error = GetLastError();
2067 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2068 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2069
2070 /* empty szFeature */
2071 SetLastError(0xdeadbeef);
2072 state = MsiQueryFeatureStateA(prodcode, "");
2073 error = GetLastError();
2074 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2075 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2076 "expected ERROR_SUCCESS, got %u\n", error);
2077
2078 /* feature key does not exist yet */
2079 SetLastError(0xdeadbeef);
2080 state = MsiQueryFeatureStateA(prodcode, "feature");
2081 error = GetLastError();
2082 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, 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 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2087
2088 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
2089 lstrcatA(keypath, prod_squashed);
2090
2091 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2092 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2093
2094 /* feature key exists */
2095 SetLastError(0xdeadbeef);
2096 state = MsiQueryFeatureStateA(prodcode, "feature");
2097 error = GetLastError();
2098 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2099 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2100 "expected ERROR_SUCCESS, got %u\n", error);
2101
2102 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
2103 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2104
2105 /* feature value exists */
2106 SetLastError(0xdeadbeef);
2107 state = MsiQueryFeatureStateA(prodcode, "feature");
2108 error = GetLastError();
2109 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2110 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2111 "expected ERROR_SUCCESS, got %u\n", error);
2112
2113 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2114 lstrcatA(keypath, usersid);
2115 lstrcatA(keypath, "\\Products\\");
2116 lstrcatA(keypath, prod_squashed);
2117 lstrcatA(keypath, "\\Features");
2118
2119 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2120 if (res == ERROR_ACCESS_DENIED)
2121 {
2122 skip("Not enough rights to perform tests\n");
2123 RegDeleteKeyA(userkey, "");
2124 RegCloseKey(userkey);
2125 LocalFree(usersid);
2126 return;
2127 }
2128 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2129
2130 /* userdata features key exists */
2131 SetLastError(0xdeadbeef);
2132 state = MsiQueryFeatureStateA(prodcode, "feature");
2133 error = GetLastError();
2134 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2135 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2136 "expected ERROR_SUCCESS, got %u\n", error);
2137
2138 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2139 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2140
2141 SetLastError(0xdeadbeef);
2142 state = MsiQueryFeatureStateA(prodcode, "feature");
2143 error = GetLastError();
2144 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2145 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2146 "expected ERROR_SUCCESS, got %u\n", error);
2147
2148 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2149 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2150
2151 SetLastError(0xdeadbeef);
2152 state = MsiQueryFeatureStateA(prodcode, "feature");
2153 error = GetLastError();
2154 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2155 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2156 "expected ERROR_SUCCESS, got %u\n", error);
2157
2158 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2159 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2160
2161 SetLastError(0xdeadbeef);
2162 state = MsiQueryFeatureStateA(prodcode, "feature");
2163 error = GetLastError();
2164 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2165 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2166 "expected ERROR_SUCCESS, got %u\n", error);
2167
2168 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2169 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2170
2171 SetLastError(0xdeadbeef);
2172 state = MsiQueryFeatureStateA(prodcode, "feature");
2173 error = GetLastError();
2174 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2175 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2176 "expected ERROR_SUCCESS, got %u\n", error);
2177
2178 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2179 lstrcatA(keypath, usersid);
2180 lstrcatA(keypath, "\\Components\\");
2181 lstrcatA(keypath, comp_squashed);
2182
2183 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2184 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2185
2186 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2187 lstrcatA(keypath, usersid);
2188 lstrcatA(keypath, "\\Components\\");
2189 lstrcatA(keypath, comp_squashed2);
2190
2191 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2192 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2193
2194 SetLastError(0xdeadbeef);
2195 state = MsiQueryFeatureStateA(prodcode, "feature");
2196 error = GetLastError();
2197 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2198 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2199 "expected ERROR_SUCCESS, got %u\n", error);
2200
2201 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2202 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2203
2204 SetLastError(0xdeadbeef);
2205 state = MsiQueryFeatureStateA(prodcode, "feature");
2206 error = GetLastError();
2207 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2208 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2209 "expected ERROR_SUCCESS, got %u\n", error);
2210
2211 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2213
2214 SetLastError(0xdeadbeef);
2215 state = MsiQueryFeatureStateA(prodcode, "feature");
2216 error = GetLastError();
2217 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2218 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2219 "expected ERROR_SUCCESS, got %u\n", error);
2220
2221 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2222 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2223
2224 /* INSTALLSTATE_LOCAL */
2225 SetLastError(0xdeadbeef);
2226 state = MsiQueryFeatureStateA(prodcode, "feature");
2227 error = GetLastError();
2228 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2229 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2230 "expected ERROR_SUCCESS, got %u\n", error);
2231
2232 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2233 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2234
2235 /* INSTALLSTATE_SOURCE */
2236 SetLastError(0xdeadbeef);
2237 state = MsiQueryFeatureStateA(prodcode, "feature");
2238 error = GetLastError();
2239 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2240 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2241 "expected ERROR_SUCCESS, got %u\n", error);
2242
2243 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2244 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2245
2246 /* bad INSTALLSTATE_SOURCE */
2247 SetLastError(0xdeadbeef);
2248 state = MsiQueryFeatureStateA(prodcode, "feature");
2249 error = GetLastError();
2250 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2251 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2252 "expected ERROR_SUCCESS, got %u\n", error);
2253
2254 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2255 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2256
2257 /* INSTALLSTATE_SOURCE */
2258 SetLastError(0xdeadbeef);
2259 state = MsiQueryFeatureStateA(prodcode, "feature");
2260 error = GetLastError();
2261 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2262 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2263 "expected ERROR_SUCCESS, got %u\n", error);
2264
2265 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2266 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2267
2268 /* bad INSTALLSTATE_SOURCE */
2269 SetLastError(0xdeadbeef);
2270 state = MsiQueryFeatureStateA(prodcode, "feature");
2271 error = GetLastError();
2272 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2273 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2274 "expected ERROR_SUCCESS, got %u\n", error);
2275
2276 RegDeleteValueA(compkey, prod_squashed);
2277 RegDeleteValueA(compkey2, prod_squashed);
2278 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2279 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2280 RegDeleteValueA(localkey, "feature");
2281 RegDeleteValueA(userkey, "feature");
2282 RegDeleteKeyA(userkey, "");
2283 RegCloseKey(compkey);
2284 RegCloseKey(compkey2);
2285 RegCloseKey(localkey);
2286 RegCloseKey(userkey);
2287
2288 /* MSIINSTALLCONTEXT_USERMANAGED */
2289
2290 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2291 lstrcatA(keypath, usersid);
2292 lstrcatA(keypath, "\\Installer\\Features\\");
2293 lstrcatA(keypath, prod_squashed);
2294
2295 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2297
2298 /* feature key exists */
2299 state = MsiQueryFeatureStateA(prodcode, "feature");
2300 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2301
2302 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2303 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2304
2305 /* feature value exists */
2306 state = MsiQueryFeatureStateA(prodcode, "feature");
2307 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2308
2309 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2310 lstrcatA(keypath, usersid);
2311 lstrcatA(keypath, "\\Products\\");
2312 lstrcatA(keypath, prod_squashed);
2313 lstrcatA(keypath, "\\Features");
2314
2315 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2316 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2317
2318 /* userdata features key exists */
2319 state = MsiQueryFeatureStateA(prodcode, "feature");
2320 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2321
2322 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2323 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2324
2325 state = MsiQueryFeatureStateA(prodcode, "feature");
2326 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2327
2328 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2330
2331 state = MsiQueryFeatureStateA(prodcode, "feature");
2332 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2333
2334 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2335 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2336
2337 state = MsiQueryFeatureStateA(prodcode, "feature");
2338 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2339
2340 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2341 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2342
2343 state = MsiQueryFeatureStateA(prodcode, "feature");
2344 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2345
2346 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2347 lstrcatA(keypath, usersid);
2348 lstrcatA(keypath, "\\Components\\");
2349 lstrcatA(keypath, comp_squashed);
2350
2351 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2352 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2353
2354 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2355 lstrcatA(keypath, usersid);
2356 lstrcatA(keypath, "\\Components\\");
2357 lstrcatA(keypath, comp_squashed2);
2358
2359 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2360 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2361
2362 state = MsiQueryFeatureStateA(prodcode, "feature");
2363 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2364
2365 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2366 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2367
2368 state = MsiQueryFeatureStateA(prodcode, "feature");
2369 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2370
2371 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2372 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2373
2374 state = MsiQueryFeatureStateA(prodcode, "feature");
2375 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2376
2377 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2378 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2379
2380 state = MsiQueryFeatureStateA(prodcode, "feature");
2381 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2382
2383 RegDeleteValueA(compkey, prod_squashed);
2384 RegDeleteValueA(compkey2, prod_squashed);
2385 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2386 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2387 RegDeleteValueA(localkey, "feature");
2388 RegDeleteValueA(userkey, "feature");
2389 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2390 RegCloseKey(compkey);
2391 RegCloseKey(compkey2);
2392 RegCloseKey(localkey);
2393 RegCloseKey(userkey);
2394
2395 /* MSIINSTALLCONTEXT_MACHINE */
2396
2397 lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
2398 lstrcatA(keypath, prod_squashed);
2399
2400 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2401 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2402
2403 /* feature key exists */
2404 state = MsiQueryFeatureStateA(prodcode, "feature");
2405 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2406
2407 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2408 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2409
2410 /* feature value exists */
2411 state = MsiQueryFeatureStateA(prodcode, "feature");
2412 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2413
2414 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2415 lstrcatA(keypath, "S-1-5-18\\Products\\");
2416 lstrcatA(keypath, prod_squashed);
2417 lstrcatA(keypath, "\\Features");
2418
2419 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2421
2422 /* userdata features key exists */
2423 state = MsiQueryFeatureStateA(prodcode, "feature");
2424 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2425
2426 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2427 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2428
2429 state = MsiQueryFeatureStateA(prodcode, "feature");
2430 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2431
2432 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2433 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2434
2435 state = MsiQueryFeatureStateA(prodcode, "feature");
2436 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2437
2438 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2440
2441 state = MsiQueryFeatureStateA(prodcode, "feature");
2442 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2443
2444 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2445 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2446
2447 state = MsiQueryFeatureStateA(prodcode, "feature");
2448 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2449
2450 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2451 lstrcatA(keypath, "S-1-5-18\\Components\\");
2452 lstrcatA(keypath, comp_squashed);
2453
2454 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2455 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2456
2457 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2458 lstrcatA(keypath, "S-1-5-18\\Components\\");
2459 lstrcatA(keypath, comp_squashed2);
2460
2461 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2462 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2463
2464 state = MsiQueryFeatureStateA(prodcode, "feature");
2465 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2466
2467 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2469
2470 state = MsiQueryFeatureStateA(prodcode, "feature");
2471 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2472
2473 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2474 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2475
2476 state = MsiQueryFeatureStateA(prodcode, "feature");
2477 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2478
2479 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2481
2482 state = MsiQueryFeatureStateA(prodcode, "feature");
2483 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2484
2485 RegDeleteValueA(compkey, prod_squashed);
2486 RegDeleteValueA(compkey2, prod_squashed);
2487 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2488 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2489 RegDeleteValueA(localkey, "feature");
2490 RegDeleteValueA(userkey, "feature");
2491 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2492 RegCloseKey(compkey);
2493 RegCloseKey(compkey2);
2494 RegCloseKey(localkey);
2495 RegCloseKey(userkey);
2496 LocalFree(usersid);
2497 }
2498
2499 static void test_MsiQueryComponentState(void)
2500 {
2501 HKEY compkey, prodkey;
2502 CHAR prodcode[MAX_PATH];
2503 CHAR prod_squashed[MAX_PATH];
2504 CHAR component[MAX_PATH];
2505 CHAR comp_base85[MAX_PATH];
2506 CHAR comp_squashed[MAX_PATH];
2507 CHAR keypath[MAX_PATH];
2508 INSTALLSTATE state;
2509 LPSTR usersid;
2510 LONG res;
2511 UINT r;
2512 REGSAM access = KEY_ALL_ACCESS;
2513 DWORD error;
2514
2515 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
2516
2517 if (!pMsiQueryComponentStateA)
2518 {
2519 win_skip("MsiQueryComponentStateA not implemented\n");
2520 return;
2521 }
2522
2523 create_test_guid(prodcode, prod_squashed);
2524 compose_base85_guid(component, comp_base85, comp_squashed);
2525 usersid = get_user_sid();
2526
2527 if (is_wow64)
2528 access |= KEY_WOW64_64KEY;
2529
2530 /* NULL szProductCode */
2531 state = MAGIC_ERROR;
2532 SetLastError(0xdeadbeef);
2533 r = pMsiQueryComponentStateA(NULL, 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 /* empty szProductCode */
2540 state = MAGIC_ERROR;
2541 SetLastError(0xdeadbeef);
2542 r = pMsiQueryComponentStateA("", 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 /* random szProductCode */
2549 state = MAGIC_ERROR;
2550 SetLastError(0xdeadbeef);
2551 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2552 error = GetLastError();
2553 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, 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 /* GUID-length szProductCode */
2558 state = MAGIC_ERROR;
2559 SetLastError(0xdeadbeef);
2560 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2561 error = GetLastError();
2562 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2563 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2564 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2565
2566 /* GUID-length with brackets */
2567 state = MAGIC_ERROR;
2568 SetLastError(0xdeadbeef);
2569 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2570 error = GetLastError();
2571 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2572 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2573 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2574
2575 /* actual GUID */
2576 state = MAGIC_ERROR;
2577 SetLastError(0xdeadbeef);
2578 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2579 error = GetLastError();
2580 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2581 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2582 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2583
2584 state = MAGIC_ERROR;
2585 SetLastError(0xdeadbeef);
2586 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2587 error = GetLastError();
2588 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2589 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2590 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2591
2592 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2593 lstrcatA(keypath, prod_squashed);
2594
2595 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2596 if (res == ERROR_ACCESS_DENIED)
2597 {
2598 skip("Not enough rights to perform tests\n");
2599 LocalFree(usersid);
2600 return;
2601 }
2602 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2603
2604 state = MAGIC_ERROR;
2605 SetLastError(0xdeadbeef);
2606 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2607 error = GetLastError();
2608 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2609 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2610 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2611
2612 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2613 RegCloseKey(prodkey);
2614
2615 /* create local system product key */
2616 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
2617 lstrcatA(keypath, prod_squashed);
2618 lstrcatA(keypath, "\\InstallProperties");
2619
2620 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2621 if (res == ERROR_ACCESS_DENIED)
2622 {
2623 skip("Not enough rights to perform tests\n");
2624 LocalFree(usersid);
2625 return;
2626 }
2627 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2628
2629 /* local system product key exists */
2630 state = MAGIC_ERROR;
2631 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2632 error = GetLastError();
2633 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2634 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2635 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2636
2637 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2638 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2639
2640 /* LocalPackage value exists */
2641 state = MAGIC_ERROR;
2642 SetLastError(0xdeadbeef);
2643 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2644 error = GetLastError();
2645 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2646 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2647 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2648
2649 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
2650 lstrcatA(keypath, comp_squashed);
2651
2652 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2653 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2654
2655 /* component key exists */
2656 state = MAGIC_ERROR;
2657 SetLastError(0xdeadbeef);
2658 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2659 error = GetLastError();
2660 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2661 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2662 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2663
2664 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2666
2667 /* component\product exists */
2668 state = MAGIC_ERROR;
2669 SetLastError(0xdeadbeef);
2670 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2672 error = GetLastError();
2673 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2674 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2675 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2676
2677 /* NULL component, product exists */
2678 state = MAGIC_ERROR;
2679 SetLastError(0xdeadbeef);
2680 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
2681 error = GetLastError();
2682 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2683 ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
2684 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2685
2686 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2687 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2688
2689 /* INSTALLSTATE_LOCAL */
2690 state = MAGIC_ERROR;
2691 SetLastError(0xdeadbeef);
2692 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2693 error = GetLastError();
2694 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2695 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2696 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2697
2698 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2699 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2700
2701 /* INSTALLSTATE_SOURCE */
2702 state = MAGIC_ERROR;
2703 SetLastError(0xdeadbeef);
2704 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2705 error = GetLastError();
2706 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2707 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2708 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2709
2710 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2711 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2712
2713 /* bad INSTALLSTATE_SOURCE */
2714 state = MAGIC_ERROR;
2715 SetLastError(0xdeadbeef);
2716 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2717 error = GetLastError();
2718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2719 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2720 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2721
2722 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2723 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2724
2725 /* INSTALLSTATE_SOURCE */
2726 state = MAGIC_ERROR;
2727 SetLastError(0xdeadbeef);
2728 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2729 error = GetLastError();
2730 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2731 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2732 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2733
2734 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
2735 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2736
2737 /* registry component */
2738 state = MAGIC_ERROR;
2739 SetLastError(0xdeadbeef);
2740 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2741 error = GetLastError();
2742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2743 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2744 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2745
2746 RegDeleteValueA(prodkey, "LocalPackage");
2747 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2748 RegDeleteValueA(compkey, prod_squashed);
2749 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2750 RegCloseKey(prodkey);
2751 RegCloseKey(compkey);
2752
2753 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2754
2755 state = MAGIC_ERROR;
2756 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2757 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2758 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2759
2760 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2761 lstrcatA(keypath, prod_squashed);
2762
2763 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2764 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2765
2766 state = MAGIC_ERROR;
2767 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2768 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2769 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2770
2771 RegDeleteKeyA(prodkey, "");
2772 RegCloseKey(prodkey);
2773
2774 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2775 lstrcatA(keypath, usersid);
2776 lstrcatA(keypath, "\\Products\\");
2777 lstrcatA(keypath, prod_squashed);
2778 lstrcatA(keypath, "\\InstallProperties");
2779
2780 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2781 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2782
2783 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2784 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2785
2786 RegCloseKey(prodkey);
2787
2788 state = MAGIC_ERROR;
2789 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2790 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2791 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2792
2793 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2794 lstrcatA(keypath, usersid);
2795 lstrcatA(keypath, "\\Components\\");
2796 lstrcatA(keypath, comp_squashed);
2797
2798 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2799 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2800
2801 /* component key exists */
2802 state = MAGIC_ERROR;
2803 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2804 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2805 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2806
2807 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2808 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2809
2810 /* component\product exists */
2811 state = MAGIC_ERROR;
2812 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2813 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2814 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2815 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2816
2817 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2818 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2819
2820 state = MAGIC_ERROR;
2821 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2823 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2824
2825 /* MSIINSTALLCONTEXT_USERMANAGED */
2826
2827 state = MAGIC_ERROR;
2828 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2829 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2830 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2831
2832 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2833 lstrcatA(keypath, prod_squashed);
2834
2835 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2836 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2837
2838 state = MAGIC_ERROR;
2839 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2840 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2841 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2842
2843 RegDeleteKeyA(prodkey, "");
2844 RegCloseKey(prodkey);
2845
2846 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2847 lstrcatA(keypath, usersid);
2848 lstrcatA(keypath, "\\Installer\\Products\\");
2849 lstrcatA(keypath, prod_squashed);
2850
2851 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2852 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2853
2854 state = MAGIC_ERROR;
2855 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2856 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2857 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2858
2859 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2860 RegCloseKey(prodkey);
2861
2862 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2863 lstrcatA(keypath, usersid);
2864 lstrcatA(keypath, "\\Products\\");
2865 lstrcatA(keypath, prod_squashed);
2866 lstrcatA(keypath, "\\InstallProperties");
2867
2868 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2869 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2870
2871 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2872 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2873
2874 state = MAGIC_ERROR;
2875 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2877 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2878
2879 RegDeleteValueA(prodkey, "LocalPackage");
2880 RegDeleteValueA(prodkey, "ManagedLocalPackage");
2881 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2882 RegDeleteValueA(compkey, prod_squashed);
2883 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2884 RegCloseKey(prodkey);
2885 RegCloseKey(compkey);
2886 LocalFree(usersid);
2887 }
2888
2889 static void test_MsiGetComponentPath(void)
2890 {
2891 HKEY compkey, prodkey, installprop;
2892 CHAR prodcode[MAX_PATH];
2893 CHAR prod_squashed[MAX_PATH];
2894 CHAR component[MAX_PATH];
2895 CHAR comp_base85[MAX_PATH];
2896 CHAR comp_squashed[MAX_PATH];
2897 CHAR keypath[MAX_PATH];
2898 CHAR path[MAX_PATH];
2899 INSTALLSTATE state;
2900 LPSTR usersid;
2901 DWORD size, val;
2902 REGSAM access = KEY_ALL_ACCESS;
2903 LONG res;
2904
2905 create_test_guid(prodcode, prod_squashed);
2906 compose_base85_guid(component, comp_base85, comp_squashed);
2907 usersid = get_user_sid();
2908
2909 if (is_wow64)
2910 access |= KEY_WOW64_64KEY;
2911
2912 /* NULL szProduct */
2913 size = MAX_PATH;
2914 state = MsiGetComponentPathA(NULL, component, path, &size);
2915 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2916 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2917
2918 /* NULL szComponent */
2919 size = MAX_PATH;
2920 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
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 size = MAX_PATH;
2925 state = MsiLocateComponentA(NULL, path, &size);
2926 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2927 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2928
2929 /* NULL lpPathBuf */
2930 size = MAX_PATH;
2931 state = MsiGetComponentPathA(prodcode, component, NULL, &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 size = MAX_PATH;
2936 state = MsiLocateComponentA(component, NULL, &size);
2937 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2938 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2939
2940 /* NULL pcchBuf */
2941 size = MAX_PATH;
2942 state = MsiGetComponentPathA(prodcode, component, path, NULL);
2943 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2944 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2945
2946 size = MAX_PATH;
2947 state = MsiLocateComponentA(component, path, NULL);
2948 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2949 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2950
2951 /* all params valid */
2952 size = MAX_PATH;
2953 state = MsiGetComponentPathA(prodcode, component, path, &size);
2954 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2955 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2956
2957 size = MAX_PATH;
2958 state = MsiLocateComponentA(component, path, &size);
2959 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2960 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2961
2962 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2963 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2964 lstrcatA(keypath, comp_squashed);
2965
2966 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2967 if (res == ERROR_ACCESS_DENIED)
2968 {
2969 skip("Not enough rights to perform tests\n");
2970 LocalFree(usersid);
2971 return;
2972 }
2973 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2974
2975 /* local system component key exists */
2976 size = MAX_PATH;
2977 state = MsiGetComponentPathA(prodcode, component, path, &size);
2978 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2979 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2980
2981 size = MAX_PATH;
2982 state = MsiLocateComponentA(component, path, &size);
2983 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2984 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2985
2986 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2987 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2988
2989 /* product value 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 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3005 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3006 lstrcatA(keypath, prod_squashed);
3007 lstrcatA(keypath, "\\InstallProperties");
3008
3009 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3010 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3011
3012 val = 1;
3013 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3014 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3015
3016 /* install properties key exists */
3017 path[0] = 0;
3018 size = MAX_PATH;
3019 state = MsiGetComponentPathA(prodcode, component, path, &size);
3020 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3021 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3022 ok(size == 10, "Expected 10, got %d\n", size);
3023
3024 path[0] = 0;
3025 size = MAX_PATH;
3026 state = MsiLocateComponentA(component, path, &size);
3027 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3028 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3029 ok(size == 10, "Expected 10, got %d\n", size);
3030
3031 create_file("C:\\imapath", "C:\\imapath", 11);
3032
3033 /* file exists */
3034 path[0] = 'a';
3035 size = 0;
3036 state = MsiGetComponentPathA(prodcode, component, path, &size);
3037 ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
3038 ok(path[0] == 'a', "got %s\n", path);
3039 ok(size == 10, "Expected 10, got %d\n", size);
3040
3041 path[0] = 0;
3042 size = MAX_PATH;
3043 state = MsiGetComponentPathA(prodcode, component, path, &size);
3044 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3045 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3046 ok(size == 10, "Expected 10, got %d\n", size);
3047
3048 size = 0;
3049 path[0] = 'a';
3050 state = MsiLocateComponentA(component, path, &size);
3051 ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
3052 ok(path[0] == 'a', "got %s\n", path);
3053 ok(size == 10, "Expected 10, got %d\n", size);
3054
3055 path[0] = 0;
3056 size = MAX_PATH;
3057 state = MsiLocateComponentA(component, path, &size);
3058 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3059 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3060 ok(size == 10, "Expected 10, got %d\n", size);
3061
3062 RegDeleteValueA(compkey, prod_squashed);
3063 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3064 RegDeleteValueA(installprop, "WindowsInstaller");
3065 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3066 RegCloseKey(compkey);
3067 RegCloseKey(installprop);
3068 DeleteFileA("C:\\imapath");
3069
3070 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3071 lstrcatA(keypath, "Installer\\UserData\\");
3072 lstrcatA(keypath, usersid);
3073 lstrcatA(keypath, "\\Components\\");
3074 lstrcatA(keypath, comp_squashed);
3075
3076 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3077 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3078
3079 /* user managed component key exists */
3080 size = MAX_PATH;
3081 state = MsiGetComponentPathA(prodcode, component, path, &size);
3082 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3083 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3084
3085 size = MAX_PATH;
3086 state = MsiLocateComponentA(component, path, &size);
3087 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3088 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3089
3090 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3091 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3092
3093 /* product value exists */
3094 path[0] = 0;
3095 size = MAX_PATH;
3096 state = MsiGetComponentPathA(prodcode, component, path, &size);
3097 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3098 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3099 ok(size == 10, "Expected 10, got %d\n", size);
3100
3101 path[0] = 0;
3102 size = MAX_PATH;
3103 state = MsiLocateComponentA(component, path, &size);
3104 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3105 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3106 ok(size == 10, "Expected 10, got %d\n", size);
3107
3108 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3109 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3110 lstrcatA(keypath, prod_squashed);
3111 lstrcatA(keypath, "\\InstallProperties");
3112
3113 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3114 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3115
3116 val = 1;
3117 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3118 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3119
3120 /* install properties key exists */
3121 path[0] = 0;
3122 size = MAX_PATH;
3123 state = MsiGetComponentPathA(prodcode, component, path, &size);
3124 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3125 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3126 ok(size == 10, "Expected 10, got %d\n", size);
3127
3128 path[0] = 0;
3129 size = MAX_PATH;
3130 state = MsiLocateComponentA(component, path, &size);
3131 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3132 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3133 ok(size == 10, "Expected 10, got %d\n", size);
3134
3135 create_file("C:\\imapath", "C:\\imapath", 11);
3136
3137 /* file exists */
3138 path[0] = 0;
3139 size = MAX_PATH;
3140 state = MsiGetComponentPathA(prodcode, component, path, &size);
3141 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3142 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3143 ok(size == 10, "Expected 10, got %d\n", size);
3144
3145 path[0] = 0;
3146 size = MAX_PATH;
3147 state = MsiLocateComponentA(component, path, &size);
3148 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3149 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3150 ok(size == 10, "Expected 10, got %d\n", size);
3151
3152 RegDeleteValueA(compkey, prod_squashed);
3153 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3154 RegDeleteValueA(installprop, "WindowsInstaller");
3155 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3156 RegCloseKey(compkey);
3157 RegCloseKey(installprop);
3158 DeleteFileA("C:\\imapath");
3159
3160 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3161 lstrcatA(keypath, "Installer\\Managed\\");
3162 lstrcatA(keypath, usersid);
3163 lstrcatA(keypath, "\\Installer\\Products\\");
3164 lstrcatA(keypath, prod_squashed);
3165
3166 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3167 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3168
3169 /* user managed product key exists */
3170 size = MAX_PATH;
3171 state = MsiGetComponentPathA(prodcode, component, path, &size);
3172 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3173 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3174
3175 size = MAX_PATH;
3176 state = MsiLocateComponentA(component, path, &size);
3177 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3178 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3179
3180 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3181 lstrcatA(keypath, "Installer\\UserData\\");
3182 lstrcatA(keypath, usersid);
3183 lstrcatA(keypath, "\\Components\\");
3184 lstrcatA(keypath, comp_squashed);
3185
3186 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3187 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3188
3189 /* user managed component key exists */
3190 size = MAX_PATH;
3191 state = MsiGetComponentPathA(prodcode, component, path, &size);
3192 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3193 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3194
3195 size = MAX_PATH;
3196 state = MsiLocateComponentA(component, path, &size);
3197 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3198 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3199
3200 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3201 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3202
3203 /* product value exists */
3204 path[0] = 0;
3205 size = MAX_PATH;
3206 state = MsiGetComponentPathA(prodcode, component, path, &size);
3207 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3208 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3209 ok(size == 10, "Expected 10, got %d\n", size);
3210
3211 path[0] = 0;
3212 size = MAX_PATH;
3213 state = MsiLocateComponentA(component, path, &size);
3214 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3215 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3216 ok(size == 10, "Expected 10, got %d\n", size);
3217
3218 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3219 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3220 lstrcatA(keypath, prod_squashed);
3221 lstrcatA(keypath, "\\InstallProperties");
3222
3223 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3224 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3225
3226 val = 1;
3227 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3228 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3229
3230 /* install properties key exists */
3231 path[0] = 0;
3232 size = MAX_PATH;
3233 state = MsiGetComponentPathA(prodcode, component, path, &size);
3234 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3235 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3236 ok(size == 10, "Expected 10, got %d\n", size);
3237
3238 path[0] = 0;
3239 size = MAX_PATH;
3240 state = MsiLocateComponentA(component, path, &size);
3241 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3242 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3243 ok(size == 10, "Expected 10, got %d\n", size);
3244
3245 create_file("C:\\imapath", "C:\\imapath", 11);
3246
3247 /* file exists */
3248 path[0] = 0;
3249 size = MAX_PATH;
3250 state = MsiGetComponentPathA(prodcode, component, path, &size);
3251 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3252 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3253 ok(size == 10, "Expected 10, got %d\n", size);
3254
3255 path[0] = 0;
3256 size = MAX_PATH;
3257 state = MsiLocateComponentA(component, path, &size);
3258 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3259 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3260 ok(size == 10, "Expected 10, got %d\n", size);
3261
3262 RegDeleteValueA(compkey, prod_squashed);
3263 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3264 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3265 RegDeleteValueA(installprop, "WindowsInstaller");
3266 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3267 RegCloseKey(prodkey);
3268 RegCloseKey(compkey);
3269 RegCloseKey(installprop);
3270 DeleteFileA("C:\\imapath");
3271
3272 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3273 lstrcatA(keypath, prod_squashed);
3274
3275 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3276 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3277
3278 /* user unmanaged product key exists */
3279 size = MAX_PATH;
3280 state = MsiGetComponentPathA(prodcode, component, path, &size);
3281 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3282 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3283
3284 size = MAX_PATH;
3285 state = MsiLocateComponentA(component, path, &size);
3286 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3287 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3288
3289 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3290 lstrcatA(keypath, "Installer\\UserData\\");
3291 lstrcatA(keypath, usersid);
3292 lstrcatA(keypath, "\\Components\\");
3293 lstrcatA(keypath, comp_squashed);
3294
3295 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298 /* user unmanaged component key exists */
3299 size = MAX_PATH;
3300 state = MsiGetComponentPathA(prodcode, component, path, &size);
3301 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3302 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3303
3304 size = MAX_PATH;
3305 state = MsiLocateComponentA(component, path, &size);
3306 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3307 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3308
3309 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3310 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3311
3312 /* product value exists */
3313 path[0] = 0;
3314 size = MAX_PATH;
3315 state = MsiGetComponentPathA(prodcode, component, path, &size);
3316 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3317 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3318 ok(size == 10, "Expected 10, got %d\n", size);
3319
3320 path[0] = 0;
3321 size = MAX_PATH;
3322 state = MsiLocateComponentA(component, path, &size);
3323 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3324 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3325 ok(size == 10, "Expected 10, got %d\n", size);
3326
3327 create_file("C:\\imapath", "C:\\imapath", 11);
3328
3329 /* file exists */
3330 path[0] = 0;
3331 size = MAX_PATH;
3332 state = MsiGetComponentPathA(prodcode, component, path, &size);
3333 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3334 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3335 ok(size == 10, "Expected 10, got %d\n", size);
3336
3337 path[0] = 0;
3338 size = MAX_PATH;
3339 state = MsiLocateComponentA(component, path, &size);
3340 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3341 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3342 ok(size == 10, "Expected 10, got %d\n", size);
3343
3344 RegDeleteValueA(compkey, prod_squashed);
3345 RegDeleteKeyA(prodkey, "");
3346 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3347 RegCloseKey(prodkey);
3348 RegCloseKey(compkey);
3349 DeleteFileA("C:\\imapath");
3350
3351 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3352 lstrcatA(keypath, prod_squashed);
3353
3354 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3356
3357 /* local classes product key exists */
3358 size = MAX_PATH;
3359 state = MsiGetComponentPathA(prodcode, component, path, &size);
3360 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3361 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3362
3363 size = MAX_PATH;
3364 state = MsiLocateComponentA(component, path, &size);
3365 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3366 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3367
3368 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3369 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3370 lstrcatA(keypath, comp_squashed);
3371
3372 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3373 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3374
3375 /* local user component key exists */
3376 size = MAX_PATH;
3377 state = MsiGetComponentPathA(prodcode, component, path, &size);
3378 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3379 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3380
3381 size = MAX_PATH;
3382 state = MsiLocateComponentA(component, path, &size);
3383 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3384 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3385
3386 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3387 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3388
3389 /* product value exists */
3390 path[0] = 0;
3391 size = MAX_PATH;
3392 state = MsiGetComponentPathA(prodcode, component, path, &size);
3393 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3394 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3395 ok(size == 10, "Expected 10, got %d\n", size);
3396
3397 path[0] = 0;
3398 size = MAX_PATH;
3399 state = MsiLocateComponentA(component, path, &size);
3400 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3401 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3402 ok(size == 10, "Expected 10, got %d\n", size);
3403
3404 create_file("C:\\imapath", "C:\\imapath", 11);
3405
3406 /* file exists */
3407 path[0] = 0;
3408 size = MAX_PATH;
3409 state = MsiGetComponentPathA(prodcode, component, path, &size);
3410 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3411 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3412 ok(size == 10, "Expected 10, got %d\n", size);
3413
3414 path[0] = 0;
3415 size = MAX_PATH;
3416 state = MsiLocateComponentA(component, path, &size);
3417 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3418 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3419 ok(size == 10, "Expected 10, got %d\n", size);
3420
3421 RegDeleteValueA(compkey, prod_squashed);
3422 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3423 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3424 RegCloseKey(prodkey);
3425 RegCloseKey(compkey);
3426 DeleteFileA("C:\\imapath");
3427 LocalFree(usersid);
3428 }
3429
3430 static void test_MsiProvideComponent(void)
3431 {
3432 static const WCHAR sourcedirW[] =
3433 {'s','o','u','r','c','e','d','i','r',0};
3434 static const WCHAR productW[] =
3435 {'{','3','8','8','4','7','3','3','8','-','1','B','B','C','-','4','1','0','4','-',
3436 '8','1','A','C','-','2','F','A','A','C','7','E','C','D','D','C','D','}',0};
3437 static const WCHAR componentW[] =
3438 {'{','D','D','4','2','2','F','9','2','-','3','E','D','8','-','4','9','B','5','-',
3439 'A','0','B','7','-','F','2','6','6','F','9','8','3','5','7','D','F','}',0};
3440 INSTALLSTATE state;
3441 char buf[0x100];
3442 WCHAR bufW[0x100];
3443 DWORD len, len2;
3444 UINT r;
3445
3446 if (is_process_limited())
3447 {
3448 skip("process is limited\n");
3449 return;
3450 }
3451
3452 create_test_files();
3453 create_file("msitest\\sourcedir.txt", "msitest\\sourcedir.txt", 1000);
3454 create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
3455
3456 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3457
3458 buf[0] = 0;
3459 len = sizeof(buf);
3460 r = pMsiProvideComponentA("{90120000-0070-0000-0000-4000000FF1CE}",
3461 "{17961602-C4E2-482E-800A-DF6E627549CF}",
3462 "ProductFiles", INSTALLMODE_NODETECTION, buf, &len);
3463 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
3464
3465 r = MsiInstallProductA(msifile, NULL);
3466 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3467
3468 state = MsiQueryFeatureStateA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir");
3469 ok(state == INSTALLSTATE_LOCAL, "got %d\n", state);
3470
3471 buf[0] = 0;
3472 len = sizeof(buf);
3473 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3474 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3475 INSTALLMODE_NODETECTION, buf, &len);
3476 ok(r == ERROR_SUCCESS, "got %u\n", r);
3477 ok(buf[0], "empty path\n");
3478 ok(len == lstrlenA(buf), "got %u\n", len);
3479
3480 len2 = 0;
3481 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3482 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3483 INSTALLMODE_NODETECTION, NULL, &len2);
3484 ok(r == ERROR_SUCCESS, "got %u\n", r);
3485 ok(len2 == len, "got %u\n", len2);
3486
3487 len2 = 0;
3488 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3489 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3490 INSTALLMODE_NODETECTION, buf, &len2);
3491 ok(r == ERROR_MORE_DATA, "got %u\n", r);
3492 ok(len2 == len, "got %u\n", len2);
3493
3494 /* wide version */
3495
3496 bufW[0] = 0;
3497 len = sizeof(buf);
3498 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3499 INSTALLMODE_NODETECTION, bufW, &len);
3500 ok(r == ERROR_SUCCESS, "got %u\n", r);
3501 ok(bufW[0], "empty path\n");
3502 ok(len == lstrlenW(bufW), "got %u\n", len);
3503
3504 len2 = 0;
3505 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3506 INSTALLMODE_NODETECTION, NULL, &len2);
3507 ok(r == ERROR_SUCCESS, "got %u\n", r);
3508 ok(len2 == len, "got %u\n", len2);
3509
3510 len2 = 0;
3511 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3512 INSTALLMODE_NODETECTION, bufW, &len2);
3513 ok(r == ERROR_MORE_DATA, "got %u\n", r);
3514 ok(len2 == len, "got %u\n", len2);
3515
3516 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3517 ok(r == ERROR_SUCCESS, "got %u\n", r);
3518
3519 DeleteFileA("msitest\\sourcedir.txt");
3520 delete_test_files();
3521 DeleteFileA(msifile);
3522 }
3523
3524 static void test_MsiProvideQualifiedComponentEx(void)
3525 {
3526 UINT r;
3527 INSTALLSTATE state;
3528 char comp[39], comp_squashed[33], comp2[39], comp2_base85[21], comp2_squashed[33];
3529 char prod[39], prod_base85[21], prod_squashed[33];
3530 char desc[MAX_PATH], buf[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH];
3531 DWORD len = sizeof(buf);
3532 REGSAM access = KEY_ALL_ACCESS;
3533 HKEY hkey, hkey2, hkey3, hkey4, hkey5;
3534 LONG res;
3535
3536 if (is_process_limited())
3537 {
3538 skip( "process is limited\n" );
3539 return;
3540 }
3541
3542 create_test_guid( comp, comp_squashed );
3543 compose_base85_guid( comp2, comp2_base85, comp2_squashed );
3544 compose_base85_guid( prod, prod_base85, prod_squashed );
3545
3546 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3547 ok( r == ERROR_UNKNOWN_COMPONENT, "got %u\n", r );
3548
3549 lstrcpyA( keypath, "Software\\Classes\\Installer\\Components\\" );
3550 lstrcatA( keypath, comp_squashed );
3551
3552 if (is_wow64) access |= KEY_WOW64_64KEY;
3553 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey, NULL );
3554 ok( res == ERROR_SUCCESS, "got %d\n", res );
3555
3556 lstrcpyA( desc, prod_base85 );
3557 memcpy( desc + lstrlenA(desc), "feature<\0", sizeof("feature<\0") );
3558 res = RegSetValueExA( hkey, "qualifier", 0, REG_MULTI_SZ, (const BYTE *)desc,
3559 lstrlenA(prod_base85) + sizeof("feature<\0") );
3560 ok( res == ERROR_SUCCESS, "got %d\n", res );
3561
3562 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3563 ok( r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r );
3564
3565 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, NULL, 0, 0, buf, &len );
3566 ok( r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r );
3567
3568 state = MsiQueryProductStateA( prod );
3569 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3570
3571 lstrcpyA( keypath, "Software\\Classes\\Installer\\Products\\" );
3572 lstrcatA( keypath, prod_squashed );
3573
3574 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey2, NULL );
3575 ok( res == ERROR_SUCCESS, "got %d\n", res );
3576
3577 state = MsiQueryProductStateA( prod );
3578 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3579
3580 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3581 todo_wine ok( r == ERROR_UNKNOWN_FEATURE, "got %u\n", r );
3582
3583 lstrcpyA( keypath, "Software\\Classes\\Installer\\Features\\" );
3584 lstrcatA( keypath, prod_squashed );
3585
3586 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey3, NULL );
3587 ok( res == ERROR_SUCCESS, "got %d\n", res );
3588
3589 state = MsiQueryFeatureStateA( prod, "feature" );
3590 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3591
3592 res = RegSetValueExA( hkey3, "feature", 0, REG_SZ, (const BYTE *)"", 1 );
3593 ok( res == ERROR_SUCCESS, "got %d\n", res );
3594
3595 state = MsiQueryFeatureStateA( prod, "feature" );
3596 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3597
3598 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3599 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3600
3601 len = sizeof(buf);
3602 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, NULL, 0, 0, buf, &len );
3603 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3604
3605 lstrcpyA( keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\" );
3606 lstrcatA( keypath, prod_squashed );
3607 lstrcatA( keypath, "\\Features" );
3608
3609 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey4, NULL );
3610 ok( res == ERROR_SUCCESS, "got %d\n", res );
3611
3612 res = RegSetValueExA( hkey4, "feature", 0, REG_SZ, (const BYTE *)comp2_base85, sizeof(comp2_base85) );
3613 ok( res == ERROR_SUCCESS, "got %d\n", res );
3614
3615 state = MsiQueryFeatureStateA( prod, "feature" );
3616 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3617
3618 lstrcpyA( keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\" );
3619 lstrcatA( keypath, comp2_squashed );
3620
3621 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey5, NULL );
3622 ok( res == ERROR_SUCCESS, "got %d\n", res );
3623
3624 res = RegSetValueExA( hkey5, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\nosuchfile", sizeof("c:\\nosuchfile") );
3625 ok( res == ERROR_SUCCESS, "got %d\n", res );
3626
3627 state = MsiQueryFeatureStateA( prod, "feature" );
3628 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3629
3630 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3631 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3632
3633 GetCurrentDirectoryA( MAX_PATH, path );
3634 lstrcatA( path, "\\msitest" );
3635 CreateDirectoryA( path, NULL );
3636 lstrcatA( path, "\\test.txt" );
3637 create_file( path, "test", 100 );
3638
3639 res = RegSetValueExA( hkey5, prod_squashed, 0, REG_SZ, (const BYTE *)path, lstrlenA(path) + 1 );
3640 ok( res == ERROR_SUCCESS, "got %d\n", res );
3641
3642 buf[0] = 0;
3643 len = sizeof(buf);
3644 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3645 ok( r == ERROR_SUCCESS, "got %u\n", r );
3646 ok( len == lstrlenA(path), "got %u\n", len );
3647 ok( !lstrcmpA( path, buf ), "got '%s'\n", buf );
3648
3649 DeleteFileA( "msitest\\text.txt" );
3650 RemoveDirectoryA( "msitest" );
3651
3652 delete_key( hkey5, "", access & KEY_WOW64_64KEY );
3653 RegCloseKey( hkey5 );
3654 delete_key( hkey4, "", access & KEY_WOW64_64KEY );
3655 RegCloseKey( hkey4 );
3656 delete_key( hkey3, "", access & KEY_WOW64_64KEY );
3657 RegCloseKey( hkey3 );
3658 delete_key( hkey2, "", access & KEY_WOW64_64KEY );
3659 RegCloseKey( hkey2 );
3660 delete_key( hkey, "", access & KEY_WOW64_64KEY );
3661 RegCloseKey( hkey );
3662 }
3663
3664 static void test_MsiGetProductCode(void)
3665 {
3666 HKEY compkey, prodkey;
3667 CHAR prodcode[MAX_PATH];
3668 CHAR prod_squashed[MAX_PATH];
3669 CHAR prodcode2[MAX_PATH];
3670 CHAR prod2_squashed[MAX_PATH];
3671 CHAR component[MAX_PATH];
3672 CHAR comp_base85[MAX_PATH];
3673 CHAR comp_squashed[MAX_PATH];
3674 CHAR keypath[MAX_PATH];
3675 CHAR product[MAX_PATH];
3676 LPSTR usersid;
3677 LONG res;
3678 UINT r;
3679 REGSAM access = KEY_ALL_ACCESS;
3680
3681 create_test_guid(prodcode, prod_squashed);
3682 create_test_guid(prodcode2, prod2_squashed);
3683 compose_base85_guid(component, comp_base85, comp_squashed);
3684 usersid = get_user_sid();
3685
3686 if (is_wow64)
3687 access |= KEY_WOW64_64KEY;
3688
3689 /* szComponent is NULL */
3690 lstrcpyA(product, "prod");
3691 r = MsiGetProductCodeA(NULL, product);
3692 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3693 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3694
3695 /* szComponent is empty */
3696 lstrcpyA(product, "prod");
3697 r = MsiGetProductCodeA("", product);
3698 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3699 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3700
3701 /* garbage szComponent */
3702 lstrcpyA(product, "prod");
3703 r = MsiGetProductCodeA("garbage", product);
3704 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3705 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3706
3707 /* guid without brackets */
3708 lstrcpyA(product, "prod");
3709 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
3710 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3711 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3712
3713 /* guid with brackets */
3714 lstrcpyA(product, "prod");
3715 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
3716 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3717 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3718
3719 /* same length as guid, but random */
3720 lstrcpyA(product, "prod");
3721 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
3722 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3723 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3724
3725 /* all params correct, szComponent not published */
3726 lstrcpyA(product, "prod");
3727 r = MsiGetProductCodeA(component, product);
3728 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3729 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3730
3731 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3732 lstrcatA(keypath, "Installer\\UserData\\");
3733 lstrcatA(keypath, usersid);
3734 lstrcatA(keypath, "\\Components\\");
3735 lstrcatA(keypath, comp_squashed);
3736
3737 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3738 if (res == ERROR_ACCESS_DENIED)
3739 {
3740 skip("Not enough rights to perform tests\n");
3741 LocalFree(usersid);
3742 return;
3743 }
3744 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3745
3746 /* user unmanaged component key exists */
3747 lstrcpyA(product, "prod");
3748 r = MsiGetProductCodeA(component, product);
3749 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3750 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3751
3752 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3753 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3754
3755 /* product value exists */
3756 lstrcpyA(product, "prod");
3757 r = MsiGetProductCodeA(component, product);
3758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3759 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3760
3761 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3762 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3763
3764 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3765 lstrcatA(keypath, "Installer\\Managed\\");
3766 lstrcatA(keypath, usersid);
3767 lstrcatA(keypath, "\\Installer\\Products\\");
3768 lstrcatA(keypath, prod_squashed);
3769
3770 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3771 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3772
3773 /* user managed product key of first product exists */
3774 lstrcpyA(product, "prod");
3775 r = MsiGetProductCodeA(component, product);
3776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3777 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3778
3779 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3780 RegCloseKey(prodkey);
3781
3782 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3783 lstrcatA(keypath, prod_squashed);
3784
3785 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3787
3788 /* user unmanaged product key exists */
3789 lstrcpyA(product, "prod");
3790 r = MsiGetProductCodeA(component, product);
3791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3792 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3793
3794 RegDeleteKeyA(prodkey, "");
3795 RegCloseKey(prodkey);
3796
3797 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3798 lstrcatA(keypath, prod_squashed);
3799
3800 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3802
3803 /* local classes product key exists */
3804 lstrcpyA(product, "prod");
3805 r = MsiGetProductCodeA(component, 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 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3810 RegCloseKey(prodkey);
3811
3812 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3813 lstrcatA(keypath, "Installer\\Managed\\");
3814 lstrcatA(keypath, usersid);
3815 lstrcatA(keypath, "\\Installer\\Products\\");
3816 lstrcatA(keypath, prod2_squashed);
3817
3818 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3819 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3820
3821 /* user managed product key of second product exists */
3822 lstrcpyA(product, "prod");
3823 r = MsiGetProductCodeA(component, product);
3824 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3825 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3826
3827 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3828 RegCloseKey(prodkey);
3829 RegDeleteValueA(compkey, prod_squashed);
3830 RegDeleteValueA(compkey, prod2_squashed);
3831 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3832 RegCloseKey(compkey);
3833
3834 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3835 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3836 lstrcatA(keypath, comp_squashed);
3837
3838 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3839 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3840
3841 /* local user component key exists */
3842 lstrcpyA(product, "prod");
3843 r = MsiGetProductCodeA(component, product);
3844 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3845 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3846
3847 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3848 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3849
3850 /* product value exists */
3851 lstrcpyA(product, "prod");
3852 r = MsiGetProductCodeA(component, product);
3853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3854 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3855
3856 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3857 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3858
3859 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3860 lstrcatA(keypath, "Installer\\Managed\\");
3861 lstrcatA(keypath, usersid);
3862 lstrcatA(keypath, "\\Installer\\Products\\");
3863 lstrcatA(keypath, prod_squashed);
3864
3865 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3866 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3867
3868 /* user managed product key of first product exists */
3869 lstrcpyA(product, "prod");
3870 r = MsiGetProductCodeA(component, product);
3871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3872 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3873
3874 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3875 RegCloseKey(prodkey);
3876
3877 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3878 lstrcatA(keypath, prod_squashed);
3879
3880 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3881 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3882
3883 /* user unmanaged product key exists */
3884 lstrcpyA(product, "prod");
3885 r = MsiGetProductCodeA(component, product);
3886 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3887 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3888
3889 RegDeleteKeyA(prodkey, "");
3890 RegCloseKey(prodkey);
3891
3892 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3893 lstrcatA(keypath, prod_squashed);
3894
3895 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3896 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3897
3898 /* local classes product key exists */
3899 lstrcpyA(product, "prod");
3900 r = MsiGetProductCodeA(component, product);
3901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3902 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3903
3904 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3905 RegCloseKey(prodkey);
3906
3907 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3908 lstrcatA(keypath, "Installer\\Managed\\");
3909 lstrcatA(keypath, usersid);
3910 lstrcatA(keypath, "\\Installer\\Products\\");
3911 lstrcatA(keypath, prod2_squashed);
3912
3913 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3914 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3915
3916 /* user managed product key of second product exists */
3917 lstrcpyA(product, "prod");
3918 r = MsiGetProductCodeA(component, product);
3919 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3920 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3921
3922 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3923 RegCloseKey(prodkey);
3924 RegDeleteValueA(compkey, prod_squashed);
3925 RegDeleteValueA(compkey, prod2_squashed);
3926 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3927 RegCloseKey(compkey);
3928 LocalFree(usersid);
3929 }
3930
3931 static void test_MsiEnumClients(void)
3932 {
3933 HKEY compkey;
3934 CHAR prodcode[MAX_PATH];
3935 CHAR prod_squashed[MAX_PATH];
3936 CHAR prodcode2[MAX_PATH];
3937 CHAR prod2_squashed[MAX_PATH];
3938 CHAR component[MAX_PATH];
3939 CHAR comp_base85[MAX_PATH];
3940 CHAR comp_squashed[MAX_PATH];
3941 CHAR product[MAX_PATH];
3942 CHAR keypath[MAX_PATH];
3943 LPSTR usersid;
3944 LONG res;
3945 UINT r;
3946 REGSAM access = KEY_ALL_ACCESS;
3947
3948 create_test_guid(prodcode, prod_squashed);
3949 create_test_guid(prodcode2, prod2_squashed);
3950 compose_base85_guid(component, comp_base85, comp_squashed);
3951 usersid = get_user_sid();
3952
3953 if (is_wow64)
3954 access |= KEY_WOW64_64KEY;
3955
3956 /* NULL szComponent */
3957 product[0] = '\0';
3958 r = MsiEnumClientsA(NULL, 0, product);
3959 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3960 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3961
3962 /* empty szComponent */
3963 product[0] = '\0';
3964 r = MsiEnumClientsA("", 0, product);
3965 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3966 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3967
3968 /* NULL lpProductBuf */
3969 r = MsiEnumClientsA(component, 0, NULL);
3970 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3971
3972 /* all params correct, component missing */
3973 product[0] = '\0';
3974 r = MsiEnumClientsA(component, 0, product);
3975 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3976 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3977
3978 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3979 lstrcatA(keypath, "Installer\\UserData\\");
3980 lstrcatA(keypath, usersid);
3981 lstrcatA(keypath, "\\Components\\");
3982 lstrcatA(keypath, comp_squashed);
3983
3984 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3985 if (res == ERROR_ACCESS_DENIED)
3986 {
3987 skip("Not enough rights to perform tests\n");
3988 LocalFree(usersid);
3989 return;
3990 }
3991 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3992
3993 /* user unmanaged component key exists */
3994 product[0] = '\0';
3995 r = MsiEnumClientsA(component, 0, product);
3996 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3997 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3998
3999 /* index > 0, no products exist */
4000 product[0] = '\0';
4001 r = MsiEnumClientsA(component, 1, product);
4002 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4003 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4004
4005 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
4006 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4007
4008 /* product value exists */
4009 r = MsiEnumClientsA(component, 0, product);
4010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4011 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4012
4013 /* try index 0 again */
4014 product[0] = '\0';
4015 r = MsiEnumClientsA(component, 0, product);
4016 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4017 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4018
4019 /* try index 1, second product value does not exist */
4020 product[0] = '\0';
4021 r = MsiEnumClientsA(component, 1, product);
4022 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4023 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4024
4025 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
4026 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4027
4028 /* try index 1, second product value does exist */
4029 product[0] = '\0';
4030 r = MsiEnumClientsA(component, 1, product);
4031 todo_wine
4032 {
4033 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4034 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4035 }
4036
4037 /* start the enumeration over */
4038 product[0] = '\0';
4039 r = MsiEnumClientsA(component, 0, product);
4040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4041 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4042 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4043
4044 /* correctly query second product */
4045 product[0] = '\0';
4046 r = MsiEnumClientsA(component, 1, product);
4047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4048 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4049 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4050
4051 RegDeleteValueA(compkey, prod_squashed);
4052 RegDeleteValueA(compkey, prod2_squashed);
4053 delete_key(compkey, "", access & KEY_WOW64_64KEY);
4054 RegCloseKey(compkey);
4055
4056 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4057 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
4058 lstrcatA(keypath, comp_squashed);
4059
4060 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
4061 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4062
4063 /* user local component key exists */
4064 product[0] = '\0';
4065 r = MsiEnumClientsA(component, 0, product);
4066 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4067 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4068
4069 /* index > 0, no products exist */
4070 product[0] = '\0';
4071 r = MsiEnumClientsA(component, 1, product);
4072 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4073 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4074
4075 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
4076 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4077
4078 /* product value exists */
4079 product[0] = '\0';
4080 r = MsiEnumClientsA(component, 0, product);
4081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4082 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4083
4084 /* try index 0 again */
4085 product[0] = '\0';
4086 r = MsiEnumClientsA(component, 0, product);
4087 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4088
4089 /* try index 1, second product value does not exist */
4090 product[0] = '\0';
4091 r = MsiEnumClientsA(component, 1, product);
4092 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4093 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4094
4095 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
4096 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4097
4098 /* try index 1, second product value does exist */
4099 product[0] = '\0';
4100 r = MsiEnumClientsA(component, 1, product);
4101 todo_wine
4102 {
4103 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4104 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4105 }
4106
4107 /* start the enumeration over */
4108 product[0] = '\0';
4109 r = MsiEnumClientsA(component, 0, product);
4110 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4111 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4112 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4113
4114 /* correctly query second product */
4115 product[0] = '\0';
4116 r = MsiEnumClientsA(component, 1, product);
4117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4118 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4119 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4120
4121 RegDeleteValueA(compkey, prod_squashed);
4122 RegDeleteValueA(compkey, prod2_squashed);
4123 delete_key(compkey, "", access & KEY_WOW64_64KEY);
4124 RegCloseKey(compkey);
4125 LocalFree(usersid);
4126 }
4127
4128 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
4129 LPSTR *langcheck, LPDWORD langchecksz)
4130 {
4131 LPSTR version;
4132 VS_FIXEDFILEINFO *ffi;
4133 DWORD size = GetFileVersionInfoSizeA(path, NULL);
4134 USHORT *lang;
4135
4136 version = HeapAlloc(GetProcessHeap(), 0, size);
4137 GetFileVersionInfoA(path, 0, size, version);
4138
4139 VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
4140 *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
4141 sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
4142 LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
4143 LOWORD(ffi->dwFileVersionLS));
4144 *verchecksz = lstrlenA(*vercheck);
4145
4146 VerQueryValueA(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
4147 *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
4148 sprintf(*langcheck, "%d", *lang);
4149 *langchecksz = lstrlenA(*langcheck);
4150
4151 HeapFree(GetProcessHeap(), 0, version);
4152 }
4153
4154 static void test_MsiGetFileVersion(void)
4155 {
4156 UINT r;
4157 DWORD versz, langsz;
4158 char version[MAX_PATH];
4159 char lang[MAX_PATH];
4160 char path[MAX_PATH];
4161 LPSTR vercheck, langcheck;
4162 DWORD verchecksz, langchecksz;
4163
4164 /* NULL szFilePath */
4165 r = MsiGetFileVersionA(NULL, NULL, NULL, NULL, NULL);
4166 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4167
4168 versz = MAX_PATH;
4169 langsz = MAX_PATH;
4170 lstrcpyA(version, "version");
4171 lstrcpyA(lang, "lang");
4172 r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
4173 ok(r == ERROR_INVALID_PARAMETER,
4174 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4175 ok(!lstrcmpA(version, "version"),
4176 "Expected version to be unchanged, got %s\n", version);
4177 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4178 ok(!lstrcmpA(lang, "lang"),
4179 "Expected lang to be unchanged, got %s\n", lang);
4180 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4181
4182 /* empty szFilePath */
4183 r = MsiGetFileVersionA("", NULL, NULL, NULL, NULL);
4184 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4185
4186 versz = MAX_PATH;
4187 langsz = MAX_PATH;
4188 lstrcpyA(version, "version");
4189 lstrcpyA(lang, "lang");
4190 r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
4191 ok(r == ERROR_FILE_NOT_FOUND,
4192 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4193 ok(!lstrcmpA(version, "version"),
4194 "Expected version to be unchanged, got %s\n", version);
4195 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4196 ok(!lstrcmpA(lang, "lang"),
4197 "Expected lang to be unchanged, got %s\n", lang);
4198 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4199
4200 /* nonexistent szFilePath */
4201 versz = MAX_PATH;
4202 langsz = MAX_PATH;
4203 lstrcpyA(version, "version");
4204 lstrcpyA(lang, "lang");
4205 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4206 ok(r == ERROR_FILE_NOT_FOUND,
4207 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4208 ok(!lstrcmpA(version, "version"),
4209 "Expected version to be unchanged, got %s\n", version);
4210 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4211 ok(!lstrcmpA(lang, "lang"),
4212 "Expected lang to be unchanged, got %s\n", lang);
4213 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4214
4215 /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
4216 versz = MAX_PATH;
4217 langsz = MAX_PATH;
4218 lstrcpyA(version, "version");
4219 lstrcpyA(lang, "lang");
4220 r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
4221 ok(r == ERROR_INVALID_PARAMETER,
4222 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4223 ok(!lstrcmpA(version, "version"),
4224 "Expected version to be unchanged, got %s\n", version);
4225 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4226 ok(!lstrcmpA(lang, "lang"),
4227 "Expected lang to be unchanged, got %s\n", lang);
4228 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4229
4230 /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
4231 versz = MAX_PATH;
4232 langsz = MAX_PATH;
4233 lstrcpyA(version, "version");
4234 lstrcpyA(lang, "lang");
4235 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
4236 ok(r == ERROR_INVALID_PARAMETER,
4237 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4238 ok(!lstrcmpA(version, "version"),
4239 "Expected version to be unchanged, got %s\n", version);
4240 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4241 ok(!lstrcmpA(lang, "lang"),
4242 "Expected lang to be unchanged, got %s\n", lang);
4243 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4244
4245 /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
4246 versz = 0;
4247 langsz = MAX_PATH;
4248 lstrcpyA(version, "version");
4249 lstrcpyA(lang, "lang");
4250 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4251 ok(r == ERROR_FILE_NOT_FOUND,
4252 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4253 ok(!lstrcmpA(version, "version"),
4254 "Expected version to be unchanged, got %s\n", version);
4255 ok(versz == 0, "Expected 0, got %d\n", versz);
4256 ok(!lstrcmpA(lang, "lang"),
4257 "Expected lang to be unchanged, got %s\n", lang);
4258 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4259
4260 /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
4261 versz = MAX_PATH;
4262 langsz = 0;
4263 lstrcpyA(version, "version");
4264 lstrcpyA(lang, "lang");
4265 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4266 ok(r == ERROR_FILE_NOT_FOUND,
4267 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4268 ok(!lstrcmpA(version, "version"),
4269 "Expected version to be unchanged, got %s\n", version);
4270 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4271 ok(!lstrcmpA(lang, "lang"),
4272 "Expected lang to be unchanged, got %s\n", lang);
4273 ok(langsz == 0, "Expected 0, got %d\n", langsz);
4274
4275 /* nonexistent szFilePath, rest NULL */
4276 r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
4277 ok(r == ERROR_FILE_NOT_FOUND,
4278 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4279
4280 create_file("ver.txt", "ver.txt", 20);
4281
4282 /* file exists, no version information */
4283 r = MsiGetFileVersionA("ver.txt", NULL, NULL, NULL, NULL);
4284 ok(r == ERROR_FILE_INVALID, "Expected ERROR_FILE_INVALID, got %d\n", r);
4285
4286 versz = MAX_PATH;
4287 langsz = MAX_PATH;
4288 lstrcpyA(version, "version");
4289 lstrcpyA(lang, "lang");
4290 r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
4291 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4292 ok(!lstrcmpA(version, "version"),
4293 "Expected version to be unchanged, got %s\n", version);
4294 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4295 ok(!lstrcmpA(lang, "lang"),
4296 "Expected lang to be unchanged, got %s\n", lang);
4297 ok(r == ERROR_FILE_INVALID,
4298 "Expected ERROR_FILE_INVALID, got %d\n", r);
4299
4300 DeleteFileA("ver.txt");
4301
4302 /* relative path, has version information */
4303 versz = MAX_PATH;
4304 langsz = MAX_PATH;
4305 lstrcpyA(version, "version");
4306 lstrcpyA(lang, "lang");
4307 r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
4308 todo_wine
4309 {
4310 ok(r == ERROR_FILE_NOT_FOUND,
4311 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4312 ok(!lstrcmpA(version, "version"),
4313 "Expected version to be unchanged, got %s\n", version);
4314 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4315 ok(!lstrcmpA(lang, "lang"),
4316 "Expected lang to be unchanged, got %s\n", lang);
4317 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4318 }
4319
4320 GetSystemDirectoryA(path, MAX_PATH);
4321 lstrcatA(path, "\\kernel32.dll");
4322
4323 get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
4324
4325 /* absolute path, has version information */
4326 versz = MAX_PATH;
4327 langsz = MAX_PATH;
4328 lstrcpyA(version, "version");
4329 lstrcpyA(lang, "lang");
4330 r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
4331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4332 if (langchecksz && !langsz)
4333 {
4334 win_skip("broken MsiGetFileVersionA detected\n");
4335 HeapFree(GetProcessHeap(), 0, vercheck);
4336 HeapFree(GetProcessHeap(), 0, langcheck);
4337 return;
4338 }
4339 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4340 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4341 ok(!lstrcmpA(version, vercheck),
4342 "Expected %s, got %s\n", vercheck, version);
4343
4344 /* only check version */
4345 versz = MAX_PATH;
4346 lstrcpyA(version, "version");
4347 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4349 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4350 ok(!lstrcmpA(version, vercheck),
4351 "Expected %s, got %s\n", vercheck, version);
4352
4353 /* only check language */
4354 langsz = MAX_PATH;
4355 lstrcpyA(lang, "lang");
4356 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4358 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4359
4360 /* check neither version nor language */
4361 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4362 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4363
4364 /* get pcchVersionBuf */
4365 versz = MAX_PATH;
4366 r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
4367 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4368 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4369
4370 /* get pcchLangBuf */
4371 langsz = MAX_PATH;
4372 r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
4373 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4374 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4375
4376 /* pcchVersionBuf not big enough */
4377 versz = 5;
4378 lstrcpyA(version, "version");
4379 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4380 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4381 ok(!strncmp(version, vercheck, 4),
4382 "Expected first 4 characters of \"%s\", got \"%s\"\n", vercheck, version);
4383 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4384
4385 /* pcchLangBuf not big enough */
4386 langsz = 4;
4387 lstrcpyA(lang, "lang");
4388 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4389 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4390 ok(lstrcmpA(lang, "lang"), "lang not set\n");
4391 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4392
4393 /* pcchVersionBuf big enough, pcchLangBuf not big enough */
4394 versz = MAX_PATH;
4395 langsz = 0;
4396 lstrcpyA(version, "version");
4397 r = MsiGetFileVersionA(path, version, &versz, NULL, &langsz);
4398 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4399 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4400 ok(!lstrcmpA(version, vercheck), "Expected \"%s\", got \"%s\"\n", vercheck, version);
4401 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4402
4403 /* pcchVersionBuf not big enough, pcchLangBuf big enough */
4404 versz = 5;
4405 langsz = MAX_PATH;
4406 lstrcpyA(lang, "lang");
4407 r = MsiGetFileVersionA(path, NULL, &versz, lang, &langsz);
4408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4409 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4410 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4411 ok(strstr(lang, langcheck) != NULL, "expected %s in %s\n", langcheck, lang);
4412
4413 /* NULL pcchVersionBuf and pcchLangBuf */
4414 r = MsiGetFileVersionA(path, version, NULL, lang, NULL);
4415 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4416
4417 /* All NULL except szFilePath */
4418 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4419 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4420
4421 HeapFree(GetProcessHeap(), 0, vercheck);
4422 HeapFree(GetProcessHeap(), 0, langcheck);
4423 }
4424
4425 static void test_MsiGetProductInfo(void)
4426 {
4427 UINT r;
4428 LONG res;
4429 HKEY propkey, source;
4430 HKEY prodkey, localkey;
4431 CHAR prodcode[MAX_PATH];
4432 CHAR prod_squashed[MAX_PATH];
4433 CHAR packcode[MAX_PATH];
4434 CHAR pack_squashed[MAX_PATH];
4435 CHAR buf[MAX_PATH];
4436 CHAR keypath[MAX_PATH];
4437 LPSTR usersid;
4438 DWORD sz, val = 42;
4439 REGSAM access = KEY_ALL_ACCESS;
4440
4441 create_test_guid(prodcode, prod_squashed);
4442 create_test_guid(packcode, pack_squashed);
4443 usersid = get_user_sid();
4444
4445 if (is_wow64)
4446 access |= KEY_WOW64_64KEY;
4447
4448 /* NULL szProduct */
4449 sz = MAX_PATH;
4450 lstrcpyA(buf, "apple");
4451 r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4452 ok(r == ERROR_INVALID_PARAMETER,
4453 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4454 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4455 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4456
4457 /* empty szProduct */
4458 sz = MAX_PATH;
4459 lstrcpyA(buf, "apple");
4460 r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4461 ok(r == ERROR_INVALID_PARAMETER,
4462 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4463 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4464 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4465
4466 /* garbage szProduct */
4467 sz = MAX_PATH;
4468 lstrcpyA(buf, "apple");
4469 r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4470 ok(r == ERROR_INVALID_PARAMETER,
4471 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4472 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4473 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4474
4475 /* guid without brackets */
4476 sz = MAX_PATH;
4477 lstrcpyA(buf, "apple");
4478 r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
4479 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4480 ok(r == ERROR_INVALID_PARAMETER,
4481 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4482 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4483 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4484
4485 /* guid with brackets */
4486 sz = MAX_PATH;
4487 lstrcpyA(buf, "apple");
4488 r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
4489 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4490 ok(r == ERROR_UNKNOWN_PRODUCT,
4491 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4492 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4493 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4494
4495 /* same length as guid, but random */
4496 sz = MAX_PATH;
4497 lstrcpyA(buf, "apple");
4498 r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
4499 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4500 ok(r == ERROR_INVALID_PARAMETER,
4501 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4502 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4503 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4504
4505 /* not installed, NULL szAttribute */
4506 sz = MAX_PATH;
4507 lstrcpyA(buf, "apple");
4508 r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
4509 ok(r == ERROR_INVALID_PARAMETER,
4510 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4511 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4512 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4513
4514 /* not installed, NULL lpValueBuf */
4515 sz = MAX_PATH;
4516 lstrcpyA(buf, "apple");
4517 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4518 ok(r == ERROR_UNKNOWN_PRODUCT,
4519 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4520 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4521 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4522
4523 /* not installed, NULL pcchValueBuf */
4524 sz = MAX_PATH;
4525 lstrcpyA(buf, "apple");
4526 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, NULL);
4527 ok(r == ERROR_INVALID_PARAMETER,
4528 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4529 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4530 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4531
4532 /* created guid cannot possibly be an installed product code */
4533 sz = MAX_PATH;
4534 lstrcpyA(buf, "apple");
4535 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4536 ok(r == ERROR_UNKNOWN_PRODUCT,
4537 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4538 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4539 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4540
4541 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4542 lstrcatA(keypath, usersid);
4543 lstrcatA(keypath, "\\Installer\\Products\\");
4544 lstrcatA(keypath, prod_squashed);
4545
4546 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4547 if (res == ERROR_ACCESS_DENIED)
4548 {
4549 skip("Not enough rights to perform tests\n");
4550 LocalFree(usersid);
4551 return;
4552 }
4553 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4554
4555 /* managed product code exists */
4556 sz = MAX_PATH;
4557 lstrcpyA(buf, "apple");
4558 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4559 ok(r == ERROR_UNKNOWN_PROPERTY,
4560 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4561 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4562 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4563
4564 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4565 RegCloseKey(prodkey);
4566
4567 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4568 lstrcatA(keypath, usersid);
4569 lstrcatA(keypath, "\\Products\\");
4570 lstrcatA(keypath, prod_squashed);
4571
4572 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4573 if (res == ERROR_ACCESS_DENIED)
4574 {
4575 skip("Not enough rights to perform tests\n");
4576 LocalFree(usersid);
4577 return;
4578 }
4579 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4580
4581 /* local user product code exists */
4582 sz = MAX_PATH;
4583 lstrcpyA(buf, "apple");
4584 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4585 ok(r == ERROR_UNKNOWN_PRODUCT,
4586 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4587 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4588 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4589
4590 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4591 lstrcatA(keypath, usersid);
4592 lstrcatA(keypath, "\\Installer\\Products\\");
4593 lstrcatA(keypath, prod_squashed);
4594
4595 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4596 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4597
4598 /* both local and managed product code exist */
4599 sz = MAX_PATH;
4600 lstrcpyA(buf, "apple");
4601 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4602 ok(r == ERROR_UNKNOWN_PROPERTY,
4603 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4604 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4605 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4606
4607 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4608 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4609
4610 /* InstallProperties key exists */
4611 sz = MAX_PATH;
4612 lstrcpyA(buf, "apple");
4613 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4614 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4615 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4616 ok(sz == 0, "Expected 0, got %d\n", sz);
4617
4618 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4619 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4620
4621 /* HelpLink value exists */
4622 sz = MAX_PATH;
4623 lstrcpyA(buf, "apple");
4624 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4625 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4626 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4627 ok(sz == 4, "Expected 4, got %d\n", sz);
4628
4629 /* pcchBuf is NULL */
4630 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, NULL);
4631 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4632
4633 /* lpValueBuf is NULL */
4634 sz = MAX_PATH;
4635 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4636 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4637 ok(sz == 4, "Expected 4, got %d\n", sz);
4638
4639 /* lpValueBuf is NULL, pcchValueBuf is too small */
4640 sz = 2;
4641 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4642 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4643 ok(sz == 4, "Expected 4, got %d\n", sz);
4644
4645 /* lpValueBuf is non-NULL, pcchValueBuf is too small */
4646 sz = 2;
4647 lstrcpyA(buf, "apple");
4648 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4649 ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
4650 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4651 ok(sz == 4, "Expected 4, got %d\n", sz);
4652
4653 /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
4654 sz = 4;
4655 lstrcpyA(buf, "apple");
4656 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4657 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4658 ok(!lstrcmpA(buf, "apple"),
4659 "Expected buf to remain unchanged, got \"%s\"\n", buf);
4660 ok(sz == 4, "Expected 4, got %d\n", sz);
4661
4662 res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
4663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4664
4665 /* random property not supported by MSI, value exists */
4666 sz = MAX_PATH;
4667 lstrcpyA(buf, "apple");
4668 r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
4669 ok(r == ERROR_UNKNOWN_PROPERTY,
4670 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4671 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4672 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4673
4674 RegDeleteValueA(propkey, "IMadeThis");
4675 RegDeleteValueA(propkey, "HelpLink");
4676 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4677 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4678 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4679 RegCloseKey(propkey);
4680 RegCloseKey(localkey);
4681 RegCloseKey(prodkey);
4682
4683 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4684 lstrcatA(keypath, prod_squashed);
4685
4686 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4687 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4688
4689 /* user product key exists */
4690 sz = MAX_PATH;
4691 lstrcpyA(buf, "apple");
4692 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4693 ok(r == ERROR_UNKNOWN_PROPERTY,
4694 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4695 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4696 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4697
4698 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4699 lstrcatA(keypath, usersid);
4700 lstrcatA(keypath, "\\Products\\");
4701 lstrcatA(keypath, prod_squashed);
4702
4703 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4704 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4705
4706 /* local user product key exists */
4707 sz = MAX_PATH;
4708 lstrcpyA(buf, "apple");
4709 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4710 ok(r == ERROR_UNKNOWN_PROPERTY,
4711 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4712 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4713 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4714
4715 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4716 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4717
4718 /* InstallProperties key exists */
4719 sz = MAX_PATH;
4720 lstrcpyA(buf, "apple");
4721 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4722 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4723 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4724 ok(sz == 0, "Expected 0, got %d\n", sz);
4725
4726 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4727 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4728
4729 /* HelpLink value exists */
4730 sz = MAX_PATH;
4731 lstrcpyA(buf, "apple");
4732 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4733 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4734 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4735 ok(sz == 4, "Expected 4, got %d\n", sz);
4736
4737 RegDeleteValueA(propkey, "HelpLink");
4738 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4739 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4740 RegDeleteKeyA(prodkey, "");
4741 RegCloseKey(propkey);
4742 RegCloseKey(localkey);
4743 RegCloseKey(prodkey);
4744
4745 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
4746 lstrcatA(keypath, prod_squashed);
4747
4748 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4749 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4750
4751 /* classes product key exists */
4752 sz = MAX_PATH;
4753 lstrcpyA(buf, "apple");
4754 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4755 ok(r == ERROR_UNKNOWN_PROPERTY,
4756 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4757 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4758 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4759
4760 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4761 lstrcatA(keypath, usersid);
4762 lstrcatA(keypath, "\\Products\\");
4763 lstrcatA(keypath, prod_squashed);
4764
4765 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4766 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4767
4768 /* local user product key exists */
4769 sz = MAX_PATH;
4770 lstrcpyA(buf, "apple");
4771 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4772 ok(r == ERROR_UNKNOWN_PROPERTY,
4773 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4774 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4775 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4776
4777 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4778 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4779
4780 /* InstallProperties key exists */
4781 sz = MAX_PATH;
4782 lstrcpyA(buf, "apple");
4783 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4784 ok(r == ERROR_UNKNOWN_PROPERTY,
4785 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4786 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4787 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4788
4789 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4790 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4791 RegCloseKey(propkey);
4792 RegCloseKey(localkey);
4793
4794 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4795 lstrcatA(keypath, "S-1-5-18\\\\Products\\");
4796 lstrcatA(keypath, prod_squashed);
4797
4798 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4799 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4800
4801 /* Local System product key exists */
4802 sz = MAX_PATH;
4803 lstrcpyA(buf, "apple");
4804 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4805 ok(r == ERROR_UNKNOWN_PROPERTY,
4806 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4807 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4808 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4809
4810 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4811 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4812
4813 /* InstallProperties key exists */
4814 sz = MAX_PATH;
4815 lstrcpyA(buf, "apple");
4816 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4817 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4818 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4819 ok(sz == 0, "Expected 0, got %d\n", sz);
4820
4821 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4822 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4823
4824 /* HelpLink value exists */
4825 sz = MAX_PATH;
4826 lstrcpyA(buf, "apple");
4827 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4828 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4829 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4830 ok(sz == 4, "Expected 4, got %d\n", sz);
4831
4832 res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
4833 (const BYTE *)&val, sizeof(DWORD));
4834 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4835
4836 /* HelpLink type is REG_DWORD */
4837 sz = MAX_PATH;
4838 lstrcpyA(buf, "apple");
4839 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4840 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4841 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4842 ok(sz == 2, "Expected 2, got %d\n", sz);
4843
4844 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4845 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4846
4847 /* DisplayName value exists */
4848 sz = MAX_PATH;
4849 lstrcpyA(buf, "apple");
4850 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
4851 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4852 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4853 ok(sz == 4, "Expected 4, got %d\n", sz);
4854
4855 res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
4856 (const BYTE *)&val, sizeof(DWORD));
4857 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4858
4859 /* DisplayName type is REG_DWORD */
4860 sz = MAX_PATH;
4861 lstrcpyA(buf, "apple");
4862 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
4863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4864 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4865 ok(sz == 2, "Expected 2, got %d\n", sz);
4866
4867 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
4868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4869
4870 /* DisplayVersion value exists */
4871 sz = MAX_PATH;
4872 lstrcpyA(buf, "apple");
4873 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
4874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4875 ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
4876 ok(sz == 5, "Expected 5, got %d\n", sz);
4877
4878 res = RegSetValueExA(propkey, "DisplayVersion", 0,
4879 REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
4880 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4881
4882 /* DisplayVersion type is REG_DWORD */
4883 sz = MAX_PATH;
4884 lstrcpyA(buf, "apple");
4885 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
4886 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4887 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4888 ok(sz == 2, "Expected 2, got %d\n", sz);
4889
4890 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
4891 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4892
4893 /* HelpTelephone value exists */
4894 sz = MAX_PATH;
4895 lstrcpyA(buf, "apple");
4896 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
4897 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4898 ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
4899 ok(sz == 4, "Expected 4, got %d\n", sz);
4900
4901 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
4902 (const BYTE *)&val, sizeof(DWORD));
4903 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4904
4905 /* HelpTelephone type is REG_DWORD */
4906 sz = MAX_PATH;
4907 lstrcpyA(buf, "apple");
4908 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
4909 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4910 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4911 ok(sz == 2, "Expected 2, got %d\n", sz);
4912
4913 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4914 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4915
4916 /* InstallLocation value exists */
4917 sz = MAX_PATH;
4918 lstrcpyA(buf, "apple");
4919 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
4920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4921 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4922 ok(sz == 3, "Expected 3, got %d\n", sz);
4923
4924 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
4925 (const BYTE *)&val, sizeof(DWORD));
4926 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4927
4928 /* InstallLocation type is REG_DWORD */
4929 sz = MAX_PATH;
4930 lstrcpyA(buf, "apple");
4931 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
4932 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4933 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4934 ok(sz == 2, "Expected 2, got %d\n", sz);
4935
4936 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4937 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4938
4939 /* InstallSource value exists */
4940 sz = MAX_PATH;
4941 lstrcpyA(buf, "apple");
4942 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
4943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4944 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4945 ok(sz == 6, "Expected 6, got %d\n", sz);
4946
4947 res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
4948 (const BYTE *)&val, sizeof(DWORD));
4949 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4950
4951 /* InstallSource type is REG_DWORD */
4952 sz = MAX_PATH;
4953 lstrcpyA(buf, "apple");
4954 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
4955 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4956 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4957 ok(sz == 2, "Expected 2, got %d\n", sz);
4958
4959 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4960 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4961
4962 /* InstallDate value exists */
4963 sz = MAX_PATH;
4964 lstrcpyA(buf, "apple");
4965 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
4966 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4967 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4968 ok(sz == 4, "Expected 4, got %d\n", sz);
4969
4970 res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
4971 (const BYTE *)&val, sizeof(DWORD));
4972 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4973
4974 /* InstallDate type is REG_DWORD */
4975 sz = MAX_PATH;
4976 lstrcpyA(buf, "apple");
4977 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
4978 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4979 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4980 ok(sz == 2, "Expected 2, got %d\n", sz);
4981
4982 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4983 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4984
4985 /* Publisher value exists */
4986 sz = MAX_PATH;
4987 lstrcpyA(buf, "apple");
4988 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHERA, buf, &sz);
4989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4990 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4991 ok(sz == 3, "Expected 3, got %d\n", sz);
4992
4993 res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
4994 (const BYTE *)&val, sizeof(DWORD));
4995 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4996
4997 /* Publisher type is REG_DWORD */
4998 sz = MAX_PATH;
4999 lstrcpyA(buf, "apple");
5000 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHERA, buf, &sz);
5001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5002 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5003 ok(sz == 2, "Expected 2, got %d\n", sz);
5004
5005 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
5006 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5007
5008 /* LocalPackage value exists */
5009 sz = MAX_PATH;
5010 lstrcpyA(buf, "apple");
5011 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
5012 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5013 ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
5014 ok(sz == 4, "Expected 4, got %d\n", sz);
5015
5016 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
5017 (const BYTE *)&val, sizeof(DWORD));
5018 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5019
5020 /* LocalPackage type is REG_DWORD */
5021 sz = MAX_PATH;
5022 lstrcpyA(buf, "apple");
5023 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
5024 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5025 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5026 ok(sz == 2, "Expected 2, got %d\n", sz);
5027
5028 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5030
5031 /* UrlInfoAbout value exists */
5032 sz = MAX_PATH;
5033 lstrcpyA(buf, "apple");
5034 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
5035 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5036 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5037 ok(sz == 5, "Expected 5, got %d\n", sz);
5038
5039 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
5040 (const BYTE *)&val, sizeof(DWORD));
5041 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5042
5043 /* UrlInfoAbout type is REG_DWORD */
5044 sz = MAX_PATH;
5045 lstrcpyA(buf, "apple");
5046 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
5047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5048 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5049 ok(sz == 2, "Expected 2, got %d\n", sz);
5050
5051 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
5052 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5053
5054 /* UrlUpdateInfo value exists */
5055 sz = MAX_PATH;
5056 lstrcpyA(buf, "apple");
5057 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
5058 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5059 ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
5060 ok(sz == 4, "Expected 4, got %d\n", sz);
5061
5062 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
5063 (const BYTE *)&val, sizeof(DWORD));
5064 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5065
5066 /* UrlUpdateInfo type is REG_DWORD */
5067 sz = MAX_PATH;
5068 lstrcpyA(buf, "apple");
5069 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
5070 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5071 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5072 ok(sz == 2, "Expected 2, got %d\n", sz);
5073
5074 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
5075 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5076
5077 /* VersionMinor value exists */
5078 sz = MAX_PATH;
5079 lstrcpyA(buf, "apple");
5080 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
5081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5082 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5083 ok(sz == 1, "Expected 1, got %d\n", sz);
5084
5085 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
5086 (const BYTE *)&val, sizeof(DWORD));
5087 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5088
5089 /* VersionMinor type is REG_DWORD */
5090 sz = MAX_PATH;
5091 lstrcpyA(buf, "apple");
5092 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
5093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5094 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5095 ok(sz == 2, "Expected 2, got %d\n", sz);
5096
5097 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
5098 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5099
5100 /* VersionMajor value exists */
5101 sz = MAX_PATH;
5102 lstrcpyA(buf, "apple");
5103 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
5104 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5105 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5106 ok(sz == 1, "Expected 1, got %d\n", sz);
5107
5108 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
5109 (const BYTE *)&val, sizeof(DWORD));
5110 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5111
5112 /* VersionMajor type is REG_DWORD */
5113 sz = MAX_PATH;
5114 lstrcpyA(buf, "apple");
5115 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
5116 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5117 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5118 ok(sz == 2, "Expected 2, got %d\n", sz);
5119
5120 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5121 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5122
5123 /* ProductID value exists */
5124 sz = MAX_PATH;
5125 lstrcpyA(buf, "apple");
5126 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
5127 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5128 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5129 ok(sz == 2, "Expected 2, got %d\n", sz);
5130
5131 res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
5132 (const BYTE *)&val, sizeof(DWORD));
5133 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5134
5135 /* ProductID type is REG_DWORD */
5136 sz = MAX_PATH;
5137 lstrcpyA(buf, "apple");
5138 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
5139 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5140 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5141 ok(sz == 2, "Expected 2, got %d\n", sz);
5142
5143 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5144 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5145
5146 /* RegCompany value exists */
5147 sz = MAX_PATH;
5148 lstrcpyA(buf, "apple");
5149 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
5150 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5151 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5152 ok(sz == 4, "Expected 4, got %d\n", sz);
5153
5154 res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
5155 (const BYTE *)&val, sizeof(DWORD));
5156 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5157
5158 /* RegCompany type is REG_DWORD */
5159 sz = MAX_PATH;
5160 lstrcpyA(buf, "apple");
5161 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
5162 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5163 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5164 ok(sz == 2, "Expected 2, got %d\n", sz);
5165
5166 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
5167 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5168
5169 /* RegOwner value exists */
5170 sz = MAX_PATH;
5171 lstrcpyA(buf, "apple");
5172 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNERA, buf, &sz);
5173 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5174 ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
5175 ok(sz == 3, "Expected 3, got %d\n", sz);
5176
5177 res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
5178 (const BYTE *)&val, sizeof(DWORD));
5179 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5180
5181 /* RegOwner type is REG_DWORD */
5182 sz = MAX_PATH;
5183 lstrcpyA(buf, "apple");
5184 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNERA, buf, &sz);
5185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5186 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5187 ok(sz == 2, "Expected 2, got %d\n", sz);
5188
5189 res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
5190 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5191
5192 /* InstanceType value exists */
5193 sz = MAX_PATH;
5194 lstrcpyA(buf, "apple");
5195 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5197 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5198 ok(sz == 0, "Expected 0, got %d\n", sz);
5199
5200 res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
5201 (const BYTE *)&val, sizeof(DWORD));
5202 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5203
5204 /* InstanceType type is REG_DWORD */
5205 sz = MAX_PATH;
5206 lstrcpyA(buf, "apple");
5207 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5208 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5209 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5210 ok(sz == 0, "Expected 0, got %d\n", sz);
5211
5212 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
5213 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5214
5215 /* InstanceType value exists */
5216 sz = MAX_PATH;
5217 lstrcpyA(buf, "apple");
5218 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5219 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5220 ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
5221 ok(sz == 4, "Expected 4, got %d\n", sz);
5222
5223 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
5224 (const BYTE *)&val, sizeof(DWORD));
5225 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5226
5227 /* InstanceType type is REG_DWORD */
5228 sz = MAX_PATH;
5229 lstrcpyA(buf, "apple");
5230 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5231 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5232 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5233 ok(sz == 2, "Expected 2, got %d\n", sz);
5234
5235 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
5236 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5237
5238 /* Transforms value exists */
5239 sz = MAX_PATH;
5240 lstrcpyA(buf, "apple");
5241 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5243 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5244 ok(sz == 0, "Expected 0, got %d\n", sz);
5245
5246 res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
5247 (const BYTE *)&val, sizeof(DWORD));
5248 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5249
5250 /* Transforms type is REG_DWORD */
5251 sz = MAX_PATH;
5252 lstrcpyA(buf, "apple");
5253 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5255 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5256 ok(sz == 0, "Expected 0, got %d\n", sz);
5257
5258 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
5259 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5260
5261 /* Transforms value exists */
5262 sz = MAX_PATH;
5263 lstrcpyA(buf, "apple");
5264 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5265 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5266 ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
5267 ok(sz == 6, "Expected 6, got %d\n", sz);
5268
5269 res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
5270 (const BYTE *)&val, sizeof(DWORD));
5271 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5272
5273 /* Transforms type is REG_DWORD */
5274 sz = MAX_PATH;
5275 lstrcpyA(buf, "apple");
5276 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5278 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5279 ok(sz == 2, "Expected 2, got %d\n", sz);
5280
5281 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5282 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5283
5284 /* Language value exists */
5285 sz = MAX_PATH;
5286 lstrcpyA(buf, "apple");
5287 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5289 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5290 ok(sz == 0, "Expected 0, got %d\n", sz);
5291
5292 res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
5293 (const BYTE *)&val, sizeof(DWORD));
5294 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5295
5296 /* Language type is REG_DWORD */
5297 sz = MAX_PATH;
5298 lstrcpyA(buf, "apple");
5299 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5300 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5301 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5302 ok(sz == 0, "Expected 0, got %d\n", sz);
5303
5304 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5305 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5306
5307 /* Language value exists */
5308 sz = MAX_PATH;
5309 lstrcpyA(buf, "apple");
5310 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5312 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5313 ok(sz == 4, "Expected 4, got %d\n", sz);
5314
5315 res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
5316 (const BYTE *)&val, sizeof(DWORD));
5317 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5318
5319 /* Language type is REG_DWORD */
5320 sz = MAX_PATH;
5321 lstrcpyA(buf, "apple");
5322 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5324 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5325 ok(sz == 2, "Expected 2, got %d\n", sz);
5326
5327 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5328 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5329
5330 /* ProductName value exists */
5331 sz = MAX_PATH;
5332 lstrcpyA(buf, "apple");
5333 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5334 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5335 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5336 ok(sz == 0, "Expected 0, got %d\n", sz);
5337
5338 res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
5339 (const BYTE *)&val, sizeof(DWORD));
5340 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5341
5342 /* ProductName type is REG_DWORD */
5343 sz = MAX_PATH;
5344 lstrcpyA(buf, "apple");
5345 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5346 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5347 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5348 ok(sz == 0, "Expected 0, got %d\n", sz);
5349
5350 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5351 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5352
5353 /* ProductName value exists */
5354 sz = MAX_PATH;
5355 lstrcpyA(buf, "apple");
5356 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5358 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5359 ok(sz == 4, "Expected 4, got %d\n", sz);
5360
5361 res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
5362 (const BYTE *)&val, sizeof(DWORD));
5363 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5364
5365 /* ProductName type is REG_DWORD */
5366 sz = MAX_PATH;
5367 lstrcpyA(buf, "apple");
5368 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5369 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5370 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5371 ok(sz == 2, "Expected 2, got %d\n", sz);
5372
5373 res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5375
5376 /* Assignment value exists */
5377 sz = MAX_PATH;
5378 lstrcpyA(buf, "apple");
5379 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5381 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5382 ok(sz == 0, "Expected 0, got %d\n", sz);
5383
5384 res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
5385 (const BYTE *)&val, sizeof(DWORD));
5386 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5387
5388 /* Assignment type is REG_DWORD */
5389 sz = MAX_PATH;
5390 lstrcpyA(buf, "apple");
5391 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5392 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5393 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5394 ok(sz == 0, "Expected 0, got %d\n", sz);
5395
5396 res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5397 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5398
5399 /* Assignment value exists */
5400 sz = MAX_PATH;
5401 lstrcpyA(buf, "apple");
5402 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5403 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5404 ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
5405 ok(sz == 2, "Expected 2, got %d\n", sz);
5406
5407 res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
5408 (const BYTE *)&val, sizeof(DWORD));
5409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5410
5411 /* Assignment type is REG_DWORD */
5412 sz = MAX_PATH;
5413 lstrcpyA(buf, "apple");
5414 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5416 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5417 ok(sz == 2, "Expected 2, got %d\n", sz);
5418
5419 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5421
5422 /* PackageCode value exists */
5423 sz = MAX_PATH;
5424 lstrcpyA(buf, "apple");
5425 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5427 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5428 ok(sz == 0, "Expected 0, got %d\n", sz);
5429
5430 res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
5431 (const BYTE *)&val, sizeof(DWORD));
5432 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5433
5434 /* PackageCode type is REG_DWORD */
5435 sz = MAX_PATH;
5436 lstrcpyA(buf, "apple");
5437 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5439 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5440 ok(sz == 0, "Expected 0, got %d\n", sz);
5441
5442 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5443 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5444
5445 /* PackageCode value exists */
5446 sz = MAX_PATH;
5447 lstrcpyA(buf, "apple");
5448 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5449 ok(r == ERROR_BAD_CONFIGURATION,
5450 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5451 ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
5452 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5453
5454 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
5455 (const BYTE *)&val, sizeof(DWORD));
5456 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5457
5458 /* PackageCode type is REG_DWORD */
5459 sz = MAX_PATH;
5460 lstrcpyA(buf, "apple");
5461 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5463 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5464 ok(sz == 2, "Expected 2, got %d\n", sz);
5465
5466 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
5467 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5468
5469 /* PackageCode value exists */
5470 sz = MAX_PATH;
5471 lstrcpyA(buf, "apple");
5472 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5473 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5474 ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
5475 ok(sz == 38, "Expected 38, got %d\n", sz);
5476
5477 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5478 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5479
5480 /* Version value exists */
5481 sz = MAX_PATH;
5482 lstrcpyA(buf, "apple");
5483 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5485 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5486 ok(sz == 0, "Expected 0, got %d\n", sz);
5487
5488 res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
5489 (const BYTE *)&val, sizeof(DWORD));
5490 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5491
5492 /* Version type is REG_DWORD */
5493 sz = MAX_PATH;
5494 lstrcpyA(buf, "apple");
5495 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5497 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5498 ok(sz == 0, "Expected 0, got %d\n", sz);
5499
5500 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5501 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5502
5503 /* Version value exists */
5504 sz = MAX_PATH;
5505 lstrcpyA(buf, "apple");
5506 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5507 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5508 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5509 ok(sz == 3, "Expected 3, got %d\n", sz);
5510
5511 res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
5512 (const BYTE *)&val, sizeof(DWORD));
5513 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5514
5515 /* Version type is REG_DWORD */
5516 sz = MAX_PATH;
5517 lstrcpyA(buf, "apple");
5518 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5520 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5521 ok(sz == 2, "Expected 2, got %d\n", sz);
5522
5523 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5524 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5525
5526 /* ProductIcon value exists */
5527 sz = MAX_PATH;
5528 lstrcpyA(buf, "apple");
5529 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5530 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5531 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5532 ok(sz == 0, "Expected 0, got %d\n", sz);
5533
5534 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
5535 (const BYTE *)&val, sizeof(DWORD));
5536 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5537
5538 /* ProductIcon type is REG_DWORD */
5539 sz = MAX_PATH;
5540 lstrcpyA(buf, "apple");
5541 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5542 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5543 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5544 ok(sz == 0, "Expected 0, got %d\n", sz);
5545
5546 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5547 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5548
5549 /* ProductIcon value exists */
5550 sz = MAX_PATH;
5551 lstrcpyA(buf, "apple");
5552 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5554 ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
5555 ok(sz == 3, "Expected 3, got %d\n", sz);
5556
5557 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
5558 (const BYTE *)&val, sizeof(DWORD));
5559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5560
5561 /* ProductIcon type is REG_DWORD */
5562 sz = MAX_PATH;
5563 lstrcpyA(buf, "apple");
5564 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5566 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5567 ok(sz == 2, "Expected 2, got %d\n", sz);
5568
5569 /* SourceList key does not exist */
5570 sz = MAX_PATH;
5571 lstrcpyA(buf, "apple");
5572 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5573 ok(r == ERROR_UNKNOWN_PRODUCT,
5574 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5575 ok(!lstrcmpA(buf, "apple"),
5576 "Expected buf to be unchanged, got \"%s\"\n", buf);
5577 ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
5578
5579 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
5580 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5581
5582 /* SourceList key exists, but PackageName val does not exist */
5583 sz = MAX_PATH;
5584 lstrcpyA(buf, "apple");
5585 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5586 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5587 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5588 ok(sz == 0, "Expected 0, got %d\n", sz);
5589
5590 res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
5591 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5592
5593 /* PackageName val exists */
5594 sz = MAX_PATH;
5595 lstrcpyA(buf, "apple");
5596 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5598 ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
5599 ok(sz == 8, "Expected 8, got %d\n", sz);
5600
5601 res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
5602 (const BYTE *)&val, sizeof(DWORD));
5603 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5604
5605 /* PackageName type is REG_DWORD */
5606 sz = MAX_PATH;
5607 lstrcpyA(buf, "apple");
5608 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5609 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5610 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5611 ok(sz == 2, "Expected 2, got %d\n", sz);
5612
5613 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5614 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5615
5616 /* Authorized value exists */
5617 sz = MAX_PATH;
5618 lstrcpyA(buf, "apple");
5619 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5620 if (r != ERROR_UNKNOWN_PROPERTY)
5621 {
5622 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5623 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5624 ok(sz == 0, "Expected 0, got %d\n", sz);
5625 }
5626
5627 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
5628 (const BYTE *)&val, sizeof(DWORD));
5629 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5630
5631 /* AuthorizedLUAApp type is REG_DWORD */
5632 sz = MAX_PATH;
5633 lstrcpyA(buf, "apple");
5634 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5635 if (r != ERROR_UNKNOWN_PROPERTY)
5636 {
5637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5638 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5639 ok(sz == 0, "Expected 0, got %d\n", sz);
5640 }
5641
5642 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5643 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5644
5645 /* Authorized value exists */
5646 sz = MAX_PATH;
5647 lstrcpyA(buf, "apple");
5648 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5649 if (r != ERROR_UNKNOWN_PROPERTY)
5650 {
5651 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5652 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5653 ok(sz == 4, "Expected 4, got %d\n", sz);
5654 }
5655
5656 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
5657 (const BYTE *)&val, sizeof(DWORD));
5658 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5659
5660 /* AuthorizedLUAApp type is REG_DWORD */
5661 sz = MAX_PATH;
5662 lstrcpyA(buf, "apple");
5663 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5664 if (r != ERROR_UNKNOWN_PROPERTY)
5665 {
5666 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5667 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5668 ok(sz == 2, "Expected 2, got %d\n", sz);
5669 }
5670
5671 RegDeleteValueA(propkey, "HelpLink");
5672 RegDeleteValueA(propkey, "DisplayName");
5673 RegDeleteValueA(propkey, "DisplayVersion");
5674 RegDeleteValueA(propkey, "HelpTelephone");
5675 RegDeleteValueA(propkey, "InstallLocation");
5676 RegDeleteValueA(propkey, "InstallSource");
5677 RegDeleteValueA(propkey, "InstallDate");
5678 RegDeleteValueA(propkey, "Publisher");
5679 RegDeleteValueA(propkey, "LocalPackage");
5680 RegDeleteValueA(propkey, "UrlInfoAbout");
5681 RegDeleteValueA(propkey, "UrlUpdateInfo");
5682 RegDeleteValueA(propkey, "VersionMinor");
5683 RegDeleteValueA(propkey, "VersionMajor");
5684 RegDeleteValueA(propkey, "ProductID");
5685 RegDeleteValueA(propkey, "RegCompany");
5686 RegDeleteValueA(propkey, "RegOwner");
5687 RegDeleteValueA(propkey, "InstanceType");
5688 RegDeleteValueA(propkey, "Transforms");
5689 RegDeleteValueA(propkey, "Language");
5690 RegDeleteValueA(propkey, "ProductName");
5691 RegDeleteValueA(propkey, "Assignment");
5692 RegDeleteValueA(propkey, "PackageCode");
5693 RegDeleteValueA(propkey, "Version");
5694 RegDeleteValueA(propkey, "ProductIcon");
5695 RegDeleteValueA(propkey, "AuthorizedLUAApp");
5696 delete_key(propkey, "", access & KEY_WOW64_64KEY);
5697 delete_key(localkey, "", access & KEY_WOW64_64KEY);
5698 RegDeleteValueA(prodkey, "InstanceType");
5699 RegDeleteValueA(prodkey, "Transforms");
5700 RegDeleteValueA(prodkey, "Language");
5701 RegDeleteValueA(prodkey, "ProductName");
5702 RegDeleteValueA(prodkey, "Assignment");
5703 RegDeleteValueA(prodkey, "PackageCode");
5704 RegDeleteValueA(prodkey, "Version");
5705 RegDeleteValueA(prodkey, "ProductIcon");
5706 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5707 RegDeleteValueA(source, "PackageName");
5708 delete_key(source, "", access & KEY_WOW64_64KEY);
5709 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5710 RegCloseKey(propkey);
5711 RegCloseKey(localkey);
5712 RegCloseKey(source);
5713 RegCloseKey(prodkey);
5714 LocalFree(usersid);
5715 }
5716
5717 static void test_MsiGetProductInfoEx(void)
5718 {
5719 UINT r;
5720 LONG res;
5721 HKEY propkey, userkey;
5722 HKEY prodkey, localkey;
5723 CHAR prodcode[MAX_PATH];
5724 CHAR prod_squashed[MAX_PATH];
5725 CHAR packcode[MAX_PATH];
5726 CHAR pack_squashed[MAX_PATH];
5727 CHAR buf[MAX_PATH];
5728 CHAR keypath[MAX_PATH];
5729 LPSTR usersid;
5730 DWORD sz;
5731 REGSAM access = KEY_ALL_ACCESS;
5732
5733 if (!pMsiGetProductInfoExA)
5734 {
5735 win_skip("MsiGetProductInfoExA is not available\n");
5736 return;
5737 }
5738
5739 create_test_guid(prodcode, prod_squashed);
5740 create_test_guid(packcode, pack_squashed);
5741 usersid = get_user_sid();
5742
5743 if (is_wow64)
5744 access |= KEY_WOW64_64KEY;
5745
5746 /* NULL szProductCode */
5747 sz = MAX_PATH;
5748 lstrcpyA(buf, "apple");
5749 r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5750 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5751 ok(r == ERROR_INVALID_PARAMETER,
5752 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5753 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5754 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5755
5756 /* empty szProductCode */
5757 sz = MAX_PATH;
5758 lstrcpyA(buf, "apple");
5759 r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5760 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5761 ok(r == ERROR_INVALID_PARAMETER,
5762 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5763 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5764 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5765
5766 /* garbage szProductCode */
5767 sz = MAX_PATH;
5768 lstrcpyA(buf, "apple");
5769 r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5770 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5771 ok(r == ERROR_INVALID_PARAMETER,
5772 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5773 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5774 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5775
5776 /* guid without brackets */
5777 sz = MAX_PATH;
5778 lstrcpyA(buf, "apple");
5779 r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
5780 MSIINSTALLCONTEXT_USERUNMANAGED,
5781 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5782 ok(r == ERROR_INVALID_PARAMETER,
5783 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5784 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5785 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5786
5787 /* guid with brackets */
5788 sz = MAX_PATH;
5789 lstrcpyA(buf, "apple");
5790 r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
5791 MSIINSTALLCONTEXT_USERUNMANAGED,
5792 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5793 ok(r == ERROR_UNKNOWN_PRODUCT,
5794 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5795 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5796 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5797
5798 /* szValue is non-NULL while pcchValue is NULL */
5799 lstrcpyA(buf, "apple");
5800 r = pMsiGetProductInfoExA(prodcode, usersid,
5801 MSIINSTALLCONTEXT_USERUNMANAGED,
5802 INSTALLPROPERTY_PRODUCTSTATEA, buf, NULL);
5803 ok(r == ERROR_INVALID_PARAMETER,
5804 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5805 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5806
5807 /* dwContext is out of range */
5808 sz = MAX_PATH;
5809 lstrcpyA(buf, "apple");
5810 r = pMsiGetProductInfoExA(prodcode, usersid, 42,
5811 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5812 ok(r == ERROR_INVALID_PARAMETER,
5813 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5814 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5815 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5816
5817 /* szProperty is NULL */
5818 sz = MAX_PATH;
5819 lstrcpyA(buf, "apple");
5820 r = pMsiGetProductInfoExA(prodcode, usersid,
5821 MSIINSTALLCONTEXT_USERUNMANAGED,
5822 NULL, buf, &sz);
5823 ok(r == ERROR_INVALID_PARAMETER,
5824 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5825 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5826 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5827
5828 /* szProperty is empty */
5829 sz = MAX_PATH;
5830 lstrcpyA(buf, "apple");
5831 r = pMsiGetProductInfoExA(prodcode, usersid,
5832 MSIINSTALLCONTEXT_USERUNMANAGED,
5833 "", buf, &sz);
5834 ok(r == ERROR_INVALID_PARAMETER,
5835 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5836 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5837 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5838
5839 /* szProperty is not a valid property */
5840 sz = MAX_PATH;
5841 lstrcpyA(buf, "apple");
5842 r = pMsiGetProductInfoExA(prodcode, usersid,
5843 MSIINSTALLCONTEXT_USERUNMANAGED,
5844 "notvalid", buf, &sz);
5845 ok(r == ERROR_UNKNOWN_PRODUCT,
5846 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5847 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5848 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5849
5850 /* same length as guid, but random */
5851 sz = MAX_PATH;
5852 lstrcpyA(buf, "apple");
5853 r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
5854 MSIINSTALLCONTEXT_USERUNMANAGED,
5855 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5856 ok(r == ERROR_INVALID_PARAMETER,
5857 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5858 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5859 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5860
5861 /* MSIINSTALLCONTEXT_USERUNMANAGED */
5862
5863 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5864 lstrcatA(keypath, usersid);
5865 lstrcatA(keypath, "\\Products\\");
5866 lstrcatA(keypath, prod_squashed);
5867
5868 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5869 if (res == ERROR_ACCESS_DENIED)
5870 {
5871 skip("Not enough rights to perform tests\n");
5872 LocalFree(usersid);
5873 return;
5874 }
5875 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5876
5877 /* local user product key exists */
5878 sz = MAX_PATH;
5879 lstrcpyA(buf, "apple");
5880 r = pMsiGetProductInfoExA(prodcode, usersid,
5881 MSIINSTALLCONTEXT_USERUNMANAGED,
5882 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5883 ok(r == ERROR_UNKNOWN_PRODUCT,
5884 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5885 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5886 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5887
5888 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5889 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5890
5891 /* InstallProperties key exists */
5892 sz = MAX_PATH;
5893 lstrcpyA(buf, "apple");
5894 r = pMsiGetProductInfoExA(prodcode, usersid,
5895 MSIINSTALLCONTEXT_USERUNMANAGED,
5896 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5897 ok(r == ERROR_UNKNOWN_PRODUCT,
5898 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5899 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5900 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5901
5902 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5903 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5904
5905 /* LocalPackage value exists */
5906 sz = MAX_PATH;
5907 lstrcpyA(buf, "apple");
5908 r = pMsiGetProductInfoExA(prodcode, usersid,
5909 MSIINSTALLCONTEXT_USERUNMANAGED,
5910 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5911 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5912 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5913 ok(sz == 1, "Expected 1, got %d\n", sz);
5914
5915 RegDeleteValueA(propkey, "LocalPackage");
5916
5917 /* LocalPackage value must exist */
5918 sz = MAX_PATH;
5919 lstrcpyA(buf, "apple");
5920 r = pMsiGetProductInfoExA(prodcode, usersid,
5921 MSIINSTALLCONTEXT_USERUNMANAGED,
5922 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5923 ok(r == ERROR_UNKNOWN_PRODUCT,
5924 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5925 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5926 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5927
5928 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5929 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5930
5931 /* LocalPackage exists, but HelpLink does not exist */
5932 sz = MAX_PATH;
5933 lstrcpyA(buf, "apple");
5934 r = pMsiGetProductInfoExA(prodcode, usersid,
5935 MSIINSTALLCONTEXT_USERUNMANAGED,
5936 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5938 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5939 ok(sz == 0, "Expected 0, got %d\n", sz);
5940
5941 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5942 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5943
5944 /* HelpLink value exists */
5945 sz = MAX_PATH;
5946 lstrcpyA(buf, "apple");
5947 r = pMsiGetProductInfoExA(prodcode, usersid,
5948 MSIINSTALLCONTEXT_USERUNMANAGED,
5949 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5951 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5952 ok(sz == 4, "Expected 4, got %d\n", sz);
5953
5954 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5955 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5956
5957 /* HelpTelephone value exists */
5958 sz = MAX_PATH;
5959 lstrcpyA(buf, "apple");
5960 r = pMsiGetProductInfoExA(prodcode, usersid,
5961 MSIINSTALLCONTEXT_USERUNMANAGED,
5962 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5963 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5964 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5965 ok(sz == 5, "Expected 5, got %d\n", sz);
5966
5967 /* szValue and pcchValue are NULL */
5968 r = pMsiGetProductInfoExA(prodcode, usersid,
5969 MSIINSTALLCONTEXT_USERUNMANAGED,
5970 INSTALLPROPERTY_HELPTELEPHONEA, NULL, NULL);
5971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5972
5973 /* pcchValue is exactly 5 */
5974 sz = 5;
5975 lstrcpyA(buf, "apple");
5976 r = pMsiGetProductInfoExA(prodcode, usersid,
5977 MSIINSTALLCONTEXT_USERUNMANAGED,
5978 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5979 ok(r == ERROR_MORE_DATA,
5980 "Expected ERROR_MORE_DATA, got %d\n", r);
5981 ok(sz == 10, "Expected 10, got %d\n", sz);
5982
5983 /* szValue is NULL, pcchValue is exactly 5 */
5984 sz = 5;
5985 r = pMsiGetProductInfoExA(prodcode, usersid,
5986 MSIINSTALLCONTEXT_USERUNMANAGED,
5987 INSTALLPROPERTY_HELPTELEPHONEA, NULL, &sz);
5988 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5989 ok(sz == 10, "Expected 10, got %d\n", sz);
5990
5991 /* szValue is NULL, pcchValue is MAX_PATH */
5992 sz = MAX_PATH;
5993 r = pMsiGetProductInfoExA(prodcode, usersid,
5994 MSIINSTALLCONTEXT_USERUNMANAGED,
5995 INSTALLPROPERTY_HELPTELEPHONEA, NULL, &sz);
5996 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5997 ok(sz == 10, "Expected 10, got %d\n", sz);
5998
5999 /* pcchValue is exactly 0 */
6000 sz = 0;
6001 lstrcpyA(buf, "apple");
6002 r = pMsiGetProductInfoExA(prodcode, usersid,
6003 MSIINSTALLCONTEXT_USERUNMANAGED,
6004 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6005 ok(r == ERROR_MORE_DATA,
6006 "Expected ERROR_MORE_DATA, got %d\n", r);
6007 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
6008 ok(sz == 10, "Expected 10, got %d\n", sz);
6009
6010 res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
6011 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6012
6013 /* szProperty is not a valid property */
6014 sz = MAX_PATH;
6015 lstrcpyA(buf, "apple");
6016 r = pMsiGetProductInfoExA(prodcode, usersid,
6017 MSIINSTALLCONTEXT_USERUNMANAGED,
6018 "notvalid", buf, &sz);
6019 ok(r == ERROR_UNKNOWN_PROPERTY,
6020 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6021 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6022 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6023
6024 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6025 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6026
6027 /* InstallDate value exists */
6028 sz = MAX_PATH;
6029 lstrcpyA(buf, "apple");
6030 r = pMsiGetProductInfoExA(prodcode, usersid,
6031 MSIINSTALLCONTEXT_USERUNMANAGED,
6032 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6033 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6034 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6035 ok(sz == 4, "Expected 4, got %d\n", sz);
6036
6037 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6038 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6039
6040 /* DisplayName value exists */
6041 sz = MAX_PATH;
6042 lstrcpyA(buf, "apple");
6043 r = pMsiGetProductInfoExA(prodcode, usersid,
6044 MSIINSTALLCONTEXT_USERUNMANAGED,
6045 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6046 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6047 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6048 ok(sz == 4, "Expected 4, got %d\n", sz);
6049
6050 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6051 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6052
6053 /* InstallLocation value exists */
6054 sz = MAX_PATH;
6055 lstrcpyA(buf, "apple");
6056 r = pMsiGetProductInfoExA(prodcode, usersid,
6057 MSIINSTALLCONTEXT_USERUNMANAGED,
6058 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6059 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6060 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6061 ok(sz == 3, "Expected 3, got %d\n", sz);
6062
6063 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6064 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6065
6066 /* InstallSource value exists */
6067 sz = MAX_PATH;
6068 lstrcpyA(buf, "apple");
6069 r = pMsiGetProductInfoExA(prodcode, usersid,
6070 MSIINSTALLCONTEXT_USERUNMANAGED,
6071 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6073 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6074 ok(sz == 6, "Expected 6, got %d\n", sz);
6075
6076 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6077 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6078
6079 /* LocalPackage value exists */
6080 sz = MAX_PATH;
6081 lstrcpyA(buf, "apple");
6082 r = pMsiGetProductInfoExA(prodcode, usersid,
6083 MSIINSTALLCONTEXT_USERUNMANAGED,
6084 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6086 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6087 ok(sz == 5, "Expected 5, got %d\n", sz);
6088
6089 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6090 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6091
6092 /* Publisher value exists */
6093 sz = MAX_PATH;
6094 lstrcpyA(buf, "apple");
6095 r = pMsiGetProductInfoExA(prodcode, usersid,
6096 MSIINSTALLCONTEXT_USERUNMANAGED,
6097 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6099 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6100 ok(sz == 3, "Expected 3, got %d\n", sz);
6101
6102 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6103 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6104
6105 /* URLInfoAbout value exists */
6106 sz = MAX_PATH;
6107 lstrcpyA(buf, "apple");
6108 r = pMsiGetProductInfoExA(prodcode, usersid,
6109 MSIINSTALLCONTEXT_USERUNMANAGED,
6110 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6112 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6113 ok(sz == 5, "Expected 5, got %d\n", sz);
6114
6115 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6116 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6117
6118 /* URLUpdateInfo value exists */
6119 sz = MAX_PATH;
6120 lstrcpyA(buf, "apple");
6121 r = pMsiGetProductInfoExA(prodcode, usersid,
6122 MSIINSTALLCONTEXT_USERUNMANAGED,
6123 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6125 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6126 ok(sz == 6, "Expected 6, got %d\n", sz);
6127
6128 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6129 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6130
6131 /* VersionMinor value exists */
6132 sz = MAX_PATH;
6133 lstrcpyA(buf, "apple");
6134 r = pMsiGetProductInfoExA(prodcode, usersid,
6135 MSIINSTALLCONTEXT_USERUNMANAGED,
6136 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6137 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6138 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6139 ok(sz == 1, "Expected 1, got %d\n", sz);
6140
6141 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6142 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6143
6144 /* VersionMajor value exists */
6145 sz = MAX_PATH;
6146 lstrcpyA(buf, "apple");
6147 r = pMsiGetProductInfoExA(prodcode, usersid,
6148 MSIINSTALLCONTEXT_USERUNMANAGED,
6149 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6150 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6151 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6152 ok(sz == 1, "Expected 1, got %d\n", sz);
6153
6154 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6155 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6156
6157 /* DisplayVersion value exists */
6158 sz = MAX_PATH;
6159 lstrcpyA(buf, "apple");
6160 r = pMsiGetProductInfoExA(prodcode, usersid,
6161 MSIINSTALLCONTEXT_USERUNMANAGED,
6162 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6164 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6165 ok(sz == 5, "Expected 5, got %d\n", sz);
6166
6167 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6168 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6169
6170 /* ProductID value exists */
6171 sz = MAX_PATH;
6172 lstrcpyA(buf, "apple");
6173 r = pMsiGetProductInfoExA(prodcode, usersid,
6174 MSIINSTALLCONTEXT_USERUNMANAGED,
6175 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6177 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6178 ok(sz == 2, "Expected 2, got %d\n", sz);
6179
6180 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6181 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6182
6183 /* RegCompany value exists */
6184 sz = MAX_PATH;
6185 lstrcpyA(buf, "apple");
6186 r = pMsiGetProductInfoExA(prodcode, usersid,
6187 MSIINSTALLCONTEXT_USERUNMANAGED,
6188 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6190 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6191 ok(sz == 4, "Expected 4, got %d\n", sz);
6192
6193 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6194 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6195
6196 /* RegOwner value exists */
6197 sz = MAX_PATH;
6198 lstrcpyA(buf, "apple");
6199 r = pMsiGetProductInfoExA(prodcode, usersid,
6200 MSIINSTALLCONTEXT_USERUNMANAGED,
6201 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6202 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6203 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6204 ok(sz == 5, "Expected 5, got %d\n", sz);
6205
6206 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6207 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6208
6209 /* Transforms value exists */
6210 sz = MAX_PATH;
6211 lstrcpyA(buf, "apple");
6212 r = pMsiGetProductInfoExA(prodcode, usersid,
6213 MSIINSTALLCONTEXT_USERUNMANAGED,
6214 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6215 ok(r == ERROR_UNKNOWN_PRODUCT,
6216 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6217 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6218 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6219
6220 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6221 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6222
6223 /* Language value exists */
6224 sz = MAX_PATH;
6225 lstrcpyA(buf, "apple");
6226 r = pMsiGetProductInfoExA(prodcode, usersid,
6227 MSIINSTALLCONTEXT_USERUNMANAGED,
6228 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6229 ok(r == ERROR_UNKNOWN_PRODUCT,
6230 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6231 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6232 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6233
6234 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6235 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6236
6237 /* ProductName value exists */
6238 sz = MAX_PATH;
6239 lstrcpyA(buf, "apple");
6240 r = pMsiGetProductInfoExA(prodcode, usersid,
6241 MSIINSTALLCONTEXT_USERUNMANAGED,
6242 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6243 ok(r == ERROR_UNKNOWN_PRODUCT,
6244 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6245 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6246 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6247
6248 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6249 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6250
6251 /* FIXME */
6252
6253 /* AssignmentType value exists */
6254 sz = MAX_PATH;
6255 lstrcpyA(buf, "apple");
6256 r = pMsiGetProductInfoExA(prodcode, usersid,
6257 MSIINSTALLCONTEXT_USERUNMANAGED,
6258 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
6259 ok(r == ERROR_UNKNOWN_PRODUCT,
6260 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6261 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6262 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6263
6264 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6265 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6266
6267 /* PackageCode value exists */
6268 sz = MAX_PATH;
6269 lstrcpyA(buf, "apple");
6270 r = pMsiGetProductInfoExA(prodcode, usersid,
6271 MSIINSTALLCONTEXT_USERUNMANAGED,
6272 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
6273 ok(r == ERROR_UNKNOWN_PRODUCT,
6274 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6275 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6276 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6277
6278 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6279 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6280
6281 /* Version value exists */
6282 sz = MAX_PATH;
6283 lstrcpyA(buf, "apple");
6284 r = pMsiGetProductInfoExA(prodcode, usersid,
6285 MSIINSTALLCONTEXT_USERUNMANAGED,
6286 INSTALLPROPERTY_VERSIONA, buf, &sz);
6287 ok(r == ERROR_UNKNOWN_PRODUCT,
6288 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6289 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6290 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6291
6292 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6293 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6294
6295 /* ProductIcon value exists */
6296 sz = MAX_PATH;
6297 lstrcpyA(buf, "apple");
6298 r = pMsiGetProductInfoExA(prodcode, usersid,
6299 MSIINSTALLCONTEXT_USERUNMANAGED,
6300 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6301 ok(r == ERROR_UNKNOWN_PRODUCT,
6302 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6303 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6304 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6305
6306 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6307 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6308
6309 /* PackageName value exists */
6310 sz = MAX_PATH;
6311 lstrcpyA(buf, "apple");
6312 r = pMsiGetProductInfoExA(prodcode, usersid,
6313 MSIINSTALLCONTEXT_USERUNMANAGED,
6314 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
6315 ok(r == ERROR_UNKNOWN_PRODUCT,
6316 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6317 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6318 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6319
6320 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6321 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6322
6323 /* AuthorizedLUAApp value exists */
6324 sz = MAX_PATH;
6325 lstrcpyA(buf, "apple");
6326 r = pMsiGetProductInfoExA(prodcode, usersid,
6327 MSIINSTALLCONTEXT_USERUNMANAGED,
6328 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
6329 ok(r == ERROR_UNKNOWN_PRODUCT,
6330 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6331 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6332 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6333
6334 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6335 RegDeleteValueA(propkey, "PackageName");
6336 RegDeleteValueA(propkey, "ProductIcon");
6337 RegDeleteValueA(propkey, "Version");
6338 RegDeleteValueA(propkey, "PackageCode");
6339 RegDeleteValueA(propkey, "AssignmentType");
6340 RegDeleteValueA(propkey, "ProductName");
6341 RegDeleteValueA(propkey, "Language");
6342 RegDeleteValueA(propkey, "Transforms");
6343 RegDeleteValueA(propkey, "RegOwner");
6344 RegDeleteValueA(propkey, "RegCompany");
6345 RegDeleteValueA(propkey, "ProductID");
6346 RegDeleteValueA(propkey, "DisplayVersion");
6347 RegDeleteValueA(propkey, "VersionMajor");
6348 RegDeleteValueA(propkey, "VersionMinor");
6349 RegDeleteValueA(propkey, "URLUpdateInfo");
6350 RegDeleteValueA(propkey, "URLInfoAbout");
6351 RegDeleteValueA(propkey, "Publisher");
6352 RegDeleteValueA(propkey, "LocalPackage");
6353 RegDeleteValueA(propkey, "InstallSource");
6354 RegDeleteValueA(propkey, "InstallLocation");
6355 RegDeleteValueA(propkey, "DisplayName");
6356 RegDeleteValueA(propkey, "InstallDate");
6357 RegDeleteValueA(propkey, "HelpTelephone");
6358 RegDeleteValueA(propkey, "HelpLink");
6359 RegDeleteValueA(propkey, "LocalPackage");
6360 RegDeleteKeyA(propkey, "");
6361 RegCloseKey(propkey);
6362 RegDeleteKeyA(localkey, "");
6363 RegCloseKey(localkey);
6364
6365 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6366 lstrcatA(keypath, usersid);
6367 lstrcatA(keypath, "\\Installer\\Products\\");
6368 lstrcatA(keypath, prod_squashed);
6369
6370 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6372
6373 /* user product key exists */
6374 sz = MAX_PATH;
6375 lstrcpyA(buf, "apple");
6376 r = pMsiGetProductInfoExA(prodcode, usersid,
6377 MSIINSTALLCONTEXT_USERUNMANAGED,
6378 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6379 ok(r == ERROR_UNKNOWN_PRODUCT,
6380 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6381 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6382 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6383
6384 RegDeleteKeyA(userkey, "");
6385 RegCloseKey(userkey);
6386
6387 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6388 lstrcatA(keypath, prod_squashed);
6389
6390 res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6391 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6392
6393 sz = MAX_PATH;
6394 lstrcpyA(buf, "apple");
6395 r = pMsiGetProductInfoExA(prodcode, usersid,
6396 MSIINSTALLCONTEXT_USERUNMANAGED,
6397 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6398 ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
6399 if (r == ERROR_UNKNOWN_PRODUCT)
6400 {
6401 win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
6402 delete_key(prodkey, "", access);
6403 RegCloseKey(prodkey);
6404 return;
6405 }
6406 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6407 ok(sz == 1, "Expected 1, got %d\n", sz);
6408
6409 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6410 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6411
6412 /* HelpLink value exists */
6413 sz = MAX_PATH;
6414 lstrcpyA(buf, "apple");
6415 r = pMsiGetProductInfoExA(prodcode, usersid,
6416 MSIINSTALLCONTEXT_USERUNMANAGED,
6417 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6418 ok(r == ERROR_UNKNOWN_PROPERTY,
6419 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6420 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6421 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6422
6423 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6424 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6425
6426 /* HelpTelephone value exists */
6427 sz = MAX_PATH;
6428 lstrcpyA(buf, "apple");
6429 r = pMsiGetProductInfoExA(prodcode, usersid,
6430 MSIINSTALLCONTEXT_USERUNMANAGED,
6431 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6432 ok(r == ERROR_UNKNOWN_PROPERTY,
6433 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6434 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6435 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6436
6437 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6438 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6439
6440 /* InstallDate value exists */
6441 sz = MAX_PATH;
6442 lstrcpyA(buf, "apple");
6443 r = pMsiGetProductInfoExA(prodcode, usersid,
6444 MSIINSTALLCONTEXT_USERUNMANAGED,
6445 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6446 ok(r == ERROR_UNKNOWN_PROPERTY,
6447 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6448 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6449 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6450
6451 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6452 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6453
6454 /* DisplayName value exists */
6455 sz = MAX_PATH;
6456 lstrcpyA(buf, "apple");
6457 r = pMsiGetProductInfoExA(prodcode, usersid,
6458 MSIINSTALLCONTEXT_USERUNMANAGED,
6459 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6460 ok(r == ERROR_UNKNOWN_PROPERTY,
6461 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6462 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6463 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6464
6465 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6466 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6467
6468 /* InstallLocation value exists */
6469 sz = MAX_PATH;
6470 lstrcpyA(buf, "apple");
6471 r = pMsiGetProductInfoExA(prodcode, usersid,
6472 MSIINSTALLCONTEXT_USERUNMANAGED,
6473 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6474 ok(r == ERROR_UNKNOWN_PROPERTY,
6475 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6476 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6477 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6478
6479 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6481
6482 /* InstallSource value exists */
6483 sz = MAX_PATH;
6484 lstrcpyA(buf, "apple");
6485 r = pMsiGetProductInfoExA(prodcode, usersid,
6486 MSIINSTALLCONTEXT_USERUNMANAGED,
6487 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6488 ok(r == ERROR_UNKNOWN_PROPERTY,
6489 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6490 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6491 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6492
6493 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6494 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6495
6496 /* LocalPackage value exists */
6497 sz = MAX_PATH;
6498 lstrcpyA(buf, "apple");
6499 r = pMsiGetProductInfoExA(prodcode, usersid,
6500 MSIINSTALLCONTEXT_USERUNMANAGED,
6501 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6502 ok(r == ERROR_UNKNOWN_PROPERTY,
6503 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6504 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6505 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6506
6507 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6508 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6509
6510 /* Publisher value exists */
6511 sz = MAX_PATH;
6512 lstrcpyA(buf, "apple");
6513 r = pMsiGetProductInfoExA(prodcode, usersid,
6514 MSIINSTALLCONTEXT_USERUNMANAGED,
6515 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6516 ok(r == ERROR_UNKNOWN_PROPERTY,
6517 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6518 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6519 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6520
6521 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6523
6524 /* URLInfoAbout value exists */
6525 sz = MAX_PATH;
6526 lstrcpyA(buf, "apple");
6527 r = pMsiGetProductInfoExA(prodcode, usersid,
6528 MSIINSTALLCONTEXT_USERUNMANAGED,
6529 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6530 ok(r == ERROR_UNKNOWN_PROPERTY,
6531 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6532 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6533 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6534
6535 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6536 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6537
6538 /* URLUpdateInfo value exists */
6539 sz = MAX_PATH;
6540 lstrcpyA(buf, "apple");
6541 r = pMsiGetProductInfoExA(prodcode, usersid,
6542 MSIINSTALLCONTEXT_USERUNMANAGED,
6543 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6544 ok(r == ERROR_UNKNOWN_PROPERTY,
6545 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6546 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6547 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6548
6549 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6550 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6551
6552 /* VersionMinor value exists */
6553 sz = MAX_PATH;
6554 lstrcpyA(buf, "apple");
6555 r = pMsiGetProductInfoExA(prodcode, usersid,
6556 MSIINSTALLCONTEXT_USERUNMANAGED,
6557 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6558 ok(r == ERROR_UNKNOWN_PROPERTY,
6559 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6560 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6561 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6562
6563 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6564 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6565
6566 /* VersionMajor value exists */
6567 sz = MAX_PATH;
6568 lstrcpyA(buf, "apple");
6569 r = pMsiGetProductInfoExA(prodcode, usersid,
6570 MSIINSTALLCONTEXT_USERUNMANAGED,
6571 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6572 ok(r == ERROR_UNKNOWN_PROPERTY,
6573 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6574 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6575 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6576
6577 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6578 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6579
6580 /* DisplayVersion value exists */
6581 sz = MAX_PATH;
6582 lstrcpyA(buf, "apple");
6583 r = pMsiGetProductInfoExA(prodcode, usersid,
6584 MSIINSTALLCONTEXT_USERUNMANAGED,
6585 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6586 ok(r == ERROR_UNKNOWN_PROPERTY,
6587 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6588 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6589 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6590
6591 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6593
6594 /* ProductID value exists */
6595 sz = MAX_PATH;
6596 lstrcpyA(buf, "apple");
6597 r = pMsiGetProductInfoExA(prodcode, usersid,
6598 MSIINSTALLCONTEXT_USERUNMANAGED,
6599 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6600 ok(r == ERROR_UNKNOWN_PROPERTY,
6601 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6602 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6603 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6604
6605 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6606 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6607
6608 /* RegCompany value exists */
6609 sz = MAX_PATH;
6610 lstrcpyA(buf, "apple");
6611 r = pMsiGetProductInfoExA(prodcode, usersid,
6612 MSIINSTALLCONTEXT_USERUNMANAGED,
6613 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6614 ok(r == ERROR_UNKNOWN_PROPERTY,
6615 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6616 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6617 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6618
6619 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6620 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6621
6622 /* RegOwner value exists */
6623 sz = MAX_PATH;
6624 lstrcpyA(buf, "apple");
6625 r = pMsiGetProductInfoExA(prodcode, usersid,
6626 MSIINSTALLCONTEXT_USERUNMANAGED,
6627 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6628 ok(r == ERROR_UNKNOWN_PROPERTY,
6629 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6630 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6631 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6632
6633 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6634 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6635
6636 /* Transforms value exists */
6637 sz = MAX_PATH;
6638 lstrcpyA(buf, "apple");
6639 r = pMsiGetProductInfoExA(prodcode, usersid,
6640 MSIINSTALLCONTEXT_USERUNMANAGED,
6641 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6642 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6643 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6644 ok(sz == 5, "Expected 5, got %d\n", sz);
6645
6646 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6647 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6648
6649 /* Language value exists */
6650 sz = MAX_PATH;
6651 lstrcpyA(buf, "apple");
6652 r = pMsiGetProductInfoExA(prodcode, usersid,
6653 MSIINSTALLCONTEXT_USERUNMANAGED,
6654 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6656 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6657 ok(sz == 4, "Expected 4, got %d\n", sz);
6658
6659 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6660 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6661
6662 /* ProductName value exists */
6663 sz = MAX_PATH;
6664 lstrcpyA(buf, "apple");
6665 r = pMsiGetProductInfoExA(prodcode, usersid,
6666 MSIINSTALLCONTEXT_USERUNMANAGED,
6667 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6669 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6670 ok(sz == 4, "Expected 4, got %d\n", sz);
6671
6672 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6673 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6674
6675 /* FIXME */
6676
6677 /* AssignmentType value exists */
6678 sz = MAX_PATH;
6679 lstrcpyA(buf, "apple");
6680 r = pMsiGetProductInfoExA(prodcode, usersid,
6681 MSIINSTALLCONTEXT_USERUNMANAGED,
6682 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
6683 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6684 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6685 ok(sz == 0, "Expected 0, got %d\n", sz);
6686
6687 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6688 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6689
6690 /* FIXME */
6691
6692 /* PackageCode value exists */
6693 sz = MAX_PATH;
6694 lstrcpyA(buf, "apple");
6695 r = pMsiGetProductInfoExA(prodcode, usersid,
6696 MSIINSTALLCONTEXT_USERUNMANAGED,
6697 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
6698 todo_wine
6699 {
6700 ok(r == ERROR_BAD_CONFIGURATION,
6701 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6702 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6703 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6704 }
6705
6706 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6707 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6708
6709 /* Version value exists */
6710 sz = MAX_PATH;
6711 lstrcpyA(buf, "apple");
6712 r = pMsiGetProductInfoExA(prodcode, usersid,
6713 MSIINSTALLCONTEXT_USERUNMANAGED,
6714 INSTALLPROPERTY_VERSIONA, buf, &sz);
6715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6716 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6717 ok(sz == 3, "Expected 3, got %d\n", sz);
6718
6719 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6720 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6721
6722 /* ProductIcon value exists */
6723 sz = MAX_PATH;
6724 lstrcpyA(buf, "apple");
6725 r = pMsiGetProductInfoExA(prodcode, usersid,
6726 MSIINSTALLCONTEXT_USERUNMANAGED,
6727 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6729 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6730 ok(sz == 4, "Expected 4, got %d\n", sz);
6731
6732 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6733 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6734
6735 /* PackageName value exists */
6736 sz = MAX_PATH;
6737 lstrcpyA(buf, "apple");
6738 r = pMsiGetProductInfoExA(prodcode, usersid,
6739 MSIINSTALLCONTEXT_USERUNMANAGED,
6740 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
6741 todo_wine
6742 {
6743 ok(r == ERROR_UNKNOWN_PRODUCT,
6744 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6745 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6746 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6747 }
6748
6749 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6750 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6751
6752 /* AuthorizedLUAApp value exists */
6753 sz = MAX_PATH;
6754 lstrcpyA(buf, "apple");
6755 r = pMsiGetProductInfoExA(prodcode, usersid,
6756 MSIINSTALLCONTEXT_USERUNMANAGED,
6757 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
6758 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6759 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6760 ok(sz == 4, "Expected 4, got %d\n", sz);
6761
6762 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6763 RegDeleteValueA(prodkey, "PackageName");
6764 RegDeleteValueA(prodkey, "ProductIcon");
6765 RegDeleteValueA(prodkey, "Version");
6766 RegDeleteValueA(prodkey, "PackageCode");
6767 RegDeleteValueA(prodkey, "AssignmentType");
6768 RegDeleteValueA(prodkey, "ProductName");
6769 RegDeleteValueA(prodkey, "Language");
6770 RegDeleteValueA(prodkey, "Transforms");
6771 RegDeleteValueA(prodkey, "RegOwner");
6772 RegDeleteValueA(prodkey, "RegCompany");
6773 RegDeleteValueA(prodkey, "ProductID");
6774 RegDeleteValueA(prodkey, "DisplayVersion");
6775 RegDeleteValueA(prodkey, "VersionMajor");
6776 RegDeleteValueA(prodkey, "VersionMinor");
6777 RegDeleteValueA(prodkey, "URLUpdateInfo");
6778 RegDeleteValueA(prodkey, "URLInfoAbout");
6779 RegDeleteValueA(prodkey, "Publisher");
6780 RegDeleteValueA(prodkey, "LocalPackage");
6781 RegDeleteValueA(prodkey, "InstallSource");
6782 RegDeleteValueA(prodkey, "InstallLocation");
6783 RegDeleteValueA(prodkey, "DisplayName");
6784 RegDeleteValueA(prodkey, "InstallDate");
6785 RegDeleteValueA(prodkey, "HelpTelephone");
6786 RegDeleteValueA(prodkey, "HelpLink");
6787 RegDeleteValueA(prodkey, "LocalPackage");
6788 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6789 RegCloseKey(prodkey);
6790
6791 /* MSIINSTALLCONTEXT_USERMANAGED */
6792
6793 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
6794 lstrcatA(keypath, usersid);
6795 lstrcatA(keypath, "\\Products\\");
6796 lstrcatA(keypath, prod_squashed);
6797
6798 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6799 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6800
6801 /* local user product key exists */
6802 sz = MAX_PATH;
6803 lstrcpyA(buf, "apple");
6804 r = pMsiGetProductInfoExA(prodcode, usersid,
6805 MSIINSTALLCONTEXT_USERMANAGED,
6806 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6807 ok(r == ERROR_UNKNOWN_PRODUCT,
6808 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6809 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6810 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6811
6812 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6813 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6814
6815 /* InstallProperties key exists */
6816 sz = MAX_PATH;
6817 lstrcpyA(buf, "apple");
6818 r = pMsiGetProductInfoExA(prodcode, usersid,
6819 MSIINSTALLCONTEXT_USERMANAGED,
6820 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6821 ok(r == ERROR_UNKNOWN_PRODUCT,
6822 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6823 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6824 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6825
6826 res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6827 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6828
6829 /* ManagedLocalPackage value exists */
6830 sz = MAX_PATH;
6831 lstrcpyA(buf, "apple");
6832 r = pMsiGetProductInfoExA(prodcode, usersid,
6833 MSIINSTALLCONTEXT_USERMANAGED,
6834 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6836 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6837 ok(sz == 1, "Expected 1, got %d\n", sz);
6838
6839 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6841
6842 /* HelpLink value exists */
6843 sz = MAX_PATH;
6844 lstrcpyA(buf, "apple");
6845 r = pMsiGetProductInfoExA(prodcode, usersid,
6846 MSIINSTALLCONTEXT_USERMANAGED,
6847 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6849 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6850 ok(sz == 4, "Expected 4, got %d\n", sz);
6851
6852 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6853 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6854
6855 /* HelpTelephone value exists */
6856 sz = MAX_PATH;
6857 lstrcpyA(buf, "apple");
6858 r = pMsiGetProductInfoExA(prodcode, usersid,
6859 MSIINSTALLCONTEXT_USERMANAGED,
6860 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6861 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6862 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6863 ok(sz == 5, "Expected 5, got %d\n", sz);
6864
6865 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6866 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6867
6868 /* InstallDate value exists */
6869 sz = MAX_PATH;
6870 lstrcpyA(buf, "apple");
6871 r = pMsiGetProductInfoExA(prodcode, usersid,
6872 MSIINSTALLCONTEXT_USERMANAGED,
6873 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6875 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6876 ok(sz == 4, "Expected 4, got %d\n", sz);
6877
6878 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6879 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6880
6881 /* DisplayName value exists */
6882 sz = MAX_PATH;
6883 lstrcpyA(buf, "apple");
6884 r = pMsiGetProductInfoExA(prodcode, usersid,
6885 MSIINSTALLCONTEXT_USERMANAGED,
6886 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6888 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6889 ok(sz == 4, "Expected 4, got %d\n", sz);
6890
6891 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6892 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6893
6894 /* InstallLocation value exists */
6895 sz = MAX_PATH;
6896 lstrcpyA(buf, "apple");
6897 r = pMsiGetProductInfoExA(prodcode, usersid,
6898 MSIINSTALLCONTEXT_USERMANAGED,
6899 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6900 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6901 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6902 ok(sz == 3, "Expected 3, got %d\n", sz);
6903
6904 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6905 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6906
6907 /* InstallSource value exists */
6908 sz = MAX_PATH;
6909 lstrcpyA(buf, "apple");
6910 r = pMsiGetProductInfoExA(prodcode, usersid,
6911 MSIINSTALLCONTEXT_USERMANAGED,
6912 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6914 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6915 ok(sz == 6, "Expected 6, got %d\n", sz);
6916
6917 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6918 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6919
6920 /* LocalPackage value exists */
6921 sz = MAX_PATH;
6922 lstrcpyA(buf, "apple");
6923 r = pMsiGetProductInfoExA(prodcode, usersid,
6924 MSIINSTALLCONTEXT_USERMANAGED,
6925 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6926 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6927 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6928 ok(sz == 5, "Expected 5, got %d\n", sz);
6929
6930 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6931 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6932
6933 /* Publisher value exists */
6934 sz = MAX_PATH;
6935 lstrcpyA(buf, "apple");
6936 r = pMsiGetProductInfoExA(prodcode, usersid,
6937 MSIINSTALLCONTEXT_USERMANAGED,
6938 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6939 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6940 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6941 ok(sz == 3, "Expected 3, got %d\n", sz);
6942
6943 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6944 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6945
6946 /* URLInfoAbout value exists */
6947 sz = MAX_PATH;
6948 lstrcpyA(buf, "apple");
6949 r = pMsiGetProductInfoExA(prodcode, usersid,
6950 MSIINSTALLCONTEXT_USERMANAGED,
6951 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6952 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6953 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6954 ok(sz == 5, "Expected 5, got %d\n", sz);
6955
6956 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6958
6959 /* URLUpdateInfo value exists */
6960 sz = MAX_PATH;
6961 lstrcpyA(buf, "apple");
6962 r = pMsiGetProductInfoExA(prodcode, usersid,
6963 MSIINSTALLCONTEXT_USERMANAGED,
6964 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6966 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6967 ok(sz == 6, "Expected 6, got %d\n", sz);
6968
6969 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6970 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6971
6972 /* VersionMinor value exists */
6973 sz = MAX_PATH;
6974 lstrcpyA(buf, "apple");
6975 r = pMsiGetProductInfoExA(prodcode, usersid,
6976 MSIINSTALLCONTEXT_USERMANAGED,
6977 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6978 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6979 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6980 ok(sz == 1, "Expected 1, got %d\n", sz);
6981
6982 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6983 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6984
6985 /* VersionMajor value exists */
6986 sz = MAX_PATH;
6987 lstrcpyA(buf, "apple");
6988 r = pMsiGetProductInfoExA(prodcode, usersid,
6989 MSIINSTALLCONTEXT_USERMANAGED,
6990 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6992 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6993 ok(sz == 1, "Expected 1, got %d\n", sz);
6994
6995 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6996 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6997
6998 /* DisplayVersion value exists */
6999 sz = MAX_PATH;
7000 lstrcpyA(buf, "apple");
7001 r = pMsiGetProductInfoExA(prodcode, usersid,
7002 MSIINSTALLCONTEXT_USERMANAGED,
7003 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7005 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
7006 ok(sz == 5, "Expected 5, got %d\n", sz);
7007
7008 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7009 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7010
7011 /* ProductID value exists */
7012 sz = MAX_PATH;
7013 lstrcpyA(buf, "apple");
7014 r = pMsiGetProductInfoExA(prodcode, usersid,
7015 MSIINSTALLCONTEXT_USERMANAGED,
7016 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7018 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
7019 ok(sz == 2, "Expected 2, got %d\n", sz);
7020
7021 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7022 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7023
7024 /* RegCompany value exists */
7025 sz = MAX_PATH;
7026 lstrcpyA(buf, "apple");
7027 r = pMsiGetProductInfoExA(prodcode, usersid,
7028 MSIINSTALLCONTEXT_USERMANAGED,
7029 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7031 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
7032 ok(sz == 4, "Expected 4, got %d\n", sz);
7033
7034 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7035 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7036
7037 /* RegOwner value exists */
7038 sz = MAX_PATH;
7039 lstrcpyA(buf, "apple");
7040 r = pMsiGetProductInfoExA(prodcode, usersid,
7041 MSIINSTALLCONTEXT_USERMANAGED,
7042 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7044 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
7045 ok(sz == 5, "Expected 5, got %d\n", sz);
7046
7047 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7048 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7049
7050 /* Transforms value exists */
7051 sz = MAX_PATH;
7052 lstrcpyA(buf, "apple");
7053 r = pMsiGetProductInfoExA(prodcode, usersid,
7054 MSIINSTALLCONTEXT_USERMANAGED,
7055 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7056 ok(r == ERROR_UNKNOWN_PRODUCT,
7057 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7058 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7059 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7060
7061 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7062 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7063
7064 /* Language value exists */
7065 sz = MAX_PATH;
7066 lstrcpyA(buf, "apple");
7067 r = pMsiGetProductInfoExA(prodcode, usersid,
7068 MSIINSTALLCONTEXT_USERMANAGED,
7069 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7070 ok(r == ERROR_UNKNOWN_PRODUCT,
7071 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7072 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7073 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7074
7075 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7076 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7077
7078 /* ProductName value exists */
7079 sz = MAX_PATH;
7080 lstrcpyA(buf, "apple");
7081 r = pMsiGetProductInfoExA(prodcode, usersid,
7082 MSIINSTALLCONTEXT_USERMANAGED,
7083 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7084 ok(r == ERROR_UNKNOWN_PRODUCT,
7085 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7086 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7087 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7088
7089 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7090 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7091
7092 /* FIXME */
7093
7094 /* AssignmentType value exists */
7095 sz = MAX_PATH;
7096 lstrcpyA(buf, "apple");
7097 r = pMsiGetProductInfoExA(prodcode, usersid,
7098 MSIINSTALLCONTEXT_USERMANAGED,
7099 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7100 ok(r == ERROR_UNKNOWN_PRODUCT,
7101 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7102 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7103 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7104
7105 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7106 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7107
7108 /* PackageCode value exists */
7109 sz = MAX_PATH;
7110 lstrcpyA(buf, "apple");
7111 r = pMsiGetProductInfoExA(prodcode, usersid,
7112 MSIINSTALLCONTEXT_USERMANAGED,
7113 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7114 ok(r == ERROR_UNKNOWN_PRODUCT,
7115 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7116 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7117 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7118
7119 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7120 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7121
7122 /* Version value exists */
7123 sz = MAX_PATH;
7124 lstrcpyA(buf, "apple");
7125 r = pMsiGetProductInfoExA(prodcode, usersid,
7126 MSIINSTALLCONTEXT_USERMANAGED,
7127 INSTALLPROPERTY_VERSIONA, buf, &sz);
7128 ok(r == ERROR_UNKNOWN_PRODUCT,
7129 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7130 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7131 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7132
7133 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7134 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7135
7136 /* ProductIcon value exists */
7137 sz = MAX_PATH;
7138 lstrcpyA(buf, "apple");
7139 r = pMsiGetProductInfoExA(prodcode, usersid,
7140 MSIINSTALLCONTEXT_USERMANAGED,
7141 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7142 ok(r == ERROR_UNKNOWN_PRODUCT,
7143 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7144 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7145 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7146
7147 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7148 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7149
7150 /* PackageName value exists */
7151 sz = MAX_PATH;
7152 lstrcpyA(buf, "apple");
7153 r = pMsiGetProductInfoExA(prodcode, usersid,
7154 MSIINSTALLCONTEXT_USERMANAGED,
7155 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7156 ok(r == ERROR_UNKNOWN_PRODUCT,
7157 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7158 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7159 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7160
7161 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7162 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7163
7164 /* AuthorizedLUAApp value exists */
7165 sz = MAX_PATH;
7166 lstrcpyA(buf, "apple");
7167 r = pMsiGetProductInfoExA(prodcode, usersid,
7168 MSIINSTALLCONTEXT_USERMANAGED,
7169 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7170 ok(r == ERROR_UNKNOWN_PRODUCT,
7171 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7172 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7173 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7174
7175 RegDeleteValueA(propkey, "AuthorizedLUAApp");
7176 RegDeleteValueA(propkey, "PackageName");
7177 RegDeleteValueA(propkey, "ProductIcon");
7178 RegDeleteValueA(propkey, "Version");
7179 RegDeleteValueA(propkey, "PackageCode");
7180 RegDeleteValueA(propkey, "AssignmentType");
7181 RegDeleteValueA(propkey, "ProductName");
7182 RegDeleteValueA(propkey, "Language");
7183 RegDeleteValueA(propkey, "Transforms");
7184 RegDeleteValueA(propkey, "RegOwner");
7185 RegDeleteValueA(propkey, "RegCompany");
7186 RegDeleteValueA(propkey, "ProductID");
7187 RegDeleteValueA(propkey, "DisplayVersion");
7188 RegDeleteValueA(propkey, "VersionMajor");
7189 RegDeleteValueA(propkey, "VersionMinor");
7190 RegDeleteValueA(propkey, "URLUpdateInfo");
7191 RegDeleteValueA(propkey, "URLInfoAbout");
7192 RegDeleteValueA(propkey, "Publisher");
7193 RegDeleteValueA(propkey, "LocalPackage");
7194 RegDeleteValueA(propkey, "InstallSource");
7195 RegDeleteValueA(propkey, "InstallLocation");
7196 RegDeleteValueA(propkey, "DisplayName");
7197 RegDeleteValueA(propkey, "InstallDate");
7198 RegDeleteValueA(propkey, "HelpTelephone");
7199 RegDeleteValueA(propkey, "HelpLink");
7200 RegDeleteValueA(propkey, "ManagedLocalPackage");
7201 delete_key(propkey, "", access & KEY_WOW64_64KEY);
7202 RegCloseKey(propkey);
7203 delete_key(localkey, "", access & KEY_WOW64_64KEY);
7204 RegCloseKey(localkey);
7205
7206 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7207 lstrcatA(keypath, usersid);
7208 lstrcatA(keypath, "\\Installer\\Products\\");
7209 lstrcatA(keypath, prod_squashed);
7210
7211 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7213
7214 /* user product key exists */
7215 sz = MAX_PATH;
7216 lstrcpyA(buf, "apple");
7217 r = pMsiGetProductInfoExA(prodcode, usersid,
7218 MSIINSTALLCONTEXT_USERMANAGED,
7219 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7221 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
7222 ok(sz == 1, "Expected 1, got %d\n", sz);
7223
7224 delete_key(userkey, "", access & KEY_WOW64_64KEY);
7225 RegCloseKey(userkey);
7226
7227 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7228 lstrcatA(keypath, prod_squashed);
7229
7230 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7231 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7232
7233 /* current user product key exists */
7234 sz = MAX_PATH;
7235 lstrcpyA(buf, "apple");
7236 r = pMsiGetProductInfoExA(prodcode, usersid,
7237 MSIINSTALLCONTEXT_USERMANAGED,
7238 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7239 ok(r == ERROR_UNKNOWN_PRODUCT,
7240 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7241 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7242 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7243
7244 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7245 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7246
7247 /* HelpLink value exists, user product key does not exist */
7248 sz = MAX_PATH;
7249 lstrcpyA(buf, "apple");
7250 r = pMsiGetProductInfoExA(prodcode, usersid,
7251 MSIINSTALLCONTEXT_USERMANAGED,
7252 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7253 ok(r == ERROR_UNKNOWN_PRODUCT,
7254 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7255 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7256 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7257
7258 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7259 lstrcatA(keypath, usersid);
7260 lstrcatA(keypath, "\\Installer\\Products\\");
7261 lstrcatA(keypath, prod_squashed);
7262
7263 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7264 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7265
7266 res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7267 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7268
7269 /* HelpLink value exists, user product key does exist */
7270 sz = MAX_PATH;
7271 lstrcpyA(buf, "apple");
7272 r = pMsiGetProductInfoExA(prodcode, usersid,
7273 MSIINSTALLCONTEXT_USERMANAGED,
7274 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7275 ok(r == ERROR_UNKNOWN_PROPERTY,
7276 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7277 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7278 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7279
7280 res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7281 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7282
7283 /* HelpTelephone value exists */
7284 sz = MAX_PATH;
7285 lstrcpyA(buf, "apple");
7286 r = pMsiGetProductInfoExA(prodcode, usersid,
7287 MSIINSTALLCONTEXT_USERMANAGED,
7288 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7289 ok(r == ERROR_UNKNOWN_PROPERTY,
7290 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7291 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7292 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7293
7294 res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7295 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7296
7297 /* InstallDate value exists */
7298 sz = MAX_PATH;
7299 lstrcpyA(buf, "apple");
7300 r = pMsiGetProductInfoExA(prodcode, usersid,
7301 MSIINSTALLCONTEXT_USERMANAGED,
7302 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7303 ok(r == ERROR_UNKNOWN_PROPERTY,
7304 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7305 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7306 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7307
7308 res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7309 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7310
7311 /* DisplayName value exists */
7312 sz = MAX_PATH;
7313 lstrcpyA(buf, "apple");
7314 r = pMsiGetProductInfoExA(prodcode, usersid,
7315 MSIINSTALLCONTEXT_USERMANAGED,
7316 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7317 ok(r == ERROR_UNKNOWN_PROPERTY,
7318 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7319 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7320 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7321
7322 res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7323 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7324
7325 /* InstallLocation value exists */
7326 sz = MAX_PATH;
7327 lstrcpyA(buf, "apple");
7328 r = pMsiGetProductInfoExA(prodcode, usersid,
7329 MSIINSTALLCONTEXT_USERMANAGED,
7330 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7331 ok(r == ERROR_UNKNOWN_PROPERTY,
7332 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7333 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7334 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7335
7336 res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7337 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7338
7339 /* InstallSource value exists */
7340 sz = MAX_PATH;
7341 lstrcpyA(buf, "apple");
7342 r = pMsiGetProductInfoExA(prodcode, usersid,
7343 MSIINSTALLCONTEXT_USERMANAGED,
7344 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7345 ok(r == ERROR_UNKNOWN_PROPERTY,
7346 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7347 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7348 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7349
7350 res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7351 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7352
7353 /* LocalPackage value exists */
7354 sz = MAX_PATH;
7355 lstrcpyA(buf, "apple");
7356 r = pMsiGetProductInfoExA(prodcode, usersid,
7357 MSIINSTALLCONTEXT_USERMANAGED,
7358 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7359 ok(r == ERROR_UNKNOWN_PROPERTY,
7360 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7361 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7362 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7363
7364 res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7365 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7366
7367 /* Publisher value exists */
7368 sz = MAX_PATH;
7369 lstrcpyA(buf, "apple");
7370 r = pMsiGetProductInfoExA(prodcode, usersid,
7371 MSIINSTALLCONTEXT_USERMANAGED,
7372 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7373 ok(r == ERROR_UNKNOWN_PROPERTY,
7374 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7375 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7376 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7377
7378 res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7379 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7380
7381 /* URLInfoAbout value exists */
7382 sz = MAX_PATH;
7383 lstrcpyA(buf, "apple");
7384 r = pMsiGetProductInfoExA(prodcode, usersid,
7385 MSIINSTALLCONTEXT_USERMANAGED,
7386 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7387 ok(r == ERROR_UNKNOWN_PROPERTY,
7388 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7389 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7390 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7391
7392 res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7393 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7394
7395 /* URLUpdateInfo value exists */
7396 sz = MAX_PATH;
7397 lstrcpyA(buf, "apple");
7398 r = pMsiGetProductInfoExA(prodcode, usersid,
7399 MSIINSTALLCONTEXT_USERMANAGED,
7400 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7401 ok(r == ERROR_UNKNOWN_PROPERTY,
7402 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7403 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7404 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7405
7406 res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7407 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7408
7409 /* VersionMinor value exists */
7410 sz = MAX_PATH;
7411 lstrcpyA(buf, "apple");
7412 r = pMsiGetProductInfoExA(prodcode, usersid,
7413 MSIINSTALLCONTEXT_USERMANAGED,
7414 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7415 ok(r == ERROR_UNKNOWN_PROPERTY,
7416 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7417 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7418 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7419
7420 res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7421 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7422
7423 /* VersionMajor value exists */
7424 sz = MAX_PATH;
7425 lstrcpyA(buf, "apple");
7426 r = pMsiGetProductInfoExA(prodcode, usersid,
7427 MSIINSTALLCONTEXT_USERMANAGED,
7428 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7429 ok(r == ERROR_UNKNOWN_PROPERTY,
7430 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7431 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7432 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7433
7434 res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7435 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7436
7437 /* DisplayVersion value exists */
7438 sz = MAX_PATH;
7439 lstrcpyA(buf, "apple");
7440 r = pMsiGetProductInfoExA(prodcode, usersid,
7441 MSIINSTALLCONTEXT_USERMANAGED,
7442 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7443 ok(r == ERROR_UNKNOWN_PROPERTY,
7444 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7445 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7446 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7447
7448 res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7449 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7450
7451 /* ProductID value exists */
7452 sz = MAX_PATH;
7453 lstrcpyA(buf, "apple");
7454 r = pMsiGetProductInfoExA(prodcode, usersid,
7455 MSIINSTALLCONTEXT_USERMANAGED,
7456 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7457 ok(r == ERROR_UNKNOWN_PROPERTY,
7458 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7459 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7460 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7461
7462 res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7463 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7464
7465 /* RegCompany value exists */
7466 sz = MAX_PATH;
7467 lstrcpyA(buf, "apple");
7468 r = pMsiGetProductInfoExA(prodcode, usersid,
7469 MSIINSTALLCONTEXT_USERMANAGED,
7470 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7471 ok(r == ERROR_UNKNOWN_PROPERTY,
7472 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7473 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7474 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7475
7476 res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7477 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7478
7479 /* RegOwner value exists */
7480 sz = MAX_PATH;
7481 lstrcpyA(buf, "apple");
7482 r = pMsiGetProductInfoExA(prodcode, usersid,
7483 MSIINSTALLCONTEXT_USERMANAGED,
7484 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7485 ok(r == ERROR_UNKNOWN_PROPERTY,
7486 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7487 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7488 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7489
7490 res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7491 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7492
7493 /* Transforms value exists */
7494 sz = MAX_PATH;
7495 lstrcpyA(buf, "apple");
7496 r = pMsiGetProductInfoExA(prodcode, usersid,
7497 MSIINSTALLCONTEXT_USERMANAGED,
7498 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7500 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
7501 ok(sz == 5, "Expected 5, got %d\n", sz);
7502
7503 res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7504 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7505
7506 /* Language value exists */
7507 sz = MAX_PATH;
7508 lstrcpyA(buf, "apple");
7509 r = pMsiGetProductInfoExA(prodcode, usersid,
7510 MSIINSTALLCONTEXT_USERMANAGED,
7511 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7513 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
7514 ok(sz == 4, "Expected 4, got %d\n", sz);
7515
7516 res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7517 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7518
7519 /* ProductName value exists */
7520 sz = MAX_PATH;
7521 lstrcpyA(buf, "apple");
7522 r = pMsiGetProductInfoExA(prodcode, usersid,
7523 MSIINSTALLCONTEXT_USERMANAGED,
7524 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7525 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7526 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7527 ok(sz == 4, "Expected 4, got %d\n", sz);
7528
7529 res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7530 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7531
7532 /* FIXME */
7533
7534 /* AssignmentType value exists */
7535 sz = MAX_PATH;
7536 lstrcpyA(buf, "apple");
7537 r = pMsiGetProductInfoExA(prodcode, usersid,
7538 MSIINSTALLCONTEXT_USERMANAGED,
7539 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7541 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7542 ok(sz == 0, "Expected 0, got %d\n", sz);
7543
7544 res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7545 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7546
7547 /* FIXME */
7548
7549 /* PackageCode value exists */
7550 sz = MAX_PATH;
7551 lstrcpyA(buf, "apple");
7552 r = pMsiGetProductInfoExA(prodcode, usersid,
7553 MSIINSTALLCONTEXT_USERMANAGED,
7554 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7555 todo_wine
7556 {
7557 ok(r == ERROR_BAD_CONFIGURATION,
7558 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7559 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7560 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7561 }
7562
7563 res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7564 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7565
7566 /* Version value exists */
7567 sz = MAX_PATH;
7568 lstrcpyA(buf, "apple");
7569 r = pMsiGetProductInfoExA(prodcode, usersid,
7570 MSIINSTALLCONTEXT_USERMANAGED,
7571 INSTALLPROPERTY_VERSIONA, buf, &sz);
7572 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7573 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7574 ok(sz == 3, "Expected 3, got %d\n", sz);
7575
7576 res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7577 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7578
7579 /* ProductIcon value exists */
7580 sz = MAX_PATH;
7581 lstrcpyA(buf, "apple");
7582 r = pMsiGetProductInfoExA(prodcode, usersid,
7583 MSIINSTALLCONTEXT_USERMANAGED,
7584 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7585 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7586 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7587 ok(sz == 4, "Expected 4, got %d\n", sz);
7588
7589 res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7590 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7591
7592 /* PackageName value exists */
7593 sz = MAX_PATH;
7594 lstrcpyA(buf, "apple");
7595 r = pMsiGetProductInfoExA(prodcode, usersid,
7596 MSIINSTALLCONTEXT_USERMANAGED,
7597 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7598 todo_wine
7599 {
7600 ok(r == ERROR_UNKNOWN_PRODUCT,
7601 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7602 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7603 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7604 }
7605
7606 res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7607 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7608
7609 /* AuthorizedLUAApp value exists */
7610 sz = MAX_PATH;
7611 lstrcpyA(buf, "apple");
7612 r = pMsiGetProductInfoExA(prodcode, usersid,
7613 MSIINSTALLCONTEXT_USERMANAGED,
7614 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7615 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7616 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7617 ok(sz == 4, "Expected 4, got %d\n", sz);
7618
7619 RegDeleteValueA(userkey, "AuthorizedLUAApp");
7620 RegDeleteValueA(userkey, "PackageName");
7621 RegDeleteValueA(userkey, "ProductIcon");
7622 RegDeleteValueA(userkey, "Version");
7623 RegDeleteValueA(userkey, "PackageCode");
7624 RegDeleteValueA(userkey, "AssignmentType");
7625 RegDeleteValueA(userkey, "ProductName");
7626 RegDeleteValueA(userkey, "Language");
7627 RegDeleteValueA(userkey, "Transforms");
7628 RegDeleteValueA(userkey, "RegOwner");
7629 RegDeleteValueA(userkey, "RegCompany");
7630 RegDeleteValueA(userkey, "ProductID");
7631 RegDeleteValueA(userkey, "DisplayVersion");
7632 RegDeleteValueA(userkey, "VersionMajor");
7633 RegDeleteValueA(userkey, "VersionMinor");
7634 RegDeleteValueA(userkey, "URLUpdateInfo");
7635 RegDeleteValueA(userkey, "URLInfoAbout");
7636 RegDeleteValueA(userkey, "Publisher");
7637 RegDeleteValueA(userkey, "LocalPackage");
7638 RegDeleteValueA(userkey, "InstallSource");
7639 RegDeleteValueA(userkey, "InstallLocation");
7640 RegDeleteValueA(userkey, "DisplayName");
7641 RegDeleteValueA(userkey, "InstallDate");
7642 RegDeleteValueA(userkey, "HelpTelephone");
7643 RegDeleteValueA(userkey, "HelpLink");
7644 delete_key(userkey, "", access & KEY_WOW64_64KEY);
7645 RegCloseKey(userkey);
7646 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7647 RegCloseKey(prodkey);
7648
7649 /* MSIINSTALLCONTEXT_MACHINE */
7650
7651 /* szUserSid is non-NULL */
7652 sz = MAX_PATH;
7653 lstrcpyA(buf, "apple");
7654 r = pMsiGetProductInfoExA(prodcode, usersid,
7655 MSIINSTALLCONTEXT_MACHINE,
7656 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7657 ok(r == ERROR_INVALID_PARAMETER,
7658 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7659 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7660 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7661
7662 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
7663 lstrcatA(keypath, prod_squashed);
7664
7665 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
7666 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7667
7668 /* local system product key exists */
7669 sz = MAX_PATH;
7670 lstrcpyA(buf, "apple");
7671 r = pMsiGetProductInfoExA(prodcode, NULL,
7672 MSIINSTALLCONTEXT_MACHINE,
7673 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7674 ok(r == ERROR_UNKNOWN_PRODUCT,
7675 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7676 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7677 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7678
7679 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
7680 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7681
7682 /* InstallProperties key exists */
7683 sz = MAX_PATH;
7684 lstrcpyA(buf, "apple");
7685 r = pMsiGetProductInfoExA(prodcode, NULL,
7686 MSIINSTALLCONTEXT_MACHINE,
7687 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7688 ok(r == ERROR_UNKNOWN_PRODUCT,
7689 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7690 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7691 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7692
7693 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7695
7696 /* LocalPackage value exists */
7697 sz = MAX_PATH;
7698 lstrcpyA(buf, "apple");
7699 r = pMsiGetProductInfoExA(prodcode, NULL,
7700 MSIINSTALLCONTEXT_MACHINE,
7701 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7703 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
7704 ok(sz == 1, "Expected 1, got %d\n", sz);
7705
7706 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7707 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7708
7709 /* HelpLink value exists */
7710 sz = MAX_PATH;
7711 lstrcpyA(buf, "apple");
7712 r = pMsiGetProductInfoExA(prodcode, NULL,
7713 MSIINSTALLCONTEXT_MACHINE,
7714 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7716 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
7717 ok(sz == 4, "Expected 4, got %d\n", sz);
7718
7719 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7720 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7721
7722 /* HelpTelephone value exists */
7723 sz = MAX_PATH;
7724 lstrcpyA(buf, "apple");
7725 r = pMsiGetProductInfoExA(prodcode, NULL,
7726 MSIINSTALLCONTEXT_MACHINE,
7727 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7729 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
7730 ok(sz == 5, "Expected 5, got %d\n", sz);
7731
7732 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7733 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7734
7735 /* InstallDate value exists */
7736 sz = MAX_PATH;
7737 lstrcpyA(buf, "apple");
7738 r = pMsiGetProductInfoExA(prodcode, NULL,
7739 MSIINSTALLCONTEXT_MACHINE,
7740 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7742 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
7743 ok(sz == 4, "Expected 4, got %d\n", sz);
7744
7745 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7746 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7747
7748 /* DisplayName value exists */
7749 sz = MAX_PATH;
7750 lstrcpyA(buf, "apple");
7751 r = pMsiGetProductInfoExA(prodcode, NULL,
7752 MSIINSTALLCONTEXT_MACHINE,
7753 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7755 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7756 ok(sz == 4, "Expected 4, got %d\n", sz);
7757
7758 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7759 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7760
7761 /* InstallLocation value exists */
7762 sz = MAX_PATH;
7763 lstrcpyA(buf, "apple");
7764 r = pMsiGetProductInfoExA(prodcode, NULL,
7765 MSIINSTALLCONTEXT_MACHINE,
7766 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7767 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7768 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
7769 ok(sz == 3, "Expected 3, got %d\n", sz);
7770
7771 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7772 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7773
7774 /* InstallSource value exists */
7775 sz = MAX_PATH;
7776 lstrcpyA(buf, "apple");
7777 r = pMsiGetProductInfoExA(prodcode, NULL,
7778 MSIINSTALLCONTEXT_MACHINE,
7779 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7780 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7781 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
7782 ok(sz == 6, "Expected 6, got %d\n", sz);
7783
7784 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7785 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7786
7787 /* LocalPackage value exists */
7788 sz = MAX_PATH;
7789 lstrcpyA(buf, "apple");
7790 r = pMsiGetProductInfoExA(prodcode, NULL,
7791 MSIINSTALLCONTEXT_MACHINE,
7792 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7793 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7794 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
7795 ok(sz == 5, "Expected 5, got %d\n", sz);
7796
7797 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7798 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7799
7800 /* Publisher value exists */
7801 sz = MAX_PATH;
7802 lstrcpyA(buf, "apple");
7803 r = pMsiGetProductInfoExA(prodcode, NULL,
7804 MSIINSTALLCONTEXT_MACHINE,
7805 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7806 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7807 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
7808 ok(sz == 3, "Expected 3, got %d\n", sz);
7809
7810 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7811 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7812
7813 /* URLInfoAbout value exists */
7814 sz = MAX_PATH;
7815 lstrcpyA(buf, "apple");
7816 r = pMsiGetProductInfoExA(prodcode, NULL,
7817 MSIINSTALLCONTEXT_MACHINE,
7818 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7820 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
7821 ok(sz == 5, "Expected 5, got %d\n", sz);
7822
7823 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7824 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7825
7826 /* URLUpdateInfo value exists */
7827 sz = MAX_PATH;
7828 lstrcpyA(buf, "apple");
7829 r = pMsiGetProductInfoExA(prodcode, NULL,
7830 MSIINSTALLCONTEXT_MACHINE,
7831 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7832 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7833 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
7834 ok(sz == 6, "Expected 6, got %d\n", sz);
7835
7836 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7837 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7838
7839 /* VersionMinor value exists */
7840 sz = MAX_PATH;
7841 lstrcpyA(buf, "apple");
7842 r = pMsiGetProductInfoExA(prodcode, NULL,
7843 MSIINSTALLCONTEXT_MACHINE,
7844 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7845 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7846 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
7847 ok(sz == 1, "Expected 1, got %d\n", sz);
7848
7849 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7850 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7851
7852 /* VersionMajor value exists */
7853 sz = MAX_PATH;
7854 lstrcpyA(buf, "apple");
7855 r = pMsiGetProductInfoExA(prodcode, NULL,
7856 MSIINSTALLCONTEXT_MACHINE,
7857 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7858 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7859 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
7860 ok(sz == 1, "Expected 1, got %d\n", sz);
7861
7862 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7863 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7864
7865 /* DisplayVersion value exists */
7866 sz = MAX_PATH;
7867 lstrcpyA(buf, "apple");
7868 r = pMsiGetProductInfoExA(prodcode, NULL,
7869 MSIINSTALLCONTEXT_MACHINE,
7870 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7872 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
7873 ok(sz == 5, "Expected 5, got %d\n", sz);
7874
7875 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7876 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7877
7878 /* ProductID value exists */
7879 sz = MAX_PATH;
7880 lstrcpyA(buf, "apple");
7881 r = pMsiGetProductInfoExA(prodcode, NULL,
7882 MSIINSTALLCONTEXT_MACHINE,
7883 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7884 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7885 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
7886 ok(sz == 2, "Expected 2, got %d\n", sz);
7887
7888 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7889 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7890
7891 /* RegCompany value exists */
7892 sz = MAX_PATH;
7893 lstrcpyA(buf, "apple");
7894 r = pMsiGetProductInfoExA(prodcode, NULL,
7895 MSIINSTALLCONTEXT_MACHINE,
7896 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7897 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7898 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
7899 ok(sz == 4, "Expected 4, got %d\n", sz);
7900
7901 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7902 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7903
7904 /* RegOwner value exists */
7905 sz = MAX_PATH;
7906 lstrcpyA(buf, "apple");
7907 r = pMsiGetProductInfoExA(prodcode, NULL,
7908 MSIINSTALLCONTEXT_MACHINE,
7909 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7910 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7911 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
7912 ok(sz == 5, "Expected 5, got %d\n", sz);
7913
7914 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7915 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7916
7917 /* Transforms value exists */
7918 sz = MAX_PATH;
7919 lstrcpyA(buf, "apple");
7920 r = pMsiGetProductInfoExA(prodcode, NULL,
7921 MSIINSTALLCONTEXT_MACHINE,
7922 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7923 ok(r == ERROR_UNKNOWN_PRODUCT,
7924 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7925 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7926 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7927
7928 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7929 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7930
7931 /* Language value exists */
7932 sz = MAX_PATH;
7933 lstrcpyA(buf, "apple");
7934 r = pMsiGetProductInfoExA(prodcode, NULL,
7935 MSIINSTALLCONTEXT_MACHINE,
7936 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7937 ok(r == ERROR_UNKNOWN_PRODUCT,
7938 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7939 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7940 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7941
7942 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7943 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7944
7945 /* ProductName value exists */
7946 sz = MAX_PATH;
7947 lstrcpyA(buf, "apple");
7948 r = pMsiGetProductInfoExA(prodcode, NULL,
7949 MSIINSTALLCONTEXT_MACHINE,
7950 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7951 ok(r == ERROR_UNKNOWN_PRODUCT,
7952 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7953 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7954 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7955
7956 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7958
7959 /* FIXME */
7960
7961 /* AssignmentType value exists */
7962 sz = MAX_PATH;
7963 lstrcpyA(buf, "apple");
7964 r = pMsiGetProductInfoExA(prodcode, NULL,
7965 MSIINSTALLCONTEXT_MACHINE,
7966 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7967 ok(r == ERROR_UNKNOWN_PRODUCT,
7968 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7969 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7970 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7971
7972 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7973 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7974
7975 /* PackageCode value exists */
7976 sz = MAX_PATH;
7977 lstrcpyA(buf, "apple");
7978 r = pMsiGetProductInfoExA(prodcode, NULL,
7979 MSIINSTALLCONTEXT_MACHINE,
7980 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7981 ok(r == ERROR_UNKNOWN_PRODUCT,
7982 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7983 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7984 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7985
7986 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7987 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7988
7989 /* Version value exists */
7990 sz = MAX_PATH;
7991 lstrcpyA(buf, "apple");
7992 r = pMsiGetProductInfoExA(prodcode, NULL,
7993 MSIINSTALLCONTEXT_MACHINE,
7994 INSTALLPROPERTY_VERSIONA, buf, &sz);
7995 ok(r == ERROR_UNKNOWN_PRODUCT,
7996 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7997 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7998 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7999
8000 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
8001 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8002
8003 /* ProductIcon value exists */
8004 sz = MAX_PATH;
8005 lstrcpyA(buf, "apple");
8006 r = pMsiGetProductInfoExA(prodcode, NULL,
8007 MSIINSTALLCONTEXT_MACHINE,
8008 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
8009 ok(r == ERROR_UNKNOWN_PRODUCT,
8010 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8011 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8012 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8013
8014 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
8015 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8016
8017 /* PackageName value exists */
8018 sz = MAX_PATH;
8019 lstrcpyA(buf, "apple");
8020 r = pMsiGetProductInfoExA(prodcode, NULL,
8021 MSIINSTALLCONTEXT_MACHINE,
8022 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
8023 ok(r == ERROR_UNKNOWN_PRODUCT,
8024 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8025 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8026 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8027
8028 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
8029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8030
8031 /* AuthorizedLUAApp value exists */
8032 sz = MAX_PATH;
8033 lstrcpyA(buf, "apple");
8034 r = pMsiGetProductInfoExA(prodcode, NULL,
8035 MSIINSTALLCONTEXT_MACHINE,
8036 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
8037 ok(r == ERROR_UNKNOWN_PRODUCT,
8038 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8039 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8040 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8041
8042 RegDeleteValueA(propkey, "AuthorizedLUAApp");
8043 RegDeleteValueA(propkey, "PackageName");
8044 RegDeleteValueA(propkey, "ProductIcon");
8045 RegDeleteValueA(propkey, "Version");
8046 RegDeleteValueA(propkey, "PackageCode");
8047 RegDeleteValueA(propkey, "AssignmentType");
8048 RegDeleteValueA(propkey, "ProductName");
8049 RegDeleteValueA(propkey, "Language");
8050 RegDeleteValueA(propkey, "Transforms");
8051 RegDeleteValueA(propkey, "RegOwner");
8052 RegDeleteValueA(propkey, "RegCompany");
8053 RegDeleteValueA(propkey, "ProductID");
8054 RegDeleteValueA(propkey, "DisplayVersion");
8055 RegDeleteValueA(propkey, "VersionMajor");
8056 RegDeleteValueA(propkey, "VersionMinor");
8057 RegDeleteValueA(propkey, "URLUpdateInfo");
8058 RegDeleteValueA(propkey, "URLInfoAbout");
8059 RegDeleteValueA(propkey, "Publisher");
8060 RegDeleteValueA(propkey, "LocalPackage");
8061 RegDeleteValueA(propkey, "InstallSource");
8062 RegDeleteValueA(propkey, "InstallLocation");
8063 RegDeleteValueA(propkey, "DisplayName");
8064 RegDeleteValueA(propkey, "InstallDate");
8065 RegDeleteValueA(propkey, "HelpTelephone");
8066 RegDeleteValueA(propkey, "HelpLink");
8067 RegDeleteValueA(propkey, "LocalPackage");
8068 delete_key(propkey, "", access & KEY_WOW64_64KEY);
8069 RegCloseKey(propkey);
8070 delete_key(localkey, "", access & KEY_WOW64_64KEY);
8071 RegCloseKey(localkey);
8072
8073 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8074 lstrcatA(keypath, prod_squashed);
8075
8076 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8077 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8078
8079 /* local classes product key exists */
8080 sz = MAX_PATH;
8081 lstrcpyA(buf, "apple");
8082 r = pMsiGetProductInfoExA(prodcode, NULL,
8083 MSIINSTALLCONTEXT_MACHINE,
8084 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
8085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8086 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
8087 ok(sz == 1, "Expected 1, got %d\n", sz);
8088
8089 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
8090 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8091
8092 /* HelpLink value exists */
8093 sz = MAX_PATH;
8094 lstrcpyA(buf, "apple");
8095 r = pMsiGetProductInfoExA(prodcode, NULL,
8096 MSIINSTALLCONTEXT_MACHINE,
8097 INSTALLPROPERTY_HELPLINKA, buf, &sz);
8098 ok(r == ERROR_UNKNOWN_PROPERTY,
8099 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8100 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8101 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8102
8103 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
8104 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8105
8106 /* HelpTelephone value exists */
8107 sz = MAX_PATH;
8108 lstrcpyA(buf, "apple");
8109 r = pMsiGetProductInfoExA(prodcode, NULL,
8110 MSIINSTALLCONTEXT_MACHINE,
8111 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
8112 ok(r == ERROR_UNKNOWN_PROPERTY,
8113 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8114 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8115 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8116
8117 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
8118 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8119
8120 /* InstallDate value exists */
8121 sz = MAX_PATH;
8122 lstrcpyA(buf, "apple");
8123 r = pMsiGetProductInfoExA(prodcode, NULL,
8124 MSIINSTALLCONTEXT_MACHINE,
8125 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
8126 ok(r == ERROR_UNKNOWN_PROPERTY,
8127 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8128 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8129 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8130
8131 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
8132 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8133
8134 /* DisplayName value exists */
8135 sz = MAX_PATH;
8136 lstrcpyA(buf, "apple");
8137 r = pMsiGetProductInfoExA(prodcode, NULL,
8138 MSIINSTALLCONTEXT_MACHINE,
8139 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
8140 ok(r == ERROR_UNKNOWN_PROPERTY,
8141 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8142 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8143 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8144
8145 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
8146 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8147
8148 /* InstallLocation value exists */
8149 sz = MAX_PATH;
8150 lstrcpyA(buf, "apple");
8151 r = pMsiGetProductInfoExA(prodcode, NULL,
8152 MSIINSTALLCONTEXT_MACHINE,
8153 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
8154 ok(r == ERROR_UNKNOWN_PROPERTY,
8155 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8156 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8157 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8158
8159 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
8160 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8161
8162 /* InstallSource value exists */
8163 sz = MAX_PATH;
8164 lstrcpyA(buf, "apple");
8165 r = pMsiGetProductInfoExA(prodcode, NULL,
8166 MSIINSTALLCONTEXT_MACHINE,
8167 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
8168 ok(r == ERROR_UNKNOWN_PROPERTY,
8169 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8170 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8171 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8172
8173 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
8174 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8175
8176 /* LocalPackage value exists */
8177 sz = MAX_PATH;
8178 lstrcpyA(buf, "apple");
8179 r = pMsiGetProductInfoExA(prodcode, NULL,
8180 MSIINSTALLCONTEXT_MACHINE,
8181 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
8182 ok(r == ERROR_UNKNOWN_PROPERTY,
8183 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8184 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8185 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8186
8187 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
8188 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8189
8190 /* Publisher value exists */
8191 sz = MAX_PATH;
8192 lstrcpyA(buf, "apple");
8193 r = pMsiGetProductInfoExA(prodcode, NULL,
8194 MSIINSTALLCONTEXT_MACHINE,
8195 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
8196 ok(r == ERROR_UNKNOWN_PROPERTY,
8197 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8198 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8199 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8200
8201 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
8202 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8203
8204 /* URLInfoAbout value exists */
8205 sz = MAX_PATH;
8206 lstrcpyA(buf, "apple");
8207 r = pMsiGetProductInfoExA(prodcode, NULL,
8208 MSIINSTALLCONTEXT_MACHINE,
8209 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
8210 ok(r == ERROR_UNKNOWN_PROPERTY,
8211 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8212 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8213 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8214
8215 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
8216 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8217
8218 /* URLUpdateInfo value exists */
8219 sz = MAX_PATH;
8220 lstrcpyA(buf, "apple");
8221 r = pMsiGetProductInfoExA(prodcode, NULL,
8222 MSIINSTALLCONTEXT_MACHINE,
8223 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
8224 ok(r == ERROR_UNKNOWN_PROPERTY,
8225 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8226 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8227 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8228
8229 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
8230 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8231
8232 /* VersionMinor value exists */
8233 sz = MAX_PATH;
8234 lstrcpyA(buf, "apple");
8235 r = pMsiGetProductInfoExA(prodcode, NULL,
8236 MSIINSTALLCONTEXT_MACHINE,
8237 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
8238 ok(r == ERROR_UNKNOWN_PROPERTY,
8239 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8240 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8241 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8242
8243 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
8244 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8245
8246 /* VersionMajor value exists */
8247 sz = MAX_PATH;
8248 lstrcpyA(buf, "apple");
8249 r = pMsiGetProductInfoExA(prodcode, NULL,
8250 MSIINSTALLCONTEXT_MACHINE,
8251 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
8252 ok(r == ERROR_UNKNOWN_PROPERTY,
8253 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8254 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8255 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8256
8257 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
8258 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8259
8260 /* DisplayVersion value exists */
8261 sz = MAX_PATH;
8262 lstrcpyA(buf, "apple");
8263 r = pMsiGetProductInfoExA(prodcode, NULL,
8264 MSIINSTALLCONTEXT_MACHINE,
8265 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
8266 ok(r == ERROR_UNKNOWN_PROPERTY,
8267 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8268 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8269 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8270
8271 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
8272 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8273
8274 /* ProductID value exists */
8275 sz = MAX_PATH;
8276 lstrcpyA(buf, "apple");
8277 r = pMsiGetProductInfoExA(prodcode, NULL,
8278 MSIINSTALLCONTEXT_MACHINE,
8279 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
8280 ok(r == ERROR_UNKNOWN_PROPERTY,
8281 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8282 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8283 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8284
8285 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
8286 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8287
8288 /* RegCompany value exists */
8289 sz = MAX_PATH;
8290 lstrcpyA(buf, "apple");
8291 r = pMsiGetProductInfoExA(prodcode, NULL,
8292 MSIINSTALLCONTEXT_MACHINE,
8293 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
8294 ok(r == ERROR_UNKNOWN_PROPERTY,
8295 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8296 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8297 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8298
8299 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8301
8302 /* RegOwner value exists */
8303 sz = MAX_PATH;
8304 lstrcpyA(buf, "apple");
8305 r = pMsiGetProductInfoExA(prodcode, NULL,
8306 MSIINSTALLCONTEXT_MACHINE,
8307 INSTALLPROPERTY_REGOWNERA, buf, &sz);
8308 ok(r == ERROR_UNKNOWN_PROPERTY,
8309 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8310 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8311 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8312
8313 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
8314 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8315
8316 /* Transforms value exists */
8317 sz = MAX_PATH;
8318 lstrcpyA(buf, "apple");
8319 r = pMsiGetProductInfoExA(prodcode, NULL,
8320 MSIINSTALLCONTEXT_MACHINE,
8321 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
8322 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8323 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
8324 ok(sz == 5, "Expected 5, got %d\n", sz);
8325
8326 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
8327 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8328
8329 /* Language value exists */
8330 sz = MAX_PATH;
8331 lstrcpyA(buf, "apple");
8332 r = pMsiGetProductInfoExA(prodcode, NULL,
8333 MSIINSTALLCONTEXT_MACHINE,
8334 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
8335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8336 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
8337 ok(sz == 4, "Expected 4, got %d\n", sz);
8338
8339 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
8340 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8341
8342 /* ProductName value exists */
8343 sz = MAX_PATH;
8344 lstrcpyA(buf, "apple");
8345 r = pMsiGetProductInfoExA(prodcode, NULL,
8346 MSIINSTALLCONTEXT_MACHINE,
8347 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
8348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8349 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
8350 ok(sz == 4, "Expected 4, got %d\n", sz);
8351
8352 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
8353 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8354
8355 /* FIXME */
8356
8357 /* AssignmentType value exists */
8358 sz = MAX_PATH;
8359 lstrcpyA(buf, "apple");
8360 r = pMsiGetProductInfoExA(prodcode, NULL,
8361 MSIINSTALLCONTEXT_MACHINE,
8362 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
8363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8364 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8365 ok(sz == 0, "Expected 0, got %d\n", sz);
8366
8367 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
8368 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8369
8370 /* FIXME */
8371
8372 /* PackageCode value exists */
8373 sz = MAX_PATH;
8374 lstrcpyA(buf, "apple");
8375 r = pMsiGetProductInfoExA(prodcode, NULL,
8376 MSIINSTALLCONTEXT_MACHINE,
8377 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
8378 todo_wine
8379 {
8380 ok(r == ERROR_BAD_CONFIGURATION,
8381 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8382 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8383 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8384 }
8385
8386 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
8387 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8388
8389 /* Version value exists */
8390 sz = MAX_PATH;
8391 lstrcpyA(buf, "apple");
8392 r = pMsiGetProductInfoExA(prodcode, NULL,
8393 MSIINSTALLCONTEXT_MACHINE,
8394 INSTALLPROPERTY_VERSIONA, buf, &sz);
8395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8396 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
8397 ok(sz == 3, "Expected 3, got %d\n", sz);
8398
8399 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
8400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8401
8402 /* ProductIcon value exists */
8403 sz = MAX_PATH;
8404 lstrcpyA(buf, "apple");
8405 r = pMsiGetProductInfoExA(prodcode, NULL,
8406 MSIINSTALLCONTEXT_MACHINE,
8407 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
8408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8409 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
8410 ok(sz == 4, "Expected 4, got %d\n", sz);
8411
8412 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
8413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8414
8415 /* PackageName value exists */
8416 sz = MAX_PATH;
8417 lstrcpyA(buf, "apple");
8418 r = pMsiGetProductInfoExA(prodcode, NULL,
8419 MSIINSTALLCONTEXT_MACHINE,
8420 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
8421 todo_wine
8422 {
8423 ok(r == ERROR_UNKNOWN_PRODUCT,
8424 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8425 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8426 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8427 }
8428
8429 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
8430 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8431
8432 /* AuthorizedLUAApp value exists */
8433 sz = MAX_PATH;
8434 lstrcpyA(buf, "apple");
8435 r = pMsiGetProductInfoExA(prodcode, NULL,
8436 MSIINSTALLCONTEXT_MACHINE,
8437 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
8438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8439 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
8440 ok(sz == 4, "Expected 4, got %d\n", sz);
8441
8442 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
8443 RegDeleteValueA(prodkey, "PackageName");
8444 RegDeleteValueA(prodkey, "ProductIcon");
8445 RegDeleteValueA(prodkey, "Version");
8446 RegDeleteValueA(prodkey, "PackageCode");
8447 RegDeleteValueA(prodkey, "AssignmentType");
8448 RegDeleteValueA(prodkey, "ProductName");
8449 RegDeleteValueA(prodkey, "Language");
8450 RegDeleteValueA(prodkey, "Transforms");
8451 RegDeleteValueA(prodkey, "RegOwner");
8452 RegDeleteValueA(prodkey, "RegCompany");
8453 RegDeleteValueA(prodkey, "ProductID");
8454 RegDeleteValueA(prodkey, "DisplayVersion");
8455 RegDeleteValueA(prodkey, "VersionMajor");
8456 RegDeleteValueA(prodkey, "VersionMinor");
8457 RegDeleteValueA(prodkey, "URLUpdateInfo");
8458 RegDeleteValueA(prodkey, "URLInfoAbout");
8459 RegDeleteValueA(prodkey, "Publisher");
8460 RegDeleteValueA(prodkey, "LocalPackage");
8461 RegDeleteValueA(prodkey, "InstallSource");
8462 RegDeleteValueA(prodkey, "InstallLocation");
8463 RegDeleteValueA(prodkey, "DisplayName");
8464 RegDeleteValueA(prodkey, "InstallDate");
8465 RegDeleteValueA(prodkey, "HelpTelephone");
8466 RegDeleteValueA(prodkey, "HelpLink");
8467 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8468 RegCloseKey(prodkey);
8469 LocalFree(usersid);
8470 }
8471
8472 #define INIT_USERINFO() \
8473 lstrcpyA(user, "apple"); \
8474 lstrcpyA(org, "orange"); \
8475 lstrcpyA(serial, "banana"); \
8476 usersz = orgsz = serialsz = MAX_PATH;
8477
8478 static void test_MsiGetUserInfo(void)
8479 {
8480 USERINFOSTATE state;
8481 CHAR user[MAX_PATH];
8482 CHAR org[MAX_PATH];
8483 CHAR serial[MAX_PATH];
8484 DWORD usersz, orgsz, serialsz;
8485 CHAR keypath[MAX_PATH * 2];
8486 CHAR prodcode[MAX_PATH];
8487 CHAR prod_squashed[MAX_PATH];
8488 HKEY prodkey, userprod, props;
8489 LPSTR usersid;
8490 LONG res;
8491 REGSAM access = KEY_ALL_ACCESS;
8492
8493 create_test_guid(prodcode, prod_squashed);
8494 usersid = get_user_sid();
8495
8496 if (is_wow64)
8497 access |= KEY_WOW64_64KEY;
8498
8499 /* NULL szProduct */
8500 INIT_USERINFO();
8501 state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
8502 ok(state == USERINFOSTATE_INVALIDARG,
8503 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8504 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8505 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8506 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8507 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8508 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8509 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8510
8511 /* empty szProductCode */
8512 INIT_USERINFO();
8513 state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
8514 ok(state == USERINFOSTATE_INVALIDARG,
8515 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8516 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8517 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8518 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8519 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8520 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8521 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8522
8523 /* garbage szProductCode */
8524 INIT_USERINFO();
8525 state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
8526 ok(state == USERINFOSTATE_INVALIDARG,
8527 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8528 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8529 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8530 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8531 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8532 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8533 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8534
8535 /* guid without brackets */
8536 INIT_USERINFO();
8537 state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
8538 user, &usersz, org, &orgsz, serial, &serialsz);
8539 ok(state == USERINFOSTATE_INVALIDARG,
8540 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8541 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8542 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8543 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8544 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8545 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8546 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8547
8548 /* guid with brackets */
8549 INIT_USERINFO();
8550 state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
8551 user, &usersz, org, &orgsz, serial, &serialsz);
8552 ok(state == USERINFOSTATE_UNKNOWN,
8553 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8554 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8555 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8556 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8557 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8558 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8559 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8560
8561 /* NULL lpUserNameBuf */
8562 INIT_USERINFO();
8563 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8564 ok(state == USERINFOSTATE_UNKNOWN,
8565 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8566 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8567 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8568 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8569 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8570 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8571
8572 /* NULL pcchUserNameBuf */
8573 INIT_USERINFO();
8574 state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
8575 ok(state == USERINFOSTATE_INVALIDARG,
8576 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8577 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8578 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8579 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8580 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8581 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8582
8583 /* both lpUserNameBuf and pcchUserNameBuf NULL */
8584 INIT_USERINFO();
8585 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8586 ok(state == USERINFOSTATE_UNKNOWN,
8587 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8588 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8589 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8590 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8591 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8592
8593 /* NULL lpOrgNameBuf */
8594 INIT_USERINFO();
8595 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
8596 ok(state == USERINFOSTATE_UNKNOWN,
8597 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8598 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8599 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8600 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8601 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8602 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8603
8604 /* NULL pcchOrgNameBuf */
8605 INIT_USERINFO();
8606 state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
8607 ok(state == USERINFOSTATE_INVALIDARG,
8608 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8609 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8610 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8611 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8612 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8613 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8614
8615 /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
8616 INIT_USERINFO();
8617 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
8618 ok(state == USERINFOSTATE_UNKNOWN,
8619 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8620 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8621 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8622 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8623 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8624
8625 /* NULL lpSerialBuf */
8626 INIT_USERINFO();
8627 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
8628 ok(state == USERINFOSTATE_UNKNOWN,
8629 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8630 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8631 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8632 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8633 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8634 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8635
8636 /* NULL pcchSerialBuf */
8637 INIT_USERINFO();
8638 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
8639 ok(state == USERINFOSTATE_INVALIDARG,
8640 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8641 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8642 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8643 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8644 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8645 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8646
8647 /* both lpSerialBuf and pcchSerialBuf NULL */
8648 INIT_USERINFO();
8649 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
8650 ok(state == USERINFOSTATE_UNKNOWN,
8651 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8652 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8653 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8654 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8655 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8656
8657 /* MSIINSTALLCONTEXT_USERMANAGED */
8658
8659 /* create local system product key */
8660 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8661 lstrcatA(keypath, usersid);
8662 lstrcatA(keypath, "\\Installer\\Products\\");
8663 lstrcatA(keypath, prod_squashed);
8664
8665 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8666 if (res == ERROR_ACCESS_DENIED)
8667 {
8668 skip("Not enough rights to perform tests\n");
8669 LocalFree(usersid);
8670 return;
8671 }
8672 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8673
8674 /* managed product key exists */
8675 INIT_USERINFO();
8676 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8677 ok(state == USERINFOSTATE_ABSENT,
8678 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8679 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8680 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8681 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8682 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8683 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8684 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8685
8686 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8687 lstrcatA(keypath, "Installer\\UserData\\");
8688 lstrcatA(keypath, usersid);
8689 lstrcatA(keypath, "\\Products\\");
8690 lstrcatA(keypath, prod_squashed);
8691
8692 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8693 if (res == ERROR_ACCESS_DENIED)
8694 {
8695 skip("Not enough rights to perform tests\n");
8696 LocalFree(usersid);
8697 return;
8698 }
8699 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8700
8701 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8702 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8703
8704 /* InstallProperties key exists */
8705 INIT_USERINFO();
8706 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8707 ok(state == USERINFOSTATE_ABSENT,
8708 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8709 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8710 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8711 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8712 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8713 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8714 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8715
8716 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8717 INIT_USERINFO();
8718 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8719 ok(state == USERINFOSTATE_ABSENT,
8720 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8721 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8722 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8723 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8724 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8725
8726 /* RegOwner, RegCompany don't exist, out params are NULL */
8727 INIT_USERINFO();
8728 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8729 ok(state == USERINFOSTATE_ABSENT,
8730 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8731 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8732 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8733
8734 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8735 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8736
8737 /* RegOwner value exists */
8738 INIT_USERINFO();
8739 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8740 ok(state == USERINFOSTATE_ABSENT,
8741 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8742 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8743 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8744 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8745 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8746 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8747 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8748
8749 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8750 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8751
8752 /* RegCompany value exists */
8753 INIT_USERINFO();
8754 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8755 ok(state == USERINFOSTATE_ABSENT,
8756 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8757 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8758 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8759 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8760 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8761 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8762 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8763
8764 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8765 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8766
8767 /* ProductID value exists */
8768 INIT_USERINFO();
8769 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8770 ok(state == USERINFOSTATE_PRESENT,
8771 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8772 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8773 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8774 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8775 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8776 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8777 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8778
8779 /* pcchUserNameBuf is too small */
8780 INIT_USERINFO();
8781 usersz = 0;
8782 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8783 ok(state == USERINFOSTATE_MOREDATA,
8784 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8785 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8786 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8787 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8788 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8789 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8790 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8791
8792 /* pcchUserNameBuf has no room for NULL terminator */
8793 INIT_USERINFO();
8794 usersz = 5;
8795 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8796 ok(state == USERINFOSTATE_MOREDATA,
8797 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8798 todo_wine
8799 {
8800 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8801 }
8802 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8803 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8804 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8805 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8806 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8807
8808 /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
8809 INIT_USERINFO();
8810 usersz = 0;
8811 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8812 ok(state == USERINFOSTATE_PRESENT,
8813 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8814 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8815 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8816 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8817 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8818 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8819 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8820
8821 RegDeleteValueA(props, "ProductID");
8822 RegDeleteValueA(props, "RegCompany");
8823 RegDeleteValueA(props, "RegOwner");
8824 delete_key(props, "", access & KEY_WOW64_64KEY);
8825 RegCloseKey(props);
8826 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8827 RegCloseKey(userprod);
8828 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8829 RegCloseKey(prodkey);
8830
8831 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8832
8833 /* create local system product key */
8834 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8835 lstrcatA(keypath, prod_squashed);
8836
8837 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8838 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8839
8840 /* product key exists */
8841 INIT_USERINFO();
8842 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8843 ok(state == USERINFOSTATE_ABSENT,
8844 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8845 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8846 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8847 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8848 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8849 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8850 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8851
8852 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8853 lstrcatA(keypath, "Installer\\UserData\\");
8854 lstrcatA(keypath, usersid);
8855 lstrcatA(keypath, "\\Products\\");
8856 lstrcatA(keypath, prod_squashed);
8857
8858 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8859 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8860
8861 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8862 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8863
8864 /* InstallProperties key exists */
8865 INIT_USERINFO();
8866 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8867 ok(state == USERINFOSTATE_ABSENT,
8868 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8869 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8870 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8871 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8872 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8873 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8874 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8875
8876 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8877 INIT_USERINFO();
8878 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8879 ok(state == USERINFOSTATE_ABSENT,
8880 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8881 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8882 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8883 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8884 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8885
8886 /* RegOwner, RegCompany don't exist, out params are NULL */
8887 INIT_USERINFO();
8888 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8889 ok(state == USERINFOSTATE_ABSENT,
8890 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8891 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8892 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8893
8894 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8895 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8896
8897 /* RegOwner value exists */
8898 INIT_USERINFO();
8899 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8900 ok(state == USERINFOSTATE_ABSENT,
8901 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8902 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8903 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8904 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8905 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8906 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8907 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8908
8909 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8910 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8911
8912 /* RegCompany value exists */
8913 INIT_USERINFO();
8914 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8915 ok(state == USERINFOSTATE_ABSENT,
8916 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8917 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8918 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8919 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8920 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8921 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8922 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8923
8924 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8925 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8926
8927 /* ProductID value exists */
8928 INIT_USERINFO();
8929 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8930 ok(state == USERINFOSTATE_PRESENT,
8931 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8932 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8933 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8934 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8935 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8936 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8937 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8938
8939 RegDeleteValueA(props, "ProductID");
8940 RegDeleteValueA(props, "RegCompany");
8941 RegDeleteValueA(props, "RegOwner");
8942 delete_key(props, "", access & KEY_WOW64_64KEY);
8943 RegCloseKey(props);
8944 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8945 RegCloseKey(userprod);
8946 RegDeleteKeyA(prodkey, "");
8947 RegCloseKey(prodkey);
8948
8949 /* MSIINSTALLCONTEXT_MACHINE */
8950
8951 /* create local system product key */
8952 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8953 lstrcatA(keypath, prod_squashed);
8954
8955 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8956 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8957
8958 /* product key exists */
8959 INIT_USERINFO();
8960 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8961 ok(state == USERINFOSTATE_ABSENT,
8962 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8963 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8964 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8965 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8966 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8967 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8968 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8969
8970 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8971 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
8972 lstrcatA(keypath, "\\Products\\");
8973 lstrcatA(keypath, prod_squashed);
8974
8975 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8977
8978 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8979 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8980
8981 /* InstallProperties key exists */
8982 INIT_USERINFO();
8983 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8984 ok(state == USERINFOSTATE_ABSENT,
8985 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8986 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8987 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8988 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8989 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8990 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8991 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8992
8993 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8994 INIT_USERINFO();
8995 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8996 ok(state == USERINFOSTATE_ABSENT,
8997 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8998 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8999 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9000 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
9001 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9002
9003 /* RegOwner, RegCompany don't exist, out params are NULL */
9004 INIT_USERINFO();
9005 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
9006 ok(state == USERINFOSTATE_ABSENT,
9007 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9008 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9009 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9010
9011 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
9012 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9013
9014 /* RegOwner value exists */
9015 INIT_USERINFO();
9016 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9017 ok(state == USERINFOSTATE_ABSENT,
9018 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9019 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9020 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
9021 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9022 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9023 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
9024 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9025
9026 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
9027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9028
9029 /* RegCompany value exists */
9030 INIT_USERINFO();
9031 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9032 ok(state == USERINFOSTATE_ABSENT,
9033 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9034 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9035 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9036 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9037 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9038 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9039 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9040
9041 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
9042 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9043
9044 /* ProductID value exists */
9045 INIT_USERINFO();
9046 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9047 ok(state == USERINFOSTATE_PRESENT,
9048 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
9049 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9050 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9051 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
9052 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9053 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9054 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
9055
9056 RegDeleteValueA(props, "ProductID");
9057 RegDeleteValueA(props, "RegCompany");
9058 RegDeleteValueA(props, "RegOwner");
9059 delete_key(props, "", access & KEY_WOW64_64KEY);
9060 RegCloseKey(props);
9061 delete_key(userprod, "", access & KEY_WOW64_64KEY);
9062 RegCloseKey(userprod);
9063 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9064 RegCloseKey(prodkey);
9065 LocalFree(usersid);
9066 }
9067
9068 static void test_MsiOpenProduct(void)
9069 {
9070 MSIHANDLE hprod, hdb;
9071 CHAR val[MAX_PATH];
9072 CHAR path[MAX_PATH];
9073 CHAR keypath[MAX_PATH*2];
9074 CHAR prodcode[MAX_PATH];
9075 CHAR prod_squashed[MAX_PATH];
9076 HKEY prodkey, userkey, props;
9077 LPSTR usersid;
9078 DWORD size;
9079 LONG res;
9080 UINT r;
9081 REGSAM access = KEY_ALL_ACCESS;
9082
9083 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9084
9085 GetCurrentDirectoryA(MAX_PATH, path);
9086 lstrcatA(path, "\\");
9087
9088 create_test_guid(prodcode, prod_squashed);
9089 usersid = get_user_sid();
9090
9091 if (is_wow64)
9092 access |= KEY_WOW64_64KEY;
9093
9094 hdb = create_package_db(prodcode);
9095 MsiCloseHandle(hdb);
9096
9097 /* NULL szProduct */
9098 hprod = 0xdeadbeef;
9099 r = MsiOpenProductA(NULL, &hprod);
9100 ok(r == ERROR_INVALID_PARAMETER,
9101 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9102 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9103
9104 /* empty szProduct */
9105 hprod = 0xdeadbeef;
9106 r = MsiOpenProductA("", &hprod);
9107 ok(r == ERROR_INVALID_PARAMETER,
9108 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9109 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9110
9111 /* garbage szProduct */
9112 hprod = 0xdeadbeef;
9113 r = MsiOpenProductA("garbage", &hprod);
9114 ok(r == ERROR_INVALID_PARAMETER,
9115 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9116 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9117
9118 /* guid without brackets */
9119 hprod = 0xdeadbeef;
9120 r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
9121 ok(r == ERROR_INVALID_PARAMETER,
9122 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9123 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9124
9125 /* guid with brackets */
9126 hprod = 0xdeadbeef;
9127 r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
9128 ok(r == ERROR_UNKNOWN_PRODUCT,
9129 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9130 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9131
9132 /* same length as guid, but random */
9133 hprod = 0xdeadbeef;
9134 r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
9135 ok(r == ERROR_INVALID_PARAMETER,
9136 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9137 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9138
9139 /* hProduct is NULL */
9140 hprod = 0xdeadbeef;
9141 r = MsiOpenProductA(prodcode, NULL);
9142 ok(r == ERROR_INVALID_PARAMETER,
9143 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9144 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9145
9146 /* MSIINSTALLCONTEXT_USERMANAGED */
9147
9148 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9149 lstrcatA(keypath, "Installer\\Managed\\");
9150 lstrcatA(keypath, usersid);
9151 lstrcatA(keypath, "\\Installer\\Products\\");
9152 lstrcatA(keypath, prod_squashed);
9153
9154 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9155 if (res == ERROR_ACCESS_DENIED)
9156 {
9157 skip("Not enough rights to perform tests\n");
9158 LocalFree(usersid);
9159 return;
9160 }
9161 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9162
9163 /* managed product key exists */
9164 hprod = 0xdeadbeef;
9165 r = MsiOpenProductA(prodcode, &hprod);
9166 ok(r == ERROR_UNKNOWN_PRODUCT,
9167 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9168 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9169
9170 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9171 lstrcatA(keypath, "Installer\\UserData\\");
9172 lstrcatA(keypath, usersid);
9173 lstrcatA(keypath, "\\Products\\");
9174 lstrcatA(keypath, prod_squashed);
9175
9176 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9177 if (res == ERROR_ACCESS_DENIED)
9178 {
9179 skip("Not enough rights to perform tests\n");
9180 LocalFree(usersid);
9181 return;
9182 }
9183 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9184
9185 /* user product key exists */
9186 hprod = 0xdeadbeef;
9187 r = MsiOpenProductA(prodcode, &hprod);
9188 ok(r == ERROR_UNKNOWN_PRODUCT,
9189 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9190 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9191
9192 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9193 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9194
9195 /* InstallProperties key exists */
9196 hprod = 0xdeadbeef;
9197 r = MsiOpenProductA(prodcode, &hprod);
9198 ok(r == ERROR_UNKNOWN_PRODUCT,
9199 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9200 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9201
9202 lstrcpyA(val, path);
9203 lstrcatA(val, "\\winetest.msi");
9204 res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
9205 (const BYTE *)val, lstrlenA(val) + 1);
9206 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9207
9208 /* ManagedLocalPackage value exists */
9209 hprod = 0xdeadbeef;
9210 r = MsiOpenProductA(prodcode, &hprod);
9211 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9212 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9213
9214 size = MAX_PATH;
9215 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9216 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9217 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9218 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9219
9220 MsiCloseHandle(hprod);
9221
9222 RegDeleteValueA(props, "ManagedLocalPackage");
9223 delete_key(props, "", access & KEY_WOW64_64KEY);
9224 RegCloseKey(props);
9225 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9226 RegCloseKey(userkey);
9227 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9228 RegCloseKey(prodkey);
9229
9230 /* MSIINSTALLCONTEXT_USERUNMANAGED */
9231
9232 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9233 lstrcatA(keypath, prod_squashed);
9234
9235 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9236 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9237
9238 /* unmanaged product key exists */
9239 hprod = 0xdeadbeef;
9240 r = MsiOpenProductA(prodcode, &hprod);
9241 ok(r == ERROR_UNKNOWN_PRODUCT,
9242 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9243 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9244
9245 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9246 lstrcatA(keypath, "Installer\\UserData\\");
9247 lstrcatA(keypath, usersid);
9248 lstrcatA(keypath, "\\Products\\");
9249 lstrcatA(keypath, prod_squashed);
9250
9251 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9252 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9253
9254 /* user product key exists */
9255 hprod = 0xdeadbeef;
9256 r = MsiOpenProductA(prodcode, &hprod);
9257 ok(r == ERROR_UNKNOWN_PRODUCT,
9258 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9259 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9260
9261 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9262 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9263
9264 /* InstallProperties key exists */
9265 hprod = 0xdeadbeef;
9266 r = MsiOpenProductA(prodcode, &hprod);
9267 ok(r == ERROR_UNKNOWN_PRODUCT,
9268 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9269 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9270
9271 lstrcpyA(val, path);
9272 lstrcatA(val, "\\winetest.msi");
9273 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9274 (const BYTE *)val, lstrlenA(val) + 1);
9275 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9276
9277 /* LocalPackage value exists */
9278 hprod = 0xdeadbeef;
9279 r = MsiOpenProductA(prodcode, &hprod);
9280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9281 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9282
9283 size = MAX_PATH;
9284 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9285 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9286 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9287 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9288
9289 MsiCloseHandle(hprod);
9290
9291 RegDeleteValueA(props, "LocalPackage");
9292 delete_key(props, "", access & KEY_WOW64_64KEY);
9293 RegCloseKey(props);
9294 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9295 RegCloseKey(userkey);
9296 RegDeleteKeyA(prodkey, "");
9297 RegCloseKey(prodkey);
9298
9299 /* MSIINSTALLCONTEXT_MACHINE */
9300
9301 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9302 lstrcatA(keypath, prod_squashed);
9303
9304 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9305 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9306
9307 /* managed product key exists */
9308 hprod = 0xdeadbeef;
9309 r = MsiOpenProductA(prodcode, &hprod);
9310 ok(r == ERROR_UNKNOWN_PRODUCT,
9311 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9312 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9313
9314 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9315 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9316 lstrcatA(keypath, prod_squashed);
9317
9318 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9319 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9320
9321 /* user product key exists */
9322 hprod = 0xdeadbeef;
9323 r = MsiOpenProductA(prodcode, &hprod);
9324 ok(r == ERROR_UNKNOWN_PRODUCT,
9325 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9326 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9327
9328 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9330
9331 /* InstallProperties key exists */
9332 hprod = 0xdeadbeef;
9333 r = MsiOpenProductA(prodcode, &hprod);
9334 ok(r == ERROR_UNKNOWN_PRODUCT,
9335 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9336 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9337
9338 lstrcpyA(val, path);
9339 lstrcatA(val, "\\winetest.msi");
9340 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9341 (const BYTE *)val, lstrlenA(val) + 1);
9342 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9343
9344 /* LocalPackage value exists */
9345 hprod = 0xdeadbeef;
9346 r = MsiOpenProductA(prodcode, &hprod);
9347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9348 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9349
9350 size = MAX_PATH;
9351 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9352 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9353 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9354 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9355
9356 MsiCloseHandle(hprod);
9357
9358 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9359 (const BYTE *)"winetest.msi", 13);
9360 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9361
9362 lstrcpyA(val, path);
9363 lstrcatA(val, "\\winetest.msi");
9364 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9365 (const BYTE *)val, lstrlenA(val) + 1);
9366 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9367
9368 DeleteFileA(msifile);
9369
9370 /* local package does not exist */
9371 hprod = 0xdeadbeef;
9372 r = MsiOpenProductA(prodcode, &hprod);
9373 ok(r == ERROR_UNKNOWN_PRODUCT,
9374 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9375 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9376
9377 RegDeleteValueA(props, "LocalPackage");
9378 delete_key(props, "", access & KEY_WOW64_64KEY);
9379 RegCloseKey(props);
9380 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9381 RegCloseKey(userkey);
9382 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9383 RegCloseKey(prodkey);
9384
9385 DeleteFileA(msifile);
9386 LocalFree(usersid);
9387 }
9388
9389 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
9390 {
9391 MSIINSTALLCONTEXT context;
9392 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9393 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9394 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9395 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9396 HKEY prodkey, patches, udprod, udpatch, hpatch;
9397 DWORD size, data;
9398 LONG res;
9399 UINT r;
9400 REGSAM access = KEY_ALL_ACCESS;
9401
9402 create_test_guid(prodcode, prod_squashed);
9403 create_test_guid(patch, patch_squashed);
9404
9405 if (is_wow64)
9406 access |= KEY_WOW64_64KEY;
9407
9408 /* MSIPATCHSTATE_APPLIED */
9409
9410 lstrcpyA(patchcode, "apple");
9411 lstrcpyA(targetprod, "banana");
9412 context = 0xdeadbeef;
9413 lstrcpyA(targetsid, "kiwi");
9414 size = MAX_PATH;
9415 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9416 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9417 &context, targetsid, &size);
9418 if (r == ERROR_ACCESS_DENIED)
9419 {
9420 skip("Not enough rights to perform tests\n");
9421 return;
9422 }
9423 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9424 ok(!lstrcmpA(patchcode, "apple"),
9425 "Expected patchcode to be unchanged, got %s\n", patchcode);
9426 ok(!lstrcmpA(targetprod, "banana"),
9427 "Expected targetprod to be unchanged, got %s\n", targetprod);
9428 ok(context == 0xdeadbeef,
9429 "Expected context to be unchanged, got %d\n", context);
9430 ok(!lstrcmpA(targetsid, "kiwi"),
9431 "Expected targetsid to be unchanged, got %s\n", targetsid);
9432 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9433
9434 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9435 lstrcatA(keypath, expectedsid);
9436 lstrcatA(keypath, "\\Installer\\Products\\");
9437 lstrcatA(keypath, prod_squashed);
9438
9439 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9440 if (res == ERROR_ACCESS_DENIED)
9441 {
9442 skip("Not enough rights to perform tests\n");
9443 return;
9444 }
9445 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9446
9447 /* managed product key exists */
9448 lstrcpyA(patchcode, "apple");
9449 lstrcpyA(targetprod, "banana");
9450 context = 0xdeadbeef;
9451 lstrcpyA(targetsid, "kiwi");
9452 size = MAX_PATH;
9453 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9454 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9455 &context, targetsid, &size);
9456 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9457 ok(!lstrcmpA(patchcode, "apple"),
9458 "Expected patchcode to be unchanged, got %s\n", patchcode);
9459 ok(!lstrcmpA(targetprod, "banana"),
9460 "Expected targetprod to be unchanged, got %s\n", targetprod);
9461 ok(context == 0xdeadbeef,
9462 "Expected context to be unchanged, got %d\n", context);
9463 ok(!lstrcmpA(targetsid, "kiwi"),
9464 "Expected targetsid to be unchanged, got %s\n", targetsid);
9465 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9466
9467 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9469
9470 /* patches key exists */
9471 lstrcpyA(patchcode, "apple");
9472 lstrcpyA(targetprod, "banana");
9473 context = 0xdeadbeef;
9474 lstrcpyA(targetsid, "kiwi");
9475 size = MAX_PATH;
9476 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9477 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9478 &context, targetsid, &size);
9479 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9480 ok(!lstrcmpA(patchcode, "apple"),
9481 "Expected patchcode to be unchanged, got %s\n", patchcode);
9482 ok(!lstrcmpA(targetprod, "banana"),
9483 "Expected targetprod to be unchanged, got %s\n", targetprod);
9484 ok(context == 0xdeadbeef,
9485 "Expected context to be unchanged, got %d\n", context);
9486 ok(!lstrcmpA(targetsid, "kiwi"),
9487 "Expected targetsid to be unchanged, got %s\n", targetsid);
9488 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9489
9490 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9491 (const BYTE *)patch_squashed,
9492 lstrlenA(patch_squashed) + 1);
9493 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9494
9495 /* Patches value exists, is not REG_MULTI_SZ */
9496 lstrcpyA(patchcode, "apple");
9497 lstrcpyA(targetprod, "banana");
9498 context = 0xdeadbeef;
9499 lstrcpyA(targetsid, "kiwi");
9500 size = MAX_PATH;
9501 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9502 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9503 &context, targetsid, &size);
9504 ok(r == ERROR_BAD_CONFIGURATION,
9505 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9506 ok(!lstrcmpA(patchcode, "apple"),
9507 "Expected patchcode to be unchanged, got %s\n", patchcode);
9508 ok(!lstrcmpA(targetprod, "banana"),
9509 "Expected targetprod to be unchanged, got %s\n", targetprod);
9510 ok(context == 0xdeadbeef,
9511 "Expected context to be unchanged, got %d\n", context);
9512 ok(!lstrcmpA(targetsid, "kiwi"),
9513 "Expected targetsid to be unchanged, got %s\n", targetsid);
9514 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9515
9516 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9517 (const BYTE *)"a\0b\0c\0\0", 7);
9518 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9519
9520 /* Patches value exists, is not a squashed guid */
9521 lstrcpyA(patchcode, "apple");
9522 lstrcpyA(targetprod, "banana");
9523 context = 0xdeadbeef;
9524 lstrcpyA(targetsid, "kiwi");
9525 size = MAX_PATH;
9526 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9527 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9528 &context, targetsid, &size);
9529 ok(r == ERROR_BAD_CONFIGURATION,
9530 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9531 ok(!lstrcmpA(patchcode, "apple"),
9532 "Expected patchcode to be unchanged, got %s\n", patchcode);
9533 ok(!lstrcmpA(targetprod, "banana"),
9534 "Expected targetprod to be unchanged, got %s\n", targetprod);
9535 ok(context == 0xdeadbeef,
9536 "Expected context to be unchanged, got %d\n", context);
9537 ok(!lstrcmpA(targetsid, "kiwi"),
9538 "Expected targetsid to be unchanged, got %s\n", targetsid);
9539 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9540
9541 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9542 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9543 (const BYTE *)patch_squashed,
9544 lstrlenA(patch_squashed) + 2);
9545 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9546
9547 /* Patches value exists */
9548 lstrcpyA(patchcode, "apple");
9549 lstrcpyA(targetprod, "banana");
9550 context = 0xdeadbeef;
9551 lstrcpyA(targetsid, "kiwi");
9552 size = MAX_PATH;
9553 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9554 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9555 &context, targetsid, &size);
9556 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9557 ok(!lstrcmpA(patchcode, "apple"),
9558 "Expected patchcode to be unchanged, got %s\n", patchcode);
9559 ok(!lstrcmpA(targetprod, "banana"),
9560 "Expected targetprod to be unchanged, got %s\n", targetprod);
9561 ok(context == 0xdeadbeef,
9562 "Expected context to be unchanged, got %d\n", context);
9563 ok(!lstrcmpA(targetsid, "kiwi"),
9564 "Expected targetsid to be unchanged, got %s\n", targetsid);
9565 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9566
9567 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9568 (const BYTE *)"whatever", 9);
9569 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9570
9571 /* patch squashed value exists */
9572 lstrcpyA(patchcode, "apple");
9573 lstrcpyA(targetprod, "banana");
9574 context = 0xdeadbeef;
9575 lstrcpyA(targetsid, "kiwi");
9576 size = MAX_PATH;
9577 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9578 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9579 &context, targetsid, &size);
9580 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9581 ok(!lstrcmpA(patchcode, patch),
9582 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9583 ok(!lstrcmpA(targetprod, prodcode),
9584 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9585 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9586 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9587 ok(!lstrcmpA(targetsid, expectedsid),
9588 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9589 ok(size == lstrlenA(expectedsid),
9590 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9591
9592 /* increase the index */
9593 lstrcpyA(patchcode, "apple");
9594 lstrcpyA(targetprod, "banana");
9595 context = 0xdeadbeef;
9596 lstrcpyA(targetsid, "kiwi");
9597 size = MAX_PATH;
9598 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9599 MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
9600 &context, targetsid, &size);
9601 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9602 ok(!lstrcmpA(patchcode, "apple"),
9603 "Expected patchcode to be unchanged, got %s\n", patchcode);
9604 ok(!lstrcmpA(targetprod, "banana"),
9605 "Expected targetprod to be unchanged, got %s\n", targetprod);
9606 ok(context == 0xdeadbeef,
9607 "Expected context to be unchanged, got %d\n", context);
9608 ok(!lstrcmpA(targetsid, "kiwi"),
9609 "Expected targetsid to be unchanged, got %s\n", targetsid);
9610 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9611
9612 /* increase again */
9613 lstrcpyA(patchcode, "apple");
9614 lstrcpyA(targetprod, "banana");
9615 context = 0xdeadbeef;
9616 lstrcpyA(targetsid, "kiwi");
9617 size = MAX_PATH;
9618 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9619 MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
9620 &context, targetsid, &size);
9621 ok(r == ERROR_INVALID_PARAMETER,
9622 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9623 ok(!lstrcmpA(patchcode, "apple"),
9624 "Expected patchcode to be unchanged, got %s\n", patchcode);
9625 ok(!lstrcmpA(targetprod, "banana"),
9626 "Expected targetprod to be unchanged, got %s\n", targetprod);
9627 ok(context == 0xdeadbeef,
9628 "Expected context to be unchanged, got %d\n", context);
9629 ok(!lstrcmpA(targetsid, "kiwi"),
9630 "Expected targetsid to be unchanged, got %s\n", targetsid);
9631 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9632
9633 /* szPatchCode is NULL */
9634 lstrcpyA(targetprod, "banana");
9635 context = 0xdeadbeef;
9636 lstrcpyA(targetsid, "kiwi");
9637 size = MAX_PATH;
9638 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9639 MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
9640 &context, targetsid, &size);
9641 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9642 ok(!lstrcmpA(targetprod, prodcode),
9643 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9644 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9645 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9646 ok(!lstrcmpA(targetsid, expectedsid),
9647 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9648 ok(size == lstrlenA(expectedsid),
9649 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9650
9651 /* szTargetProductCode is NULL */
9652 lstrcpyA(patchcode, "apple");
9653 context = 0xdeadbeef;
9654 lstrcpyA(targetsid, "kiwi");
9655 size = MAX_PATH;
9656 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9657 MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
9658 &context, targetsid, &size);
9659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9660 ok(!lstrcmpA(patchcode, patch),
9661 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9662 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9663 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9664 ok(!lstrcmpA(targetsid, expectedsid),
9665 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9666 ok(size == lstrlenA(expectedsid),
9667 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9668
9669 /* pdwTargetProductContext is NULL */
9670 lstrcpyA(patchcode, "apple");
9671 lstrcpyA(targetprod, "banana");
9672 lstrcpyA(targetsid, "kiwi");
9673 size = MAX_PATH;
9674 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9675 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9676 NULL, targetsid, &size);
9677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9678 ok(!lstrcmpA(patchcode, patch),
9679 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9680 ok(!lstrcmpA(targetprod, prodcode),
9681 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9682 ok(!lstrcmpA(targetsid, expectedsid),
9683 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9684 ok(size == lstrlenA(expectedsid),
9685 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9686
9687 /* szTargetUserSid is NULL */
9688 lstrcpyA(patchcode, "apple");
9689 lstrcpyA(targetprod, "banana");
9690 context = 0xdeadbeef;
9691 size = MAX_PATH;
9692 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9693 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9694 &context, NULL, &size);
9695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9696 ok(!lstrcmpA(patchcode, patch),
9697 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9698 ok(!lstrcmpA(targetprod, prodcode),
9699 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9700 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9701 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9702 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
9703 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
9704
9705 /* pcchTargetUserSid is exactly the length of szTargetUserSid */
9706 lstrcpyA(patchcode, "apple");
9707 lstrcpyA(targetprod, "banana");
9708 context = 0xdeadbeef;
9709 lstrcpyA(targetsid, "kiwi");
9710 size = lstrlenA(expectedsid);
9711 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9712 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9713 &context, targetsid, &size);
9714 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9715 ok(!lstrcmpA(patchcode, patch),
9716 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9717 ok(!lstrcmpA(targetprod, prodcode),
9718 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9719 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9720 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9721 ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
9722 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9723 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
9724 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
9725
9726 /* pcchTargetUserSid has enough room for NULL terminator */
9727 lstrcpyA(patchcode, "apple");
9728 lstrcpyA(targetprod, "banana");
9729 context = 0xdeadbeef;
9730 lstrcpyA(targetsid, "kiwi");
9731 size = lstrlenA(expectedsid) + 1;
9732 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9733 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9734 &context, targetsid, &size);
9735 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9736 ok(!lstrcmpA(patchcode, patch),
9737 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9738 ok(!lstrcmpA(targetprod, prodcode),
9739 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9740 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9741 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9742 ok(!lstrcmpA(targetsid, expectedsid),
9743 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9744 ok(size == lstrlenA(expectedsid),
9745 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9746
9747 /* both szTargetuserSid and pcchTargetUserSid are NULL */
9748 lstrcpyA(patchcode, "apple");
9749 lstrcpyA(targetprod, "banana");
9750 context = 0xdeadbeef;
9751 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9752 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9753 &context, NULL, NULL);
9754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9755 ok(!lstrcmpA(patchcode, patch),
9756 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9757 ok(!lstrcmpA(targetprod, prodcode),
9758 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9759 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9760 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9761
9762 /* MSIPATCHSTATE_SUPERSEDED */
9763
9764 lstrcpyA(patchcode, "apple");
9765 lstrcpyA(targetprod, "banana");
9766 context = 0xdeadbeef;
9767 lstrcpyA(targetsid, "kiwi");
9768 size = MAX_PATH;
9769 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9770 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9771 &context, targetsid, &size);
9772 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9773 ok(!lstrcmpA(patchcode, "apple"),
9774 "Expected patchcode to be unchanged, got %s\n", patchcode);
9775 ok(!lstrcmpA(targetprod, "banana"),
9776 "Expected targetprod to be unchanged, got %s\n", targetprod);
9777 ok(context == 0xdeadbeef,
9778 "Expected context to be unchanged, got %d\n", context);
9779 ok(!lstrcmpA(targetsid, "kiwi"),
9780 "Expected targetsid to be unchanged, got %s\n", targetsid);
9781 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9782
9783 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9784 lstrcatA(keypath, expectedsid);
9785 lstrcatA(keypath, "\\Products\\");
9786 lstrcatA(keypath, prod_squashed);
9787
9788 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9789 if (res == ERROR_ACCESS_DENIED)
9790 {
9791 skip("Not enough rights to perform tests\n");
9792 return;
9793 }
9794 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9795
9796 /* UserData product key exists */
9797 lstrcpyA(patchcode, "apple");
9798 lstrcpyA(targetprod, "banana");
9799 context = 0xdeadbeef;
9800 lstrcpyA(targetsid, "kiwi");
9801 size = MAX_PATH;
9802 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9803 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9804 &context, targetsid, &size);
9805 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9806 ok(!lstrcmpA(patchcode, "apple"),
9807 "Expected patchcode to be unchanged, got %s\n", patchcode);
9808 ok(!lstrcmpA(targetprod, "banana"),
9809 "Expected targetprod to be unchanged, got %s\n", targetprod);
9810 ok(context == 0xdeadbeef,
9811 "Expected context to be unchanged, got %d\n", context);
9812 ok(!lstrcmpA(targetsid, "kiwi"),
9813 "Expected targetsid to be unchanged, got %s\n", targetsid);
9814 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9815
9816 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9817 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9818
9819 /* UserData patches key exists */
9820 lstrcpyA(patchcode, "apple");
9821 lstrcpyA(targetprod, "banana");
9822 context = 0xdeadbeef;
9823 lstrcpyA(targetsid, "kiwi");
9824 size = MAX_PATH;
9825 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9826 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9827 &context, targetsid, &size);
9828 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9829 ok(!lstrcmpA(patchcode, "apple"),
9830 "Expected patchcode to be unchanged, got %s\n", patchcode);
9831 ok(!lstrcmpA(targetprod, "banana"),
9832 "Expected targetprod to be unchanged, got %s\n", targetprod);
9833 ok(context == 0xdeadbeef,
9834 "Expected context to be unchanged, got %d\n", context);
9835 ok(!lstrcmpA(targetsid, "kiwi"),
9836 "Expected targetsid to be unchanged, got %s\n", targetsid);
9837 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9838
9839 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9841
9842 /* specific UserData patch key exists */
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_USERMANAGED,
9849 MSIPATCHSTATE_SUPERSEDED, 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 data = MSIPATCHSTATE_SUPERSEDED;
9864 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9865 (const BYTE *)&data, sizeof(DWORD));
9866 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9867
9868 /* State value exists */
9869 lstrcpyA(patchcode, "apple");
9870 lstrcpyA(targetprod, "banana");
9871 context = 0xdeadbeef;
9872 lstrcpyA(targetsid, "kiwi");
9873 size = MAX_PATH;
9874 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9875 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9876 &context, targetsid, &size);
9877 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9878 ok(!lstrcmpA(patchcode, patch),
9879 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9880 ok(!lstrcmpA(targetprod, prodcode),
9881 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9882 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9883 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9884 ok(!lstrcmpA(targetsid, expectedsid),
9885 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9886 ok(size == lstrlenA(expectedsid),
9887 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9888
9889 /* MSIPATCHSTATE_OBSOLETED */
9890
9891 lstrcpyA(patchcode, "apple");
9892 lstrcpyA(targetprod, "banana");
9893 context = 0xdeadbeef;
9894 lstrcpyA(targetsid, "kiwi");
9895 size = MAX_PATH;
9896 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9897 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9898 &context, targetsid, &size);
9899 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9900 ok(!lstrcmpA(patchcode, "apple"),
9901 "Expected patchcode to be unchanged, got %s\n", patchcode);
9902 ok(!lstrcmpA(targetprod, "banana"),
9903 "Expected targetprod to be unchanged, got %s\n", targetprod);
9904 ok(context == 0xdeadbeef,
9905 "Expected context to be unchanged, got %d\n", context);
9906 ok(!lstrcmpA(targetsid, "kiwi"),
9907 "Expected targetsid to be unchanged, got %s\n", targetsid);
9908 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9909
9910 data = MSIPATCHSTATE_OBSOLETED;
9911 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9912 (const BYTE *)&data, sizeof(DWORD));
9913 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9914
9915 /* State value is obsoleted */
9916 lstrcpyA(patchcode, "apple");
9917 lstrcpyA(targetprod, "banana");
9918 context = 0xdeadbeef;
9919 lstrcpyA(targetsid, "kiwi");
9920 size = MAX_PATH;
9921 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9922 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9923 &context, targetsid, &size);
9924 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9925 ok(!lstrcmpA(patchcode, patch),
9926 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9927 ok(!lstrcmpA(targetprod, prodcode),
9928 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9929 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9930 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9931 ok(!lstrcmpA(targetsid, expectedsid),
9932 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9933 ok(size == lstrlenA(expectedsid),
9934 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9935
9936 /* MSIPATCHSTATE_REGISTERED */
9937 /* FIXME */
9938
9939 /* MSIPATCHSTATE_ALL */
9940
9941 /* 1st */
9942 lstrcpyA(patchcode, "apple");
9943 lstrcpyA(targetprod, "banana");
9944 context = 0xdeadbeef;
9945 lstrcpyA(targetsid, "kiwi");
9946 size = MAX_PATH;
9947 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9948 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9949 &context, targetsid, &size);
9950 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9951 ok(!lstrcmpA(patchcode, patch),
9952 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9953 ok(!lstrcmpA(targetprod, prodcode),
9954 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9955 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9956 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9957 ok(!lstrcmpA(targetsid, expectedsid),
9958 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9959 ok(size == lstrlenA(expectedsid),
9960 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9961
9962 /* same patch in multiple places, only one is enumerated */
9963 lstrcpyA(patchcode, "apple");
9964 lstrcpyA(targetprod, "banana");
9965 context = 0xdeadbeef;
9966 lstrcpyA(targetsid, "kiwi");
9967 size = MAX_PATH;
9968 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9969 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9970 &context, targetsid, &size);
9971 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9972 ok(!lstrcmpA(patchcode, "apple"),
9973 "Expected patchcode to be unchanged, got %s\n", patchcode);
9974 ok(!lstrcmpA(targetprod, "banana"),
9975 "Expected targetprod to be unchanged, got %s\n", targetprod);
9976 ok(context == 0xdeadbeef,
9977 "Expected context to be unchanged, got %d\n", context);
9978 ok(!lstrcmpA(targetsid, "kiwi"),
9979 "Expected targetsid to be unchanged, got %s\n", targetsid);
9980 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9981
9982 RegDeleteValueA(hpatch, "State");
9983 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9984 RegCloseKey(hpatch);
9985 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9986 RegCloseKey(udpatch);
9987 delete_key(udprod, "", access & KEY_WOW64_64KEY);
9988 RegCloseKey(udprod);
9989 RegDeleteValueA(patches, "Patches");
9990 delete_key(patches, "", access & KEY_WOW64_64KEY);
9991 RegCloseKey(patches);
9992 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9993 RegCloseKey(prodkey);
9994 }
9995
9996 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
9997 {
9998 MSIINSTALLCONTEXT context;
9999 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10000 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
10001 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10002 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10003 HKEY prodkey, patches, udprod, udpatch;
10004 HKEY userkey, hpatch;
10005 DWORD size, data;
10006 LONG res;
10007 UINT r;
10008 REGSAM access = KEY_ALL_ACCESS;
10009
10010 create_test_guid(prodcode, prod_squashed);
10011 create_test_guid(patch, patch_squashed);
10012
10013 if (is_wow64)
10014 access |= KEY_WOW64_64KEY;
10015
10016 /* MSIPATCHSTATE_APPLIED */
10017
10018 lstrcpyA(patchcode, "apple");
10019 lstrcpyA(targetprod, "banana");
10020 context = 0xdeadbeef;
10021 lstrcpyA(targetsid, "kiwi");
10022 size = MAX_PATH;
10023 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10024 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10025 &context, targetsid, &size);
10026 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10027 ok(!lstrcmpA(patchcode, "apple"),
10028 "Expected patchcode to be unchanged, got %s\n", patchcode);
10029 ok(!lstrcmpA(targetprod, "banana"),
10030 "Expected targetprod to be unchanged, got %s\n", targetprod);
10031 ok(context == 0xdeadbeef,
10032 "Expected context to be unchanged, got %d\n", context);
10033 ok(!lstrcmpA(targetsid, "kiwi"),
10034 "Expected targetsid to be unchanged, got %s\n", targetsid);
10035 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10036
10037 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10038 lstrcatA(keypath, prod_squashed);
10039
10040 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10041 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10042
10043 /* current user product key exists */
10044 lstrcpyA(patchcode, "apple");
10045 lstrcpyA(targetprod, "banana");
10046 context = 0xdeadbeef;
10047 lstrcpyA(targetsid, "kiwi");
10048 size = MAX_PATH;
10049 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10050 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10051 &context, targetsid, &size);
10052 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10053 ok(!lstrcmpA(patchcode, "apple"),
10054 "Expected patchcode to be unchanged, got %s\n", patchcode);
10055 ok(!lstrcmpA(targetprod, "banana"),
10056 "Expected targetprod to be unchanged, got %s\n", targetprod);
10057 ok(context == 0xdeadbeef,
10058 "Expected context to be unchanged, got %d\n", context);
10059 ok(!lstrcmpA(targetsid, "kiwi"),
10060 "Expected targetsid to be unchanged, got %s\n", targetsid);
10061 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10062
10063 res = RegCreateKeyA(prodkey, "Patches", &patches);
10064 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10065
10066 /* Patches key exists */
10067 lstrcpyA(patchcode, "apple");
10068 lstrcpyA(targetprod, "banana");
10069 context = 0xdeadbeef;
10070 lstrcpyA(targetsid, "kiwi");
10071 size = MAX_PATH;
10072 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10073 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10074 &context, targetsid, &size);
10075 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10076 ok(!lstrcmpA(patchcode, "apple"),
10077 "Expected patchcode to be unchanged, got %s\n", patchcode);
10078 ok(!lstrcmpA(targetprod, "banana"),
10079 "Expected targetprod to be unchanged, got %s\n", targetprod);
10080 ok(context == 0xdeadbeef,
10081 "Expected context to be unchanged, got %d\n", context);
10082 ok(!lstrcmpA(targetsid, "kiwi"),
10083 "Expected targetsid to be unchanged, got %s\n", targetsid);
10084 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10085
10086 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10087 (const BYTE *)patch_squashed,
10088 lstrlenA(patch_squashed) + 1);
10089 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10090
10091 /* Patches value exists, is not REG_MULTI_SZ */
10092 lstrcpyA(patchcode, "apple");
10093 lstrcpyA(targetprod, "banana");
10094 context = 0xdeadbeef;
10095 lstrcpyA(targetsid, "kiwi");
10096 size = MAX_PATH;
10097 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10098 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10099 &context, targetsid, &size);
10100 ok(r == ERROR_BAD_CONFIGURATION,
10101 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10102 ok(!lstrcmpA(patchcode, "apple"),
10103 "Expected patchcode to be unchanged, got %s\n", patchcode);
10104 ok(!lstrcmpA(targetprod, "banana"),
10105 "Expected targetprod to be unchanged, got %s\n", targetprod);
10106 ok(context == 0xdeadbeef,
10107 "Expected context to be unchanged, got %d\n", context);
10108 ok(!lstrcmpA(targetsid, "kiwi"),
10109 "Expected targetsid to be unchanged, got %s\n", targetsid);
10110 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10111
10112 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10113 (const BYTE *)"a\0b\0c\0\0", 7);
10114 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10115
10116 /* Patches value exists, is not a squashed guid */
10117 lstrcpyA(patchcode, "apple");
10118 lstrcpyA(targetprod, "banana");
10119 context = 0xdeadbeef;
10120 lstrcpyA(targetsid, "kiwi");
10121 size = MAX_PATH;
10122 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10123 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10124 &context, targetsid, &size);
10125 ok(r == ERROR_BAD_CONFIGURATION,
10126 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10127 ok(!lstrcmpA(patchcode, "apple"),
10128 "Expected patchcode to be unchanged, got %s\n", patchcode);
10129 ok(!lstrcmpA(targetprod, "banana"),
10130 "Expected targetprod to be unchanged, got %s\n", targetprod);
10131 ok(context == 0xdeadbeef,
10132 "Expected context to be unchanged, got %d\n", context);
10133 ok(!lstrcmpA(targetsid, "kiwi"),
10134 "Expected targetsid to be unchanged, got %s\n", targetsid);
10135 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10136
10137 patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
10138 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10139 (const BYTE *)patch_squashed,
10140 lstrlenA(patch_squashed) + 2);
10141 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10142
10143 /* Patches value exists */
10144 lstrcpyA(patchcode, "apple");
10145 lstrcpyA(targetprod, "banana");
10146 context = 0xdeadbeef;
10147 lstrcpyA(targetsid, "kiwi");
10148 size = MAX_PATH;
10149 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10150 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10151 &context, targetsid, &size);
10152 ok(r == ERROR_NO_MORE_ITEMS ||
10153 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
10154 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10155 ok(!lstrcmpA(patchcode, "apple"),
10156 "Expected patchcode to be unchanged, got %s\n", patchcode);
10157 ok(!lstrcmpA(targetprod, "banana"),
10158 "Expected targetprod to be unchanged, got %s\n", targetprod);
10159 ok(context == 0xdeadbeef,
10160 "Expected context to be unchanged, got %d\n", context);
10161 ok(!lstrcmpA(targetsid, "kiwi"),
10162 "Expected targetsid to be unchanged, got %s\n", targetsid);
10163 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10164
10165 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10166 (const BYTE *)"whatever", 9);
10167 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10168
10169 /* patch code value exists */
10170 lstrcpyA(patchcode, "apple");
10171 lstrcpyA(targetprod, "banana");
10172 context = 0xdeadbeef;
10173 lstrcpyA(targetsid, "kiwi");
10174 size = MAX_PATH;
10175 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10176 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10177 &context, targetsid, &size);
10178 ok(r == ERROR_NO_MORE_ITEMS ||
10179 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
10180 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10181 ok(!lstrcmpA(patchcode, "apple"),
10182 "Expected patchcode to be unchanged, got %s\n", patchcode);
10183 ok(!lstrcmpA(targetprod, "banana"),
10184 "Expected targetprod to be unchanged, got %s\n", targetprod);
10185 ok(context == 0xdeadbeef,
10186 "Expected context to be unchanged, got %d\n", context);
10187 ok(!lstrcmpA(targetsid, "kiwi"),
10188 "Expected targetsid to be unchanged, got %s\n", targetsid);
10189 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10190
10191 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10192 lstrcatA(keypath, expectedsid);
10193 lstrcatA(keypath, "\\Patches\\");
10194 lstrcatA(keypath, patch_squashed);
10195
10196 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10197 if (res == ERROR_ACCESS_DENIED)
10198 {
10199 skip("Not enough rights to perform tests\n");
10200 goto error;
10201 }
10202 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10203
10204 /* userdata patch key exists */
10205 lstrcpyA(patchcode, "apple");
10206 lstrcpyA(targetprod, "banana");
10207 context = 0xdeadbeef;
10208 lstrcpyA(targetsid, "kiwi");
10209 size = MAX_PATH;
10210 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10211 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10212 &context, targetsid, &size);
10213 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10214 ok(!lstrcmpA(patchcode, patch),
10215 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10216 ok(!lstrcmpA(targetprod, prodcode),
10217 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10218 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10219 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10220 ok(!lstrcmpA(targetsid, expectedsid),
10221 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10222 ok(size == lstrlenA(expectedsid),
10223 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10224
10225 /* MSIPATCHSTATE_SUPERSEDED */
10226
10227 lstrcpyA(patchcode, "apple");
10228 lstrcpyA(targetprod, "banana");
10229 context = 0xdeadbeef;
10230 lstrcpyA(targetsid, "kiwi");
10231 size = MAX_PATH;
10232 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10233 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10234 &context, targetsid, &size);
10235 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10236 ok(!lstrcmpA(patchcode, "apple"),
10237 "Expected patchcode to be unchanged, got %s\n", patchcode);
10238 ok(!lstrcmpA(targetprod, "banana"),
10239 "Expected targetprod to be unchanged, got %s\n", targetprod);
10240 ok(context == 0xdeadbeef,
10241 "Expected context to be unchanged, got %d\n", context);
10242 ok(!lstrcmpA(targetsid, "kiwi"),
10243 "Expected targetsid to be unchanged, got %s\n", targetsid);
10244 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10245
10246 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10247 lstrcatA(keypath, expectedsid);
10248 lstrcatA(keypath, "\\Products\\");
10249 lstrcatA(keypath, prod_squashed);
10250
10251 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10252 if (res == ERROR_ACCESS_DENIED)
10253 {
10254 skip("Not enough rights to perform tests\n");
10255 goto error;
10256 }
10257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10258
10259 /* UserData product key exists */
10260 lstrcpyA(patchcode, "apple");
10261 lstrcpyA(targetprod, "banana");
10262 context = 0xdeadbeef;
10263 lstrcpyA(targetsid, "kiwi");
10264 size = MAX_PATH;
10265 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10266 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10267 &context, targetsid, &size);
10268 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10269 ok(!lstrcmpA(patchcode, "apple"),
10270 "Expected patchcode to be unchanged, got %s\n", patchcode);
10271 ok(!lstrcmpA(targetprod, "banana"),
10272 "Expected targetprod to be unchanged, got %s\n", targetprod);
10273 ok(context == 0xdeadbeef,
10274 "Expected context to be unchanged, got %d\n", context);
10275 ok(!lstrcmpA(targetsid, "kiwi"),
10276 "Expected targetsid to be unchanged, got %s\n", targetsid);
10277 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10278
10279 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10280 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10281
10282 /* UserData patches key exists */
10283 lstrcpyA(patchcode, "apple");
10284 lstrcpyA(targetprod, "banana");
10285 context = 0xdeadbeef;
10286 lstrcpyA(targetsid, "kiwi");
10287 size = MAX_PATH;
10288 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10289 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10290 &context, targetsid, &size);
10291 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10292 ok(!lstrcmpA(patchcode, "apple"),
10293 "Expected patchcode to be unchanged, got %s\n", patchcode);
10294 ok(!lstrcmpA(targetprod, "banana"),
10295 "Expected targetprod to be unchanged, got %s\n", targetprod);
10296 ok(context == 0xdeadbeef,
10297 "Expected context to be unchanged, got %d\n", context);
10298 ok(!lstrcmpA(targetsid, "kiwi"),
10299 "Expected targetsid to be unchanged, got %s\n", targetsid);
10300 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10301
10302 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10303 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10304
10305 /* specific UserData patch key exists */
10306 lstrcpyA(patchcode, "apple");
10307 lstrcpyA(targetprod, "banana");
10308 context = 0xdeadbeef;
10309 lstrcpyA(targetsid, "kiwi");
10310 size = MAX_PATH;
10311 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10312 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10313 &context, targetsid, &size);
10314 ok(r == ERROR_BAD_CONFIGURATION,
10315 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10316 ok(!lstrcmpA(patchcode, "apple"),
10317 "Expected patchcode to be unchanged, got %s\n", patchcode);
10318 ok(!lstrcmpA(targetprod, "banana"),
10319 "Expected targetprod to be unchanged, got %s\n", targetprod);
10320 ok(context == 0xdeadbeef,
10321 "Expected context to be unchanged, got %d\n", context);
10322 ok(!lstrcmpA(targetsid, "kiwi"),
10323 "Expected targetsid to be unchanged, got %s\n", targetsid);
10324 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10325
10326 data = MSIPATCHSTATE_SUPERSEDED;
10327 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10328 (const BYTE *)&data, sizeof(DWORD));
10329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10330
10331 /* State value exists */
10332 lstrcpyA(patchcode, "apple");
10333 lstrcpyA(targetprod, "banana");
10334 context = 0xdeadbeef;
10335 lstrcpyA(targetsid, "kiwi");
10336 size = MAX_PATH;
10337 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10338 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10339 &context, targetsid, &size);
10340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10341 ok(!lstrcmpA(patchcode, patch),
10342 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10343 ok(!lstrcmpA(targetprod, prodcode),
10344 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10345 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10346 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10347 ok(!lstrcmpA(targetsid, expectedsid),
10348 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10349 ok(size == lstrlenA(expectedsid),
10350 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10351
10352 /* MSIPATCHSTATE_OBSOLETED */
10353
10354 lstrcpyA(patchcode, "apple");
10355 lstrcpyA(targetprod, "banana");
10356 context = 0xdeadbeef;
10357 lstrcpyA(targetsid, "kiwi");
10358 size = MAX_PATH;
10359 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10360 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10361 &context, targetsid, &size);
10362 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10363 ok(!lstrcmpA(patchcode, "apple"),
10364 "Expected patchcode to be unchanged, got %s\n", patchcode);
10365 ok(!lstrcmpA(targetprod, "banana"),
10366 "Expected targetprod to be unchanged, got %s\n", targetprod);
10367 ok(context == 0xdeadbeef,
10368 "Expected context to be unchanged, got %d\n", context);
10369 ok(!lstrcmpA(targetsid, "kiwi"),
10370 "Expected targetsid to be unchanged, got %s\n", targetsid);
10371 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10372
10373 data = MSIPATCHSTATE_OBSOLETED;
10374 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10375 (const BYTE *)&data, sizeof(DWORD));
10376 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10377
10378 /* State value is obsoleted */
10379 lstrcpyA(patchcode, "apple");
10380 lstrcpyA(targetprod, "banana");
10381 context = 0xdeadbeef;
10382 lstrcpyA(targetsid, "kiwi");
10383 size = MAX_PATH;
10384 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10385 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10386 &context, targetsid, &size);
10387 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10388 ok(!lstrcmpA(patchcode, patch),
10389 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10390 ok(!lstrcmpA(targetprod, prodcode),
10391 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10392 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10393 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10394 ok(!lstrcmpA(targetsid, expectedsid),
10395 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10396 ok(size == lstrlenA(expectedsid),
10397 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10398
10399 /* MSIPATCHSTATE_REGISTERED */
10400 /* FIXME */
10401
10402 /* MSIPATCHSTATE_ALL */
10403
10404 /* 1st */
10405 lstrcpyA(patchcode, "apple");
10406 lstrcpyA(targetprod, "banana");
10407 context = 0xdeadbeef;
10408 lstrcpyA(targetsid, "kiwi");
10409 size = MAX_PATH;
10410 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10411 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10412 &context, targetsid, &size);
10413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10414 ok(!lstrcmpA(patchcode, patch),
10415 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10416 ok(!lstrcmpA(targetprod, prodcode),
10417 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10418 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10419 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10420 ok(!lstrcmpA(targetsid, expectedsid),
10421 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10422 ok(size == lstrlenA(expectedsid),
10423 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10424
10425 /* same patch in multiple places, only one is enumerated */
10426 lstrcpyA(patchcode, "apple");
10427 lstrcpyA(targetprod, "banana");
10428 context = 0xdeadbeef;
10429 lstrcpyA(targetsid, "kiwi");
10430 size = MAX_PATH;
10431 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10432 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10433 &context, targetsid, &size);
10434 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10435 ok(!lstrcmpA(patchcode, "apple"),
10436 "Expected patchcode to be unchanged, got %s\n", patchcode);
10437 ok(!lstrcmpA(targetprod, "banana"),
10438 "Expected targetprod to be unchanged, got %s\n", targetprod);
10439 ok(context == 0xdeadbeef,
10440 "Expected context to be unchanged, got %d\n", context);
10441 ok(!lstrcmpA(targetsid, "kiwi"),
10442 "Expected targetsid to be unchanged, got %s\n", targetsid);
10443 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10444
10445 RegDeleteValueA(hpatch, "State");
10446 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10447 RegCloseKey(hpatch);
10448 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10449 RegCloseKey(udpatch);
10450 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10451 RegCloseKey(udprod);
10452 delete_key(userkey, "", access & KEY_WOW64_64KEY);
10453 RegCloseKey(userkey);
10454 RegDeleteValueA(patches, patch_squashed);
10455 RegDeleteValueA(patches, "Patches");
10456
10457 error:
10458 RegDeleteKeyA(patches, "");
10459 RegCloseKey(patches);
10460 RegDeleteKeyA(prodkey, "");
10461 RegCloseKey(prodkey);
10462 }
10463
10464 static void test_MsiEnumPatchesEx_machine(void)
10465 {
10466 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10467 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
10468 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10469 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10470 HKEY prodkey, patches, udprod, udpatch;
10471 HKEY hpatch;
10472 MSIINSTALLCONTEXT context;
10473 DWORD size, data;
10474 LONG res;
10475 UINT r;
10476 REGSAM access = KEY_ALL_ACCESS;
10477
10478 create_test_guid(prodcode, prod_squashed);
10479 create_test_guid(patch, patch_squashed);
10480
10481 if (is_wow64)
10482 access |= KEY_WOW64_64KEY;
10483
10484 /* MSIPATCHSTATE_APPLIED */
10485
10486 lstrcpyA(patchcode, "apple");
10487 lstrcpyA(targetprod, "banana");
10488 context = 0xdeadbeef;
10489 lstrcpyA(targetsid, "kiwi");
10490 size = MAX_PATH;
10491 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10492 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10493 &context, targetsid, &size);
10494 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10495 ok(!lstrcmpA(patchcode, "apple"),
10496 "Expected patchcode to be unchanged, got %s\n", patchcode);
10497 ok(!lstrcmpA(targetprod, "banana"),
10498 "Expected targetprod to be unchanged, got %s\n", targetprod);
10499 ok(context == 0xdeadbeef,
10500 "Expected context to be unchanged, got %d\n", context);
10501 ok(!lstrcmpA(targetsid, "kiwi"),
10502 "Expected targetsid to be unchanged, got %s\n", targetsid);
10503 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10504
10505 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10506 lstrcatA(keypath, prod_squashed);
10507
10508 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10509 if (res == ERROR_ACCESS_DENIED)
10510 {
10511 skip("Not enough rights to perform tests\n");
10512 return;
10513 }
10514 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10515
10516 /* local product key exists */
10517 lstrcpyA(patchcode, "apple");
10518 lstrcpyA(targetprod, "banana");
10519 context = 0xdeadbeef;
10520 lstrcpyA(targetsid, "kiwi");
10521 size = MAX_PATH;
10522 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10523 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10524 &context, targetsid, &size);
10525 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10526 ok(!lstrcmpA(patchcode, "apple"),
10527 "Expected patchcode to be unchanged, got %s\n", patchcode);
10528 ok(!lstrcmpA(targetprod, "banana"),
10529 "Expected targetprod to be unchanged, got %s\n", targetprod);
10530 ok(context == 0xdeadbeef,
10531 "Expected context to be unchanged, got %d\n", context);
10532 ok(!lstrcmpA(targetsid, "kiwi"),
10533 "Expected targetsid to be unchanged, got %s\n", targetsid);
10534 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10535
10536 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10537 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10538
10539 /* Patches key exists */
10540 lstrcpyA(patchcode, "apple");
10541 lstrcpyA(targetprod, "banana");
10542 context = 0xdeadbeef;
10543 lstrcpyA(targetsid, "kiwi");
10544 size = MAX_PATH;
10545 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10546 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10547 &context, targetsid, &size);
10548 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10549 ok(!lstrcmpA(patchcode, "apple"),
10550 "Expected patchcode to be unchanged, got %s\n", patchcode);
10551 ok(!lstrcmpA(targetprod, "banana"),
10552 "Expected targetprod to be unchanged, got %s\n", targetprod);
10553 ok(context == 0xdeadbeef,
10554 "Expected context to be unchanged, got %d\n", context);
10555 ok(!lstrcmpA(targetsid, "kiwi"),
10556 "Expected targetsid to be unchanged, got %s\n", targetsid);
10557 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10558
10559 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10560 (const BYTE *)patch_squashed,
10561 lstrlenA(patch_squashed) + 1);
10562 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10563
10564 /* Patches value exists, is not REG_MULTI_SZ */
10565 lstrcpyA(patchcode, "apple");
10566 lstrcpyA(targetprod, "banana");
10567 context = 0xdeadbeef;
10568 lstrcpyA(targetsid, "kiwi");
10569 size = MAX_PATH;
10570 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10571 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10572 &context, targetsid, &size);
10573 ok(r == ERROR_BAD_CONFIGURATION,
10574 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10575 ok(!lstrcmpA(patchcode, "apple"),
10576 "Expected patchcode to be unchanged, got %s\n", patchcode);
10577 ok(!lstrcmpA(targetprod, "banana"),
10578 "Expected targetprod to be unchanged, got %s\n", targetprod);
10579 ok(context == 0xdeadbeef,
10580 "Expected context to be unchanged, got %d\n", context);
10581 ok(!lstrcmpA(targetsid, "kiwi"),
10582 "Expected targetsid to be unchanged, got %s\n", targetsid);
10583 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10584
10585 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10586 (const BYTE *)"a\0b\0c\0\0", 7);
10587 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10588
10589 /* Patches value exists, is not a squashed guid */
10590 lstrcpyA(patchcode, "apple");
10591 lstrcpyA(targetprod, "banana");
10592 context = 0xdeadbeef;
10593 lstrcpyA(targetsid, "kiwi");
10594 size = MAX_PATH;
10595 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10596 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10597 &context, targetsid, &size);
10598 ok(r == ERROR_BAD_CONFIGURATION,
10599 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10600 ok(!lstrcmpA(patchcode, "apple"),
10601 "Expected patchcode to be unchanged, got %s\n", patchcode);
10602 ok(!lstrcmpA(targetprod, "banana"),
10603 "Expected targetprod to be unchanged, got %s\n", targetprod);
10604 ok(context == 0xdeadbeef,
10605 "Expected context to be unchanged, got %d\n", context);
10606 ok(!lstrcmpA(targetsid, "kiwi"),
10607 "Expected targetsid to be unchanged, got %s\n", targetsid);
10608 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10609
10610 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10611 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10612 (const BYTE *)patch_squashed,
10613 lstrlenA(patch_squashed) + 2);
10614 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10615
10616 /* Patches value exists */
10617 lstrcpyA(patchcode, "apple");
10618 lstrcpyA(targetprod, "banana");
10619 context = 0xdeadbeef;
10620 lstrcpyA(targetsid, "kiwi");
10621 size = MAX_PATH;
10622 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10623 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10624 &context, targetsid, &size);
10625 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10626 ok(!lstrcmpA(patchcode, "apple"),
10627 "Expected patchcode to be unchanged, got %s\n", patchcode);
10628 ok(!lstrcmpA(targetprod, "banana"),
10629 "Expected targetprod to be unchanged, got %s\n", targetprod);
10630 ok(context == 0xdeadbeef,
10631 "Expected context to be unchanged, got %d\n", context);
10632 ok(!lstrcmpA(targetsid, "kiwi"),
10633 "Expected targetsid to be unchanged, got %s\n", targetsid);
10634 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10635
10636 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10637 (const BYTE *)"whatever", 9);
10638 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10639
10640 /* patch code value exists */
10641 lstrcpyA(patchcode, "apple");
10642 lstrcpyA(targetprod, "banana");
10643 context = 0xdeadbeef;
10644 lstrcpyA(targetsid, "kiwi");
10645 size = MAX_PATH;
10646 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10647 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10648 &context, targetsid, &size);
10649 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10650 ok(!lstrcmpA(patchcode, patch),
10651 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10652 ok(!lstrcmpA(targetprod, prodcode),
10653 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10654 ok(context == MSIINSTALLCONTEXT_MACHINE,
10655 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10656 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10657 ok(size == 0, "Expected 0, got %d\n", size);
10658
10659 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10660 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10661 lstrcatA(keypath, prod_squashed);
10662
10663 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10664 if (res == ERROR_ACCESS_DENIED)
10665 {
10666 skip("Not enough rights to perform tests\n");
10667 goto done;
10668 }
10669 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10670
10671 /* local UserData product key exists */
10672 lstrcpyA(patchcode, "apple");
10673 lstrcpyA(targetprod, "banana");
10674 context = 0xdeadbeef;
10675 lstrcpyA(targetsid, "kiwi");
10676 size = MAX_PATH;
10677 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10678 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10679 &context, targetsid, &size);
10680 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10681 ok(!lstrcmpA(patchcode, patch),
10682 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10683 ok(!lstrcmpA(targetprod, prodcode),
10684 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10685 ok(context == MSIINSTALLCONTEXT_MACHINE,
10686 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10687 ok(!lstrcmpA(targetsid, ""),
10688 "Expected \"\", got \"%s\"\n", targetsid);
10689 ok(size == 0, "Expected 0, got %d\n", size);
10690
10691 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10692 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10693
10694 /* local UserData Patches key exists */
10695 lstrcpyA(patchcode, "apple");
10696 lstrcpyA(targetprod, "banana");
10697 context = 0xdeadbeef;
10698 lstrcpyA(targetsid, "kiwi");
10699 size = MAX_PATH;
10700 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10701 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10702 &context, targetsid, &size);
10703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10704 ok(!lstrcmpA(patchcode, patch),
10705 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10706 ok(!lstrcmpA(targetprod, prodcode),
10707 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10708 ok(context == MSIINSTALLCONTEXT_MACHINE,
10709 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10710 ok(!lstrcmpA(targetsid, ""),
10711 "Expected \"\", got \"%s\"\n", targetsid);
10712 ok(size == 0, "Expected 0, got %d\n", size);
10713
10714 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10715 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10716
10717 /* local UserData Product patch key exists */
10718 lstrcpyA(patchcode, "apple");
10719 lstrcpyA(targetprod, "banana");
10720 context = 0xdeadbeef;
10721 lstrcpyA(targetsid, "kiwi");
10722 size = MAX_PATH;
10723 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10724 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10725 &context, targetsid, &size);
10726 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10727 ok(!lstrcmpA(patchcode, "apple"),
10728 "Expected patchcode to be unchanged, got %s\n", patchcode);
10729 ok(!lstrcmpA(targetprod, "banana"),
10730 "Expected targetprod to be unchanged, got %s\n", targetprod);
10731 ok(context == 0xdeadbeef,
10732 "Expected context to be unchanged, got %d\n", context);
10733 ok(!lstrcmpA(targetsid, "kiwi"),
10734 "Expected targetsid to be unchanged, got %s\n", targetsid);
10735 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10736
10737 data = MSIPATCHSTATE_APPLIED;
10738 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10739 (const BYTE *)&data, sizeof(DWORD));
10740 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10741
10742 /* State value exists */
10743 lstrcpyA(patchcode, "apple");
10744 lstrcpyA(targetprod, "banana");
10745 context = 0xdeadbeef;
10746 lstrcpyA(targetsid, "kiwi");
10747 size = MAX_PATH;
10748 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10749 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10750 &context, targetsid, &size);
10751 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10752 ok(!lstrcmpA(patchcode, patch),
10753 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10754 ok(!lstrcmpA(targetprod, prodcode),
10755 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10756 ok(context == MSIINSTALLCONTEXT_MACHINE,
10757 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10758 ok(!lstrcmpA(targetsid, ""),
10759 "Expected \"\", got \"%s\"\n", targetsid);
10760 ok(size == 0, "Expected 0, got %d\n", size);
10761
10762 /* MSIPATCHSTATE_SUPERSEDED */
10763
10764 lstrcpyA(patchcode, "apple");
10765 lstrcpyA(targetprod, "banana");
10766 context = 0xdeadbeef;
10767 lstrcpyA(targetsid, "kiwi");
10768 size = MAX_PATH;
10769 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10770 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10771 &context, targetsid, &size);
10772 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10773 ok(!lstrcmpA(patchcode, "apple"),
10774 "Expected patchcode to be unchanged, got %s\n", patchcode);
10775 ok(!lstrcmpA(targetprod, "banana"),
10776 "Expected targetprod to be unchanged, got %s\n", targetprod);
10777 ok(context == 0xdeadbeef,
10778 "Expected context to be unchanged, got %d\n", context);
10779 ok(!lstrcmpA(targetsid, "kiwi"),
10780 "Expected targetsid to be unchanged, got %s\n", targetsid);
10781 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10782
10783 data = MSIPATCHSTATE_SUPERSEDED;
10784 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10785 (const BYTE *)&data, sizeof(DWORD));
10786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10787
10788 /* State value is MSIPATCHSTATE_SUPERSEDED */
10789 lstrcpyA(patchcode, "apple");
10790 lstrcpyA(targetprod, "banana");
10791 context = 0xdeadbeef;
10792 lstrcpyA(targetsid, "kiwi");
10793 size = MAX_PATH;
10794 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10795 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10796 &context, targetsid, &size);
10797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10798 ok(!lstrcmpA(patchcode, patch),
10799 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10800 ok(!lstrcmpA(targetprod, prodcode),
10801 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10802 ok(context == MSIINSTALLCONTEXT_MACHINE,
10803 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10804 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10805 ok(size == 0, "Expected 0, got %d\n", size);
10806
10807 /* MSIPATCHSTATE_OBSOLETED */
10808
10809 lstrcpyA(patchcode, "apple");
10810 lstrcpyA(targetprod, "banana");
10811 context = 0xdeadbeef;
10812 lstrcpyA(targetsid, "kiwi");
10813 size = MAX_PATH;
10814 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10815 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10816 &context, targetsid, &size);
10817 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10818 ok(!lstrcmpA(patchcode, "apple"),
10819 "Expected patchcode to be unchanged, got %s\n", patchcode);
10820 ok(!lstrcmpA(targetprod, "banana"),
10821 "Expected targetprod to be unchanged, got %s\n", targetprod);
10822 ok(context == 0xdeadbeef,
10823 "Expected context to be unchanged, got %d\n", context);
10824 ok(!lstrcmpA(targetsid, "kiwi"),
10825 "Expected targetsid to be unchanged, got %s\n", targetsid);
10826 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10827
10828 data = MSIPATCHSTATE_OBSOLETED;
10829 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10830 (const BYTE *)&data, sizeof(DWORD));
10831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10832
10833 /* State value is obsoleted */
10834 lstrcpyA(patchcode, "apple");
10835 lstrcpyA(targetprod, "banana");
10836 context = 0xdeadbeef;
10837 lstrcpyA(targetsid, "kiwi");
10838 size = MAX_PATH;
10839 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10840 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10841 &context, targetsid, &size);
10842 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10843 ok(!lstrcmpA(patchcode, patch),
10844 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10845 ok(!lstrcmpA(targetprod, prodcode),
10846 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10847 ok(context == MSIINSTALLCONTEXT_MACHINE,
10848 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10849 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10850 ok(size == 0, "Expected 0, got %d\n", size);
10851
10852 /* MSIPATCHSTATE_REGISTERED */
10853 /* FIXME */
10854
10855 /* MSIPATCHSTATE_ALL */
10856
10857 /* 1st */
10858 lstrcpyA(patchcode, "apple");
10859 lstrcpyA(targetprod, "banana");
10860 context = 0xdeadbeef;
10861 lstrcpyA(targetsid, "kiwi");
10862 size = MAX_PATH;
10863 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10864 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10865 &context, targetsid, &size);
10866 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10867 ok(!lstrcmpA(patchcode, patch),
10868 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10869 ok(!lstrcmpA(targetprod, prodcode),
10870 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10871 ok(context == MSIINSTALLCONTEXT_MACHINE,
10872 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10873 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10874 ok(size == 0, "Expected 0, got %d\n", size);
10875
10876 /* same patch in multiple places, only one is enumerated */
10877 lstrcpyA(patchcode, "apple");
10878 lstrcpyA(targetprod, "banana");
10879 context = 0xdeadbeef;
10880 lstrcpyA(targetsid, "kiwi");
10881 size = MAX_PATH;
10882 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10883 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10884 &context, targetsid, &size);
10885 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10886 ok(!lstrcmpA(patchcode, "apple"),
10887 "Expected patchcode to be unchanged, got %s\n", patchcode);
10888 ok(!lstrcmpA(targetprod, "banana"),
10889 "Expected targetprod to be unchanged, got %s\n", targetprod);
10890 ok(context == 0xdeadbeef,
10891 "Expected context to be unchanged, got %d\n", context);
10892 ok(!lstrcmpA(targetsid, "kiwi"),
10893 "Expected targetsid to be unchanged, got %s\n", targetsid);
10894 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10895
10896 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10897 RegCloseKey(hpatch);
10898 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10899 RegCloseKey(udpatch);
10900
10901 done:
10902 RegDeleteValueA(patches, patch_squashed);
10903 RegDeleteValueA(patches, "Patches");
10904 delete_key(patches, "", access & KEY_WOW64_64KEY);
10905 RegCloseKey(patches);
10906 RegDeleteValueA(hpatch, "State");
10907 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10908 RegCloseKey(udprod);
10909 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10910 RegCloseKey(prodkey);
10911 }
10912
10913 static void test_MsiEnumPatchesEx(void)
10914 {
10915 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10916 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10917 CHAR patchcode[MAX_PATH];
10918 MSIINSTALLCONTEXT context;
10919 LPSTR usersid;
10920 DWORD size;
10921 UINT r;
10922
10923 if (!pMsiEnumPatchesExA)
10924 {
10925 win_skip("MsiEnumPatchesExA not implemented\n");
10926 return;
10927 }
10928
10929 create_test_guid(prodcode, prod_squashed);
10930 usersid = get_user_sid();
10931
10932 /* empty szProductCode */
10933 lstrcpyA(patchcode, "apple");
10934 lstrcpyA(targetprod, "banana");
10935 context = 0xdeadbeef;
10936 lstrcpyA(targetsid, "kiwi");
10937 size = MAX_PATH;
10938 r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10939 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10940 targetsid, &size);
10941 ok(r == ERROR_INVALID_PARAMETER,
10942 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10943 ok(!lstrcmpA(patchcode, "apple"),
10944 "Expected patchcode to be unchanged, got %s\n", patchcode);
10945 ok(!lstrcmpA(targetprod, "banana"),
10946 "Expected targetprod to be unchanged, got %s\n", targetprod);
10947 ok(context == 0xdeadbeef,
10948 "Expected context to be unchanged, got %d\n", context);
10949 ok(!lstrcmpA(targetsid, "kiwi"),
10950 "Expected targetsid to be unchanged, got %s\n", targetsid);
10951 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10952
10953 /* garbage szProductCode */
10954 lstrcpyA(patchcode, "apple");
10955 lstrcpyA(targetprod, "banana");
10956 context = 0xdeadbeef;
10957 lstrcpyA(targetsid, "kiwi");
10958 size = MAX_PATH;
10959 r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10960 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10961 targetsid, &size);
10962 ok(r == ERROR_INVALID_PARAMETER,
10963 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10964 ok(!lstrcmpA(patchcode, "apple"),
10965 "Expected patchcode to be unchanged, got %s\n", patchcode);
10966 ok(!lstrcmpA(targetprod, "banana"),
10967 "Expected targetprod to be unchanged, got %s\n", targetprod);
10968 ok(context == 0xdeadbeef,
10969 "Expected context to be unchanged, got %d\n", context);
10970 ok(!lstrcmpA(targetsid, "kiwi"),
10971 "Expected targetsid to be unchanged, got %s\n", targetsid);
10972 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10973
10974 /* guid without brackets */
10975 lstrcpyA(patchcode, "apple");
10976 lstrcpyA(targetprod, "banana");
10977 context = 0xdeadbeef;
10978 lstrcpyA(targetsid, "kiwi");
10979 size = MAX_PATH;
10980 r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
10981 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10982 0, patchcode, targetprod, &context,
10983 targetsid, &size);
10984 ok(r == ERROR_INVALID_PARAMETER,
10985 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10986 ok(!lstrcmpA(patchcode, "apple"),
10987 "Expected patchcode to be unchanged, got %s\n", patchcode);
10988 ok(!lstrcmpA(targetprod, "banana"),
10989 "Expected targetprod to be unchanged, got %s\n", targetprod);
10990 ok(context == 0xdeadbeef,
10991 "Expected context to be unchanged, got %d\n", context);
10992 ok(!lstrcmpA(targetsid, "kiwi"),
10993 "Expected targetsid to be unchanged, got %s\n", targetsid);
10994 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10995
10996 /* guid with brackets */
10997 lstrcpyA(patchcode, "apple");
10998 lstrcpyA(targetprod, "banana");
10999 context = 0xdeadbeef;
11000 lstrcpyA(targetsid, "kiwi");
11001 size = MAX_PATH;
11002 r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
11003 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
11004 0, patchcode, targetprod, &context,
11005 targetsid, &size);
11006 ok(r == ERROR_NO_MORE_ITEMS,
11007 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11008 ok(!lstrcmpA(patchcode, "apple"),
11009 "Expected patchcode to be unchanged, got %s\n", patchcode);
11010 ok(!lstrcmpA(targetprod, "banana"),
11011 "Expected targetprod to be unchanged, got %s\n", targetprod);
11012 ok(context == 0xdeadbeef,
11013 "Expected context to be unchanged, got %d\n", context);
11014 ok(!lstrcmpA(targetsid, "kiwi"),
11015 "Expected targetsid to be unchanged, got %s\n", targetsid);
11016 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11017
11018 /* szUserSid is S-1-5-18 */
11019 lstrcpyA(patchcode, "apple");
11020 lstrcpyA(targetprod, "banana");
11021 context = 0xdeadbeef;
11022 lstrcpyA(targetsid, "kiwi");
11023 size = MAX_PATH;
11024 r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
11025 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
11026 0, patchcode, targetprod, &context,
11027 targetsid, &size);
11028 ok(r == ERROR_INVALID_PARAMETER,
11029 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11030 ok(!lstrcmpA(patchcode, "apple"),
11031 "Expected patchcode to be unchanged, got %s\n", patchcode);
11032 ok(!lstrcmpA(targetprod, "banana"),
11033 "Expected targetprod to be unchanged, got %s\n", targetprod);
11034 ok(context == 0xdeadbeef,
11035 "Expected context to be unchanged, got %d\n", context);
11036 ok(!lstrcmpA(targetsid, "kiwi"),
11037 "Expected targetsid to be unchanged, got %s\n", targetsid);
11038 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11039
11040 /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
11041 lstrcpyA(patchcode, "apple");
11042 lstrcpyA(targetprod, "banana");
11043 context = 0xdeadbeef;
11044 lstrcpyA(targetsid, "kiwi");
11045 size = MAX_PATH;
11046 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
11047 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11048 &context, targetsid, &size);
11049 ok(r == ERROR_INVALID_PARAMETER,
11050 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11051 ok(!lstrcmpA(patchcode, "apple"),
11052 "Expected patchcode to be unchanged, got %s\n", patchcode);
11053 ok(!lstrcmpA(targetprod, "banana"),
11054 "Expected targetprod to be unchanged, got %s\n", targetprod);
11055 ok(context == 0xdeadbeef,
11056 "Expected context to be unchanged, got %d\n", context);
11057 ok(!lstrcmpA(targetsid, "kiwi"),
11058 "Expected targetsid to be unchanged, got %s\n", targetsid);
11059 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11060
11061 /* dwContext is out of bounds */
11062 lstrcpyA(patchcode, "apple");
11063 lstrcpyA(targetprod, "banana");
11064 context = 0xdeadbeef;
11065 lstrcpyA(targetsid, "kiwi");
11066 size = MAX_PATH;
11067 r = pMsiEnumPatchesExA(prodcode, usersid, 0,
11068 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11069 &context, targetsid, &size);
11070 ok(r == ERROR_INVALID_PARAMETER,
11071 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11072 ok(!lstrcmpA(patchcode, "apple"),
11073 "Expected patchcode to be unchanged, got %s\n", patchcode);
11074 ok(!lstrcmpA(targetprod, "banana"),
11075 "Expected targetprod to be unchanged, got %s\n", targetprod);
11076 ok(context == 0xdeadbeef,
11077 "Expected context to be unchanged, got %d\n", context);
11078 ok(!lstrcmpA(targetsid, "kiwi"),
11079 "Expected targetsid to be unchanged, got %s\n", targetsid);
11080 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11081
11082 /* dwContext is out of bounds */
11083 lstrcpyA(patchcode, "apple");
11084 lstrcpyA(targetprod, "banana");
11085 context = 0xdeadbeef;
11086 lstrcpyA(targetsid, "kiwi");
11087 size = MAX_PATH;
11088 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
11089 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11090 &context, targetsid, &size);
11091 ok(r == ERROR_INVALID_PARAMETER,
11092 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11093 ok(!lstrcmpA(patchcode, "apple"),
11094 "Expected patchcode to be unchanged, got %s\n", patchcode);
11095 ok(!lstrcmpA(targetprod, "banana"),
11096 "Expected targetprod to be unchanged, got %s\n", targetprod);
11097 ok(context == 0xdeadbeef,
11098 "Expected context to be unchanged, got %d\n", context);
11099 ok(!lstrcmpA(targetsid, "kiwi"),
11100 "Expected targetsid to be unchanged, got %s\n", targetsid);
11101 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11102
11103 /* dwFilter is out of bounds */
11104 lstrcpyA(patchcode, "apple");
11105 lstrcpyA(targetprod, "banana");
11106 context = 0xdeadbeef;
11107 lstrcpyA(targetsid, "kiwi");
11108 size = MAX_PATH;
11109 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11110 MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
11111 &context, targetsid, &size);
11112 ok(r == ERROR_INVALID_PARAMETER,
11113 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11114 ok(!lstrcmpA(patchcode, "apple"),
11115 "Expected patchcode to be unchanged, got %s\n", patchcode);
11116 ok(!lstrcmpA(targetprod, "banana"),
11117 "Expected targetprod to be unchanged, got %s\n", targetprod);
11118 ok(context == 0xdeadbeef,
11119 "Expected context to be unchanged, got %d\n", context);
11120 ok(!lstrcmpA(targetsid, "kiwi"),
11121 "Expected targetsid to be unchanged, got %s\n", targetsid);
11122 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11123
11124 /* dwFilter is out of bounds */
11125 lstrcpyA(patchcode, "apple");
11126 lstrcpyA(targetprod, "banana");
11127 context = 0xdeadbeef;
11128 lstrcpyA(targetsid, "kiwi");
11129 size = MAX_PATH;
11130 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11131 MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
11132 &context, targetsid, &size);
11133 ok(r == ERROR_INVALID_PARAMETER,
11134 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11135 ok(!lstrcmpA(patchcode, "apple"),
11136 "Expected patchcode to be unchanged, got %s\n", patchcode);
11137 ok(!lstrcmpA(targetprod, "banana"),
11138 "Expected targetprod to be unchanged, got %s\n", targetprod);
11139 ok(context == 0xdeadbeef,
11140 "Expected context to be unchanged, got %d\n", context);
11141 ok(!lstrcmpA(targetsid, "kiwi"),
11142 "Expected targetsid to be unchanged, got %s\n", targetsid);
11143 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11144
11145 /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
11146 lstrcpyA(patchcode, "apple");
11147 lstrcpyA(targetprod, "banana");
11148 context = 0xdeadbeef;
11149 lstrcpyA(targetsid, "kiwi");
11150 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11151 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11152 &context, targetsid, NULL);
11153 ok(r == ERROR_INVALID_PARAMETER,
11154 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11155 ok(!lstrcmpA(patchcode, "apple"),
11156 "Expected patchcode to be unchanged, got %s\n", patchcode);
11157 ok(!lstrcmpA(targetprod, "banana"),
11158 "Expected targetprod to be unchanged, got %s\n", targetprod);
11159 ok(context == 0xdeadbeef,
11160 "Expected context to be unchanged, got %d\n", context);
11161 ok(!lstrcmpA(targetsid, "kiwi"),
11162 "Expected targetsid to be unchanged, got %s\n", targetsid);
11163
11164 test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
11165 test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
11166 test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
11167 test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
11168 test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
11169 /* FIXME: Successfully test userunmanaged with a different user */
11170 test_MsiEnumPatchesEx_machine();
11171 LocalFree(usersid);
11172 }
11173
11174 static void test_MsiEnumPatches(void)
11175 {
11176 CHAR keypath[MAX_PATH], patch[MAX_PATH];
11177 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
11178 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11179 CHAR transforms[MAX_PATH];
11180 WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
11181 HKEY prodkey, patches, udprod;
11182 HKEY userkey, hpatch, udpatch;
11183 DWORD size, data;
11184 LPSTR usersid;
11185 LONG res;
11186 UINT r;
11187 REGSAM access = KEY_ALL_ACCESS;
11188
11189 create_test_guid(prodcode, prod_squashed);
11190 create_test_guid(patchcode, patch_squashed);
11191 usersid = get_user_sid();
11192
11193 if (is_wow64)
11194 access |= KEY_WOW64_64KEY;
11195
11196 /* NULL szProduct */
11197 size = MAX_PATH;
11198 lstrcpyA(patch, "apple");
11199 lstrcpyA(transforms, "banana");
11200 r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
11201 ok(r == ERROR_INVALID_PARAMETER,
11202 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11203 ok(!lstrcmpA(patch, "apple"),
11204 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11205 ok(!lstrcmpA(transforms, "banana"),
11206 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11207 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11208
11209 /* empty szProduct */
11210 size = MAX_PATH;
11211 lstrcpyA(patch, "apple");
11212 lstrcpyA(transforms, "banana");
11213 r = MsiEnumPatchesA("", 0, patch, transforms, &size);
11214 ok(r == ERROR_INVALID_PARAMETER,
11215 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11216 ok(!lstrcmpA(patch, "apple"),
11217 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11218 ok(!lstrcmpA(transforms, "banana"),
11219 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11220 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11221
11222 /* garbage szProduct */
11223 size = MAX_PATH;
11224 lstrcpyA(patch, "apple");
11225 lstrcpyA(transforms, "banana");
11226 r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
11227 ok(r == ERROR_INVALID_PARAMETER,
11228 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11229 ok(!lstrcmpA(patch, "apple"),
11230 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11231 ok(!lstrcmpA(transforms, "banana"),
11232 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11233 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11234
11235 /* guid without brackets */
11236 size = MAX_PATH;
11237 lstrcpyA(patch, "apple");
11238 lstrcpyA(transforms, "banana");
11239 r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
11240 transforms, &size);
11241 ok(r == ERROR_INVALID_PARAMETER,
11242 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11243 ok(!lstrcmpA(patch, "apple"),
11244 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11245 ok(!lstrcmpA(transforms, "banana"),
11246 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11247 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11248
11249 /* guid with brackets */
11250 size = MAX_PATH;
11251 lstrcpyA(patch, "apple");
11252 lstrcpyA(transforms, "banana");
11253 r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
11254 transforms, &size);
11255 ok(r == ERROR_UNKNOWN_PRODUCT,
11256 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11257 ok(!lstrcmpA(patch, "apple"),
11258 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11259 ok(!lstrcmpA(transforms, "banana"),
11260 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11261 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11262
11263 /* same length as guid, but random */
11264 size = MAX_PATH;
11265 lstrcpyA(patch, "apple");
11266 lstrcpyA(transforms, "banana");
11267 r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
11268 transforms, &size);
11269 ok(r == ERROR_INVALID_PARAMETER,
11270 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11271 ok(!lstrcmpA(patch, "apple"),
11272 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11273 ok(!lstrcmpA(transforms, "banana"),
11274 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11275 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11276
11277 /* MSIINSTALLCONTEXT_USERMANAGED */
11278
11279 size = MAX_PATH;
11280 lstrcpyA(patch, "apple");
11281 lstrcpyA(transforms, "banana");
11282 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11283 ok(r == ERROR_UNKNOWN_PRODUCT,
11284 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11285 ok(!lstrcmpA(patch, "apple"),
11286 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11287 ok(!lstrcmpA(transforms, "banana"),
11288 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11289 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11290
11291 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11292 lstrcatA(keypath, usersid);
11293 lstrcatA(keypath, "\\Installer\\Products\\");
11294 lstrcatA(keypath, prod_squashed);
11295
11296 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11297 if (res == ERROR_ACCESS_DENIED)
11298 {
11299 skip("Not enough rights to perform tests\n");
11300 LocalFree(usersid);
11301 return;
11302 }
11303 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11304
11305 /* managed product key exists */
11306 size = MAX_PATH;
11307 lstrcpyA(patch, "apple");
11308 lstrcpyA(transforms, "banana");
11309 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11310 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11311 ok(!lstrcmpA(patch, "apple"),
11312 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11313 ok(!lstrcmpA(transforms, "banana"),
11314 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11315 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11316
11317 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11318 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11319
11320 /* patches key exists */
11321 size = MAX_PATH;
11322 lstrcpyA(patch, "apple");
11323 lstrcpyA(transforms, "banana");
11324 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11325 ok(r == ERROR_NO_MORE_ITEMS ||
11326 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11327 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11328 ok(!lstrcmpA(patch, "apple"),
11329 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11330 ok(!lstrcmpA(transforms, "banana"),
11331 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11332 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11333
11334 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11335 (const BYTE *)patch_squashed,
11336 lstrlenA(patch_squashed) + 1);
11337 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11338
11339 /* Patches value exists, is not REG_MULTI_SZ */
11340 size = MAX_PATH;
11341 lstrcpyA(patch, "apple");
11342 lstrcpyA(transforms, "banana");
11343 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11344 ok(r == ERROR_BAD_CONFIGURATION ||
11345 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11346 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11347 ok(!lstrcmpA(patch, "apple"),
11348 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11349 ok(!lstrcmpA(transforms, "banana"),
11350 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11351 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11352
11353 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11354 (const BYTE *)"a\0b\0c\0\0", 7);
11355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11356
11357 /* Patches value exists, is not a squashed guid */
11358 size = MAX_PATH;
11359 lstrcpyA(patch, "apple");
11360 lstrcpyA(transforms, "banana");
11361 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11362 ok(r == ERROR_BAD_CONFIGURATION,
11363 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11364 ok(!lstrcmpA(patch, "apple"),
11365 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11366 ok(!lstrcmpA(transforms, "banana"),
11367 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11368 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11369
11370 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11371 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11372 (const BYTE *)patch_squashed,
11373 lstrlenA(patch_squashed) + 2);
11374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11375
11376 /* Patches value exists */
11377 size = MAX_PATH;
11378 lstrcpyA(patch, "apple");
11379 lstrcpyA(transforms, "banana");
11380 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11381 ok(r == ERROR_NO_MORE_ITEMS ||
11382 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11383 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11384 ok(!lstrcmpA(patch, "apple") ||
11385 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11386 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11387 ok(!lstrcmpA(transforms, "banana"),
11388 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11389 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11390
11391 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11392 (const BYTE *)"whatever", 9);
11393 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11394
11395 /* patch squashed value exists */
11396 size = MAX_PATH;
11397 lstrcpyA(patch, "apple");
11398 lstrcpyA(transforms, "banana");
11399 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11400 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11401 ok(!lstrcmpA(patch, patchcode),
11402 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11403 ok(!lstrcmpA(transforms, "whatever"),
11404 "Expected \"whatever\", got \"%s\"\n", transforms);
11405 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11406
11407 /* lpPatchBuf is NULL */
11408 size = MAX_PATH;
11409 lstrcpyA(transforms, "banana");
11410 r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
11411 ok(r == ERROR_INVALID_PARAMETER,
11412 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
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 /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
11418 size = MAX_PATH;
11419 lstrcpyA(patch, "apple");
11420 r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
11421 ok(r == ERROR_INVALID_PARAMETER,
11422 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11423 ok(!lstrcmpA(patch, "apple"),
11424 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11425 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11426
11427 /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
11428 lstrcpyA(patch, "apple");
11429 lstrcpyA(transforms, "banana");
11430 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
11431 ok(r == ERROR_INVALID_PARAMETER,
11432 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11433 ok(!lstrcmpA(patch, "apple"),
11434 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11435 ok(!lstrcmpA(transforms, "banana"),
11436 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11437
11438 /* pcchTransformsBuf is too small */
11439 size = 6;
11440 lstrcpyA(patch, "apple");
11441 lstrcpyA(transforms, "banana");
11442 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11443 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11444 ok(!lstrcmpA(patch, patchcode),
11445 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11446 ok(!lstrcmpA(transforms, "whate") ||
11447 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11448 "Expected \"whate\", got \"%s\"\n", transforms);
11449 ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
11450
11451 /* increase the index */
11452 size = MAX_PATH;
11453 lstrcpyA(patch, "apple");
11454 lstrcpyA(transforms, "banana");
11455 r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
11456 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11457 ok(!lstrcmpA(patch, "apple"),
11458 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11459 ok(!lstrcmpA(transforms, "banana"),
11460 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11461 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11462
11463 /* increase again */
11464 size = MAX_PATH;
11465 lstrcpyA(patch, "apple");
11466 lstrcpyA(transforms, "banana");
11467 r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
11468 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11469 ok(!lstrcmpA(patch, "apple"),
11470 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11471 ok(!lstrcmpA(transforms, "banana"),
11472 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11473 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11474
11475 RegDeleteValueA(patches, "Patches");
11476 delete_key(patches, "", access & KEY_WOW64_64KEY);
11477 RegCloseKey(patches);
11478 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11479 RegCloseKey(prodkey);
11480
11481 /* MSIINSTALLCONTEXT_USERUNMANAGED */
11482
11483 size = MAX_PATH;
11484 lstrcpyA(patch, "apple");
11485 lstrcpyA(transforms, "banana");
11486 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11487 ok(r == ERROR_UNKNOWN_PRODUCT,
11488 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11489 ok(!lstrcmpA(patch, "apple"),
11490 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11491 ok(!lstrcmpA(transforms, "banana"),
11492 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11493 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11494
11495 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11496 lstrcatA(keypath, prod_squashed);
11497
11498 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11499 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11500
11501 /* current user product key exists */
11502 size = MAX_PATH;
11503 lstrcpyA(patch, "apple");
11504 lstrcpyA(transforms, "banana");
11505 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11506 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11507 ok(!lstrcmpA(patch, "apple"),
11508 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11509 ok(!lstrcmpA(transforms, "banana"),
11510 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11511 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11512
11513 res = RegCreateKeyA(prodkey, "Patches", &patches);
11514 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11515
11516 /* Patches key exists */
11517 size = MAX_PATH;
11518 lstrcpyA(patch, "apple");
11519 lstrcpyA(transforms, "banana");
11520 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11521 ok(r == ERROR_NO_MORE_ITEMS ||
11522 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11523 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11524 ok(!lstrcmpA(patch, "apple"),
11525 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11526 ok(!lstrcmpA(transforms, "banana"),
11527 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11528 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11529
11530 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11531 (const BYTE *)patch_squashed,
11532 lstrlenA(patch_squashed) + 1);
11533 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11534
11535 /* Patches value exists, is not REG_MULTI_SZ */
11536 size = MAX_PATH;
11537 lstrcpyA(patch, "apple");
11538 lstrcpyA(transforms, "banana");
11539 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11540 ok(r == ERROR_BAD_CONFIGURATION ||
11541 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11542 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11543 ok(!lstrcmpA(patch, "apple"),
11544 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11545 ok(!lstrcmpA(transforms, "banana"),
11546 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11547 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11548
11549 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11550 (const BYTE *)"a\0b\0c\0\0", 7);
11551 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11552
11553 /* Patches value exists, is not a squashed guid */
11554 size = MAX_PATH;
11555 lstrcpyA(patch, "apple");
11556 lstrcpyA(transforms, "banana");
11557 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11558 ok(r == ERROR_BAD_CONFIGURATION,
11559 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11560 ok(!lstrcmpA(patch, "apple"),
11561 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11562 ok(!lstrcmpA(transforms, "banana"),
11563 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11564 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11565
11566 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11567 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11568 (const BYTE *)patch_squashed,
11569 lstrlenA(patch_squashed) + 2);
11570 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11571
11572 /* Patches value exists */
11573 size = MAX_PATH;
11574 lstrcpyA(patch, "apple");
11575 lstrcpyA(transforms, "banana");
11576 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11577 ok(r == ERROR_NO_MORE_ITEMS ||
11578 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11579 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11580 ok(!lstrcmpA(patch, "apple") ||
11581 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11582 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11583 ok(!lstrcmpA(transforms, "banana"),
11584 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11585 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11586
11587 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11588 (const BYTE *)"whatever", 9);
11589 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11590
11591 /* patch code value exists */
11592 size = MAX_PATH;
11593 lstrcpyA(patch, "apple");
11594 lstrcpyA(transforms, "banana");
11595 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11596 ok(r == ERROR_NO_MORE_ITEMS ||
11597 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11598 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11599 ok(!lstrcmpA(patch, "apple") ||
11600 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11601 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11602 ok(!lstrcmpA(transforms, "banana") ||
11603 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11604 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11605 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11606
11607 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11608 lstrcatA(keypath, usersid);
11609 lstrcatA(keypath, "\\Patches\\");
11610 lstrcatA(keypath, patch_squashed);
11611
11612 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
11613 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11614
11615 /* userdata patch key exists */
11616 size = MAX_PATH;
11617 lstrcpyA(patch, "apple");
11618 lstrcpyA(transforms, "banana");
11619 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11620 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11621 ok(!lstrcmpA(patch, patchcode),
11622 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11623 ok(!lstrcmpA(transforms, "whatever"),
11624 "Expected \"whatever\", got \"%s\"\n", transforms);
11625 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11626
11627 delete_key(userkey, "", access & KEY_WOW64_64KEY);
11628 RegCloseKey(userkey);
11629 RegDeleteValueA(patches, patch_squashed);
11630 RegDeleteValueA(patches, "Patches");
11631 RegDeleteKeyA(patches, "");
11632 RegCloseKey(patches);
11633 RegDeleteKeyA(prodkey, "");
11634 RegCloseKey(prodkey);
11635
11636 /* MSIINSTALLCONTEXT_MACHINE */
11637
11638 size = MAX_PATH;
11639 lstrcpyA(patch, "apple");
11640 lstrcpyA(transforms, "banana");
11641 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11642 ok(r == ERROR_UNKNOWN_PRODUCT,
11643 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11644 ok(!lstrcmpA(patch, "apple"),
11645 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11646 ok(!lstrcmpA(transforms, "banana"),
11647 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11648 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11649
11650 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11651 lstrcatA(keypath, prod_squashed);
11652
11653 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11654 if (res == ERROR_ACCESS_DENIED)
11655 {
11656 skip("Not enough rights to perform tests\n");
11657 LocalFree(usersid);
11658 return;
11659 }
11660 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11661
11662 /* local product key exists */
11663 size = MAX_PATH;
11664 lstrcpyA(patch, "apple");
11665 lstrcpyA(transforms, "banana");
11666 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11667 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11668 ok(!lstrcmpA(patch, "apple"),
11669 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11670 ok(!lstrcmpA(transforms, "banana"),
11671 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11672 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11673
11674 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11675 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11676
11677 /* Patches key exists */
11678 size = MAX_PATH;
11679 lstrcpyA(patch, "apple");
11680 lstrcpyA(transforms, "banana");
11681 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11682 ok(r == ERROR_NO_MORE_ITEMS ||
11683 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11684 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11685 ok(!lstrcmpA(patch, "apple"),
11686 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11687 ok(!lstrcmpA(transforms, "banana"),
11688 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11689 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11690
11691 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11692 (const BYTE *)patch_squashed,
11693 lstrlenA(patch_squashed) + 1);
11694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11695
11696 /* Patches value exists, is not REG_MULTI_SZ */
11697 size = MAX_PATH;
11698 lstrcpyA(patch, "apple");
11699 lstrcpyA(transforms, "banana");
11700 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11701 ok(r == ERROR_BAD_CONFIGURATION ||
11702 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11703 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11704 ok(!lstrcmpA(patch, "apple"),
11705 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11706 ok(!lstrcmpA(transforms, "banana"),
11707 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11708 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11709
11710 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11711 (const BYTE *)"a\0b\0c\0\0", 7);
11712 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11713
11714 /* Patches value exists, is not a squashed guid */
11715 size = MAX_PATH;
11716 lstrcpyA(patch, "apple");
11717 lstrcpyA(transforms, "banana");
11718 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11719 ok(r == ERROR_BAD_CONFIGURATION,
11720 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11721 ok(!lstrcmpA(patch, "apple"),
11722 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11723 ok(!lstrcmpA(transforms, "banana"),
11724 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11725 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11726
11727 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11728 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11729 (const BYTE *)patch_squashed,
11730 lstrlenA(patch_squashed) + 2);
11731 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11732
11733 /* Patches value exists */
11734 size = MAX_PATH;
11735 lstrcpyA(patch, "apple");
11736 lstrcpyA(transforms, "banana");
11737 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11738 ok(r == ERROR_NO_MORE_ITEMS ||
11739 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11740 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11741 ok(!lstrcmpA(patch, "apple") ||
11742 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11743 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11744 ok(!lstrcmpA(transforms, "banana"),
11745 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11746 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11747
11748 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11749 (const BYTE *)"whatever", 9);
11750 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11751
11752 /* patch code value exists */
11753 size = MAX_PATH;
11754 lstrcpyA(patch, "apple");
11755 lstrcpyA(transforms, "banana");
11756 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11758 ok(!lstrcmpA(patch, patchcode),
11759 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11760 ok(!lstrcmpA(transforms, "whatever"),
11761 "Expected \"whatever\", got \"%s\"\n", transforms);
11762 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11763
11764 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
11765 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
11766 lstrcatA(keypath, prod_squashed);
11767
11768 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11769 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11770
11771 /* local UserData product key exists */
11772 size = MAX_PATH;
11773 lstrcpyA(patch, "apple");
11774 lstrcpyA(transforms, "banana");
11775 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11777 ok(!lstrcmpA(patch, patchcode),
11778 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11779 ok(!lstrcmpA(transforms, "whatever"),
11780 "Expected \"whatever\", got \"%s\"\n", transforms);
11781 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11782
11783 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
11784 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11785
11786 /* local UserData Patches key exists */
11787 size = MAX_PATH;
11788 lstrcpyA(patch, "apple");
11789 lstrcpyA(transforms, "banana");
11790 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11792 ok(!lstrcmpA(patch, patchcode),
11793 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11794 ok(!lstrcmpA(transforms, "whatever"),
11795 "Expected \"whatever\", got \"%s\"\n", transforms);
11796 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11797
11798 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11799 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11800
11801 /* local UserData Product patch key exists */
11802 size = MAX_PATH;
11803 lstrcpyA(patch, "apple");
11804 lstrcpyA(transforms, "banana");
11805 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11806 ok(r == ERROR_NO_MORE_ITEMS ||
11807 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11808 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11809 ok(!lstrcmpA(patch, "apple") ||
11810 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11811 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11812 ok(!lstrcmpA(transforms, "banana") ||
11813 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11814 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11815 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11816
11817 data = MSIPATCHSTATE_APPLIED;
11818 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11819 (const BYTE *)&data, sizeof(DWORD));
11820 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11821
11822 /* State value exists */
11823 size = MAX_PATH;
11824 lstrcpyA(patch, "apple");
11825 lstrcpyA(transforms, "banana");
11826 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11827 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11828 ok(!lstrcmpA(patch, patchcode),
11829 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11830 ok(!lstrcmpA(transforms, "whatever"),
11831 "Expected \"whatever\", got \"%s\"\n", transforms);
11832 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11833
11834 /* now duplicate some of the tests for the W version */
11835
11836 /* pcchTransformsBuf is too small */
11837 size = 6;
11838 MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
11839 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11840 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11841 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11842 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11843 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11844 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11845 ok(!lstrcmpA(patch, patchcode),
11846 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11847 ok(!lstrcmpA(transforms, "whate") ||
11848 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11849 "Expected \"whate\", got \"%s\"\n", transforms);
11850 ok(size == 8, "Expected 8, got %d\n", size);
11851
11852 /* patch code value exists */
11853 size = MAX_PATH;
11854 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11855 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11856 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11857 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11858 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11859 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11860 ok(!lstrcmpA(patch, patchcode),
11861 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11862 ok(!lstrcmpA(transforms, "whatever"),
11863 "Expected \"whatever\", got \"%s\"\n", transforms);
11864 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11865
11866 RegDeleteValueA(patches, patch_squashed);
11867 RegDeleteValueA(patches, "Patches");
11868 delete_key(patches, "", access & KEY_WOW64_64KEY);
11869 RegCloseKey(patches);
11870 RegDeleteValueA(hpatch, "State");
11871 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11872 RegCloseKey(hpatch);
11873 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11874 RegCloseKey(udpatch);
11875 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11876 RegCloseKey(udprod);
11877 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11878 RegCloseKey(prodkey);
11879 LocalFree(usersid);
11880 }
11881
11882 static void test_MsiGetPatchInfoEx(void)
11883 {
11884 CHAR keypath[MAX_PATH], val[MAX_PATH];
11885 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
11886 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11887 HKEY prodkey, patches, udprod, props;
11888 HKEY hpatch, udpatch, prodpatches;
11889 LPSTR usersid;
11890 DWORD size;
11891 LONG res;
11892 UINT r;
11893 REGSAM access = KEY_ALL_ACCESS;
11894
11895 if (!pMsiGetPatchInfoExA)
11896 {
11897 win_skip("MsiGetPatchInfoEx not implemented\n");
11898 return;
11899 }
11900
11901 create_test_guid(prodcode, prod_squashed);
11902 create_test_guid(patchcode, patch_squashed);
11903 usersid = get_user_sid();
11904
11905 if (is_wow64)
11906 access |= KEY_WOW64_64KEY;
11907
11908 /* NULL szPatchCode */
11909 lstrcpyA(val, "apple");
11910 size = MAX_PATH;
11911 r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11912 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11913 ok(r == ERROR_INVALID_PARAMETER,
11914 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11915 ok(!lstrcmpA(val, "apple"),
11916 "Expected val to be unchanged, got \"%s\"\n", val);
11917 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11918
11919 /* empty szPatchCode */
11920 size = MAX_PATH;
11921 lstrcpyA(val, "apple");
11922 r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11923 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11924 ok(r == ERROR_INVALID_PARAMETER,
11925 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11926 ok(!lstrcmpA(val, "apple"),
11927 "Expected val to be unchanged, got \"%s\"\n", val);
11928 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11929
11930 /* garbage szPatchCode */
11931 size = MAX_PATH;
11932 lstrcpyA(val, "apple");
11933 r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
11934 MSIINSTALLCONTEXT_USERMANAGED,
11935 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11936 ok(r == ERROR_INVALID_PARAMETER,
11937 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11938 ok(!lstrcmpA(val, "apple"),
11939 "Expected val to be unchanged, got \"%s\"\n", val);
11940 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11941
11942 /* guid without brackets */
11943 size = MAX_PATH;
11944 lstrcpyA(val, "apple");
11945 r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
11946 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11947 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11948 ok(r == ERROR_INVALID_PARAMETER,
11949 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11950 ok(!lstrcmpA(val, "apple"),
11951 "Expected val to be unchanged, got \"%s\"\n", val);
11952 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11953
11954 /* guid with brackets */
11955 size = MAX_PATH;
11956 lstrcpyA(val, "apple");
11957 r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
11958 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11959 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11960 ok(r == ERROR_UNKNOWN_PRODUCT,
11961 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11962 ok(!lstrcmpA(val, "apple"),
11963 "Expected val to be unchanged, got \"%s\"\n", val);
11964 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11965
11966 /* same length as guid, but random */
11967 size = MAX_PATH;
11968 lstrcpyA(val, "apple");
11969 r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
11970 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11971 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11972 ok(r == ERROR_INVALID_PARAMETER,
11973 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11974 ok(!lstrcmpA(val, "apple"),
11975 "Expected val to be unchanged, got \"%s\"\n", val);
11976 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11977
11978 /* NULL szProductCode */
11979 lstrcpyA(val, "apple");
11980 size = MAX_PATH;
11981 r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11982 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11983 ok(r == ERROR_INVALID_PARAMETER,
11984 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11985 ok(!lstrcmpA(val, "apple"),
11986 "Expected val to be unchanged, got \"%s\"\n", val);
11987 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11988
11989 /* empty szProductCode */
11990 size = MAX_PATH;
11991 lstrcpyA(val, "apple");
11992 r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
11993 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11994 ok(r == ERROR_INVALID_PARAMETER,
11995 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11996 ok(!lstrcmpA(val, "apple"),
11997 "Expected val to be unchanged, got \"%s\"\n", val);
11998 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11999
12000 /* garbage szProductCode */
12001 size = MAX_PATH;
12002 lstrcpyA(val, "apple");
12003 r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
12004 MSIINSTALLCONTEXT_USERMANAGED,
12005 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12006 ok(r == ERROR_INVALID_PARAMETER,
12007 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12008 ok(!lstrcmpA(val, "apple"),
12009 "Expected val to be unchanged, got \"%s\"\n", val);
12010 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12011
12012 /* guid without brackets */
12013 size = MAX_PATH;
12014 lstrcpyA(val, "apple");
12015 r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
12016 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12017 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12018 ok(r == ERROR_INVALID_PARAMETER,
12019 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12020 ok(!lstrcmpA(val, "apple"),
12021 "Expected val to be unchanged, got \"%s\"\n", val);
12022 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12023
12024 /* guid with brackets */
12025 size = MAX_PATH;
12026 lstrcpyA(val, "apple");
12027 r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
12028 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12029 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12030 ok(r == ERROR_UNKNOWN_PRODUCT,
12031 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12032 ok(!lstrcmpA(val, "apple"),
12033 "Expected val to be unchanged, got \"%s\"\n", val);
12034 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12035
12036 /* same length as guid, but random */
12037 size = MAX_PATH;
12038 lstrcpyA(val, "apple");
12039 r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
12040 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12041 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12042 ok(r == ERROR_INVALID_PARAMETER,
12043 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12044 ok(!lstrcmpA(val, "apple"),
12045 "Expected val to be unchanged, got \"%s\"\n", val);
12046 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12047
12048 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
12049 size = MAX_PATH;
12050 lstrcpyA(val, "apple");
12051 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
12052 MSIINSTALLCONTEXT_USERMANAGED,
12053 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12054 ok(r == ERROR_INVALID_PARAMETER,
12055 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12056 ok(!lstrcmpA(val, "apple"),
12057 "Expected val to be unchanged, got \"%s\"\n", val);
12058 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12059
12060 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
12061 size = MAX_PATH;
12062 lstrcpyA(val, "apple");
12063 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
12064 MSIINSTALLCONTEXT_USERUNMANAGED,
12065 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12066 ok(r == ERROR_INVALID_PARAMETER,
12067 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12068 ok(!lstrcmpA(val, "apple"),
12069 "Expected val to be unchanged, got \"%s\"\n", val);
12070 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12071
12072 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
12073 size = MAX_PATH;
12074 lstrcpyA(val, "apple");
12075 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
12076 MSIINSTALLCONTEXT_MACHINE,
12077 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12078 ok(r == ERROR_INVALID_PARAMETER,
12079 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12080 ok(!lstrcmpA(val, "apple"),
12081 "Expected val to be unchanged, got \"%s\"\n", val);
12082 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12083
12084 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
12085 size = MAX_PATH;
12086 lstrcpyA(val, "apple");
12087 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12088 MSIINSTALLCONTEXT_MACHINE,
12089 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12090 ok(r == ERROR_INVALID_PARAMETER,
12091 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12092 ok(!lstrcmpA(val, "apple"),
12093 "Expected val to be unchanged, got \"%s\"\n", val);
12094 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12095
12096 /* dwContext is out of range */
12097 size = MAX_PATH;
12098 lstrcpyA(val, "apple");
12099 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12100 MSIINSTALLCONTEXT_NONE,
12101 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12102 ok(r == ERROR_INVALID_PARAMETER,
12103 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12104 ok(!lstrcmpA(val, "apple"),
12105 "Expected val to be unchanged, got \"%s\"\n", val);
12106 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12107
12108 /* dwContext is out of range */
12109 size = MAX_PATH;
12110 lstrcpyA(val, "apple");
12111 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12112 MSIINSTALLCONTEXT_ALL,
12113 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12114 ok(r == ERROR_INVALID_PARAMETER,
12115 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12116 ok(!lstrcmpA(val, "apple"),
12117 "Expected val to be unchanged, got \"%s\"\n", val);
12118 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12119
12120 /* dwContext is invalid */
12121 size = MAX_PATH;
12122 lstrcpyA(val, "apple");
12123 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
12124 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12125 ok(r == ERROR_INVALID_PARAMETER,
12126 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12127 ok(!lstrcmpA(val, "apple"),
12128 "Expected val to be unchanged, got \"%s\"\n", val);
12129 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12130
12131 /* MSIINSTALLCONTEXT_USERMANAGED */
12132
12133 size = MAX_PATH;
12134 lstrcpyA(val, "apple");
12135 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12136 MSIINSTALLCONTEXT_USERMANAGED,
12137 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12138 ok(r == ERROR_UNKNOWN_PRODUCT,
12139 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12140 ok(!lstrcmpA(val, "apple"),
12141 "Expected val to be unchanged, got \"%s\"\n", val);
12142 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12143
12144 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12145 lstrcatA(keypath, usersid);
12146 lstrcatA(keypath, "\\Products\\");
12147 lstrcatA(keypath, prod_squashed);
12148
12149 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12150 if (res == ERROR_ACCESS_DENIED)
12151 {
12152 skip("Not enough rights to perform tests\n");
12153 LocalFree(usersid);
12154 return;
12155 }
12156 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12157
12158 /* local UserData product key exists */
12159 size = MAX_PATH;
12160 lstrcpyA(val, "apple");
12161 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12162 MSIINSTALLCONTEXT_USERMANAGED,
12163 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12164 ok(r == ERROR_UNKNOWN_PRODUCT,
12165 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12166 ok(!lstrcmpA(val, "apple"),
12167 "Expected val to be unchanged, got \"%s\"\n", val);
12168 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12169
12170 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12171 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12172
12173 /* InstallProperties key exists */
12174 size = MAX_PATH;
12175 lstrcpyA(val, "apple");
12176 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12177 MSIINSTALLCONTEXT_USERMANAGED,
12178 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12179 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12180 ok(!lstrcmpA(val, "apple"),
12181 "Expected val to be unchanged, got \"%s\"\n", val);
12182 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12183
12184 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12185 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12186
12187 /* Patches key exists */
12188 size = MAX_PATH;
12189 lstrcpyA(val, "apple");
12190 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12191 MSIINSTALLCONTEXT_USERMANAGED,
12192 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12193 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCHA, got %d\n", r);
12194 ok(!lstrcmpA(val, "apple"),
12195 "Expected val to be unchanged, got \"%s\"\n", val);
12196 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12197
12198 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12199 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12200
12201 /* Patches key exists */
12202 size = MAX_PATH;
12203 lstrcpyA(val, "apple");
12204 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12205 MSIINSTALLCONTEXT_USERMANAGED,
12206 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12207 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12208 ok(!lstrcmpA(val, "apple"),
12209 "Expected val to be unchanged, got \"%s\"\n", val);
12210 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12211
12212 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
12213 lstrcatA(keypath, usersid);
12214 lstrcatA(keypath, "\\Installer\\Products\\");
12215 lstrcatA(keypath, prod_squashed);
12216
12217 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
12218 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12219
12220 /* managed product key exists */
12221 size = MAX_PATH;
12222 lstrcpyA(val, "apple");
12223 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12224 MSIINSTALLCONTEXT_USERMANAGED,
12225 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12226 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12227 ok(!lstrcmpA(val, "apple"),
12228 "Expected val to be unchanged, got \"%s\"\n", val);
12229 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12230
12231 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
12232 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12233
12234 /* Patches key exists */
12235 size = MAX_PATH;
12236 lstrcpyA(val, "apple");
12237 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12238 MSIINSTALLCONTEXT_USERMANAGED,
12239 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12240 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12241 ok(!lstrcmpA(val, "apple"),
12242 "Expected val to be unchanged, got \"%s\"\n", val);
12243 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12244
12245 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12246 (const BYTE *)"transforms", 11);
12247 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12248
12249 /* specific patch value exists */
12250 size = MAX_PATH;
12251 lstrcpyA(val, "apple");
12252 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12253 MSIINSTALLCONTEXT_USERMANAGED,
12254 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12255 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12256 ok(!lstrcmpA(val, "apple"),
12257 "Expected val to be unchanged, got \"%s\"\n", val);
12258 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12259
12260 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12261 lstrcatA(keypath, usersid);
12262 lstrcatA(keypath, "\\Patches\\");
12263 lstrcatA(keypath, patch_squashed);
12264
12265 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12266 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12267
12268 /* UserData Patches key exists */
12269 size = MAX_PATH;
12270 lstrcpyA(val, "apple");
12271 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12272 MSIINSTALLCONTEXT_USERMANAGED,
12273 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12274 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12275 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12276 ok(size == 0, "Expected 0, got %d\n", size);
12277
12278 res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
12279 (const BYTE *)"pack", 5);
12280 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12281
12282 /* ManagedLocalPatch value exists */
12283 size = MAX_PATH;
12284 lstrcpyA(val, "apple");
12285 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12286 MSIINSTALLCONTEXT_USERMANAGED,
12287 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12289 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12290 ok(size == 4, "Expected 4, got %d\n", size);
12291
12292 size = MAX_PATH;
12293 lstrcpyA(val, "apple");
12294 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12295 MSIINSTALLCONTEXT_USERMANAGED,
12296 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12297 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12298 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12299 ok(size == 10, "Expected 10, got %d\n", size);
12300
12301 res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
12302 (const BYTE *)"mydate", 7);
12303 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12304
12305 /* Installed value exists */
12306 size = MAX_PATH;
12307 lstrcpyA(val, "apple");
12308 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12309 MSIINSTALLCONTEXT_USERMANAGED,
12310 INSTALLPROPERTY_INSTALLDATEA, val, &size);
12311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12312 ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
12313 ok(size == 6, "Expected 6, got %d\n", size);
12314
12315 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
12316 (const BYTE *)"yes", 4);
12317 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12318
12319 /* Uninstallable value exists */
12320 size = MAX_PATH;
12321 lstrcpyA(val, "apple");
12322 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12323 MSIINSTALLCONTEXT_USERMANAGED,
12324 INSTALLPROPERTY_UNINSTALLABLEA, val, &size);
12325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12326 ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
12327 ok(size == 3, "Expected 3, got %d\n", size);
12328
12329 res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
12330 (const BYTE *)"good", 5);
12331 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12332
12333 /* State value exists */
12334 size = MAX_PATH;
12335 lstrcpyA(val, "apple");
12336 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12337 MSIINSTALLCONTEXT_USERMANAGED,
12338 INSTALLPROPERTY_PATCHSTATEA, val, &size);
12339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12340 ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
12341 ok(size == 4, "Expected 4, got %d\n", size);
12342
12343 size = 1;
12344 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
12345 (const BYTE *)&size, sizeof(DWORD));
12346 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12347
12348 /* State value exists */
12349 size = MAX_PATH;
12350 lstrcpyA(val, "apple");
12351 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12352 MSIINSTALLCONTEXT_USERMANAGED,
12353 INSTALLPROPERTY_PATCHSTATEA, val, &size);
12354 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12355 todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
12356 ok(size == 1, "Expected 1, got %d\n", size);
12357
12358 res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
12359 (const BYTE *)"display", 8);
12360 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12361
12362 /* DisplayName value exists */
12363 size = MAX_PATH;
12364 lstrcpyA(val, "apple");
12365 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12366 MSIINSTALLCONTEXT_USERMANAGED,
12367 INSTALLPROPERTY_DISPLAYNAMEA, val, &size);
12368 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12369 ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
12370 ok(size == 7, "Expected 7, got %d\n", size);
12371
12372 res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
12373 (const BYTE *)"moreinfo", 9);
12374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12375
12376 /* MoreInfoURL value exists */
12377 size = MAX_PATH;
12378 lstrcpyA(val, "apple");
12379 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12380 MSIINSTALLCONTEXT_USERMANAGED,
12381 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12383 ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
12384 ok(size == 8, "Expected 8, got %d\n", size);
12385
12386 /* szProperty is invalid */
12387 size = MAX_PATH;
12388 lstrcpyA(val, "apple");
12389 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12390 MSIINSTALLCONTEXT_USERMANAGED,
12391 "IDontExist", val, &size);
12392 ok(r == ERROR_UNKNOWN_PROPERTY,
12393 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
12394 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12395 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12396
12397 /* lpValue is NULL, while pcchValue is non-NULL */
12398 size = MAX_PATH;
12399 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12400 MSIINSTALLCONTEXT_USERMANAGED,
12401 INSTALLPROPERTY_MOREINFOURLA, NULL, &size);
12402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12403 ok(size == 16, "Expected 16, got %d\n", size);
12404
12405 /* pcchValue is NULL, while lpValue is non-NULL */
12406 lstrcpyA(val, "apple");
12407 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12408 MSIINSTALLCONTEXT_USERMANAGED,
12409 INSTALLPROPERTY_MOREINFOURLA, val, NULL);
12410 ok(r == ERROR_INVALID_PARAMETER,
12411 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12412 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12413
12414 /* both lpValue and pcchValue are NULL */
12415 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12416 MSIINSTALLCONTEXT_USERMANAGED,
12417 INSTALLPROPERTY_MOREINFOURLA, NULL, NULL);
12418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12419
12420 /* pcchValue doesn't have enough room for NULL terminator */
12421 size = 8;
12422 lstrcpyA(val, "apple");
12423 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12424 MSIINSTALLCONTEXT_USERMANAGED,
12425 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12426 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
12427 ok(!lstrcmpA(val, "moreinf"),
12428 "Expected \"moreinf\", got \"%s\"\n", val);
12429 ok(size == 16, "Expected 16, got %d\n", size);
12430
12431 /* pcchValue has exactly enough room for NULL terminator */
12432 size = 9;
12433 lstrcpyA(val, "apple");
12434 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12435 MSIINSTALLCONTEXT_USERMANAGED,
12436 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12437 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12438 ok(!lstrcmpA(val, "moreinfo"),
12439 "Expected \"moreinfo\", got \"%s\"\n", val);
12440 ok(size == 8, "Expected 8, got %d\n", size);
12441
12442 /* pcchValue is too small, lpValue is NULL */
12443 size = 0;
12444 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12445 MSIINSTALLCONTEXT_USERMANAGED,
12446 INSTALLPROPERTY_MOREINFOURLA, NULL, &size);
12447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12448 ok(size == 16, "Expected 16, got %d\n", size);
12449
12450 RegDeleteValueA(prodpatches, patch_squashed);
12451 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12452 RegCloseKey(prodpatches);
12453 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12454 RegCloseKey(prodkey);
12455
12456 /* UserData is sufficient for all properties
12457 * except INSTALLPROPERTY_TRANSFORMS
12458 */
12459 size = MAX_PATH;
12460 lstrcpyA(val, "apple");
12461 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12462 MSIINSTALLCONTEXT_USERMANAGED,
12463 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12465 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12466 ok(size == 4, "Expected 4, got %d\n", size);
12467
12468 /* UserData is sufficient for all properties
12469 * except INSTALLPROPERTY_TRANSFORMS
12470 */
12471 size = MAX_PATH;
12472 lstrcpyA(val, "apple");
12473 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12474 MSIINSTALLCONTEXT_USERMANAGED,
12475 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12476 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12477 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12478 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12479
12480 RegDeleteValueA(hpatch, "MoreInfoURL");
12481 RegDeleteValueA(hpatch, "Display");
12482 RegDeleteValueA(hpatch, "State");
12483 RegDeleteValueA(hpatch, "Uninstallable");
12484 RegDeleteValueA(hpatch, "Installed");
12485 RegDeleteValueA(udpatch, "ManagedLocalPackage");
12486 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12487 RegCloseKey(udpatch);
12488 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12489 RegCloseKey(hpatch);
12490 delete_key(patches, "", access & KEY_WOW64_64KEY);
12491 RegCloseKey(patches);
12492 delete_key(props, "", access & KEY_WOW64_64KEY);
12493 RegCloseKey(props);
12494 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12495 RegCloseKey(udprod);
12496
12497 /* MSIINSTALLCONTEXT_USERUNMANAGED */
12498
12499 size = MAX_PATH;
12500 lstrcpyA(val, "apple");
12501 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12502 MSIINSTALLCONTEXT_USERUNMANAGED,
12503 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12504 ok(r == ERROR_UNKNOWN_PRODUCT,
12505 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12506 ok(!lstrcmpA(val, "apple"),
12507 "Expected val to be unchanged, got \"%s\"\n", val);
12508 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12509
12510 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12511 lstrcatA(keypath, usersid);
12512 lstrcatA(keypath, "\\Products\\");
12513 lstrcatA(keypath, prod_squashed);
12514
12515 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12516 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12517
12518 /* local UserData product key exists */
12519 size = MAX_PATH;
12520 lstrcpyA(val, "apple");
12521 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12522 MSIINSTALLCONTEXT_USERUNMANAGED,
12523 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12524 ok(r == ERROR_UNKNOWN_PRODUCT,
12525 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12526 ok(!lstrcmpA(val, "apple"),
12527 "Expected val to be unchanged, got \"%s\"\n", val);
12528 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12529
12530 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12531 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12532
12533 /* InstallProperties key exists */
12534 size = MAX_PATH;
12535 lstrcpyA(val, "apple");
12536 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12537 MSIINSTALLCONTEXT_USERUNMANAGED,
12538 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12539 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12540 ok(!lstrcmpA(val, "apple"),
12541 "Expected val to be unchanged, got \"%s\"\n", val);
12542 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12543
12544 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12545 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12546
12547 /* Patches key exists */
12548 size = MAX_PATH;
12549 lstrcpyA(val, "apple");
12550 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12551 MSIINSTALLCONTEXT_USERUNMANAGED,
12552 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12553 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12554 ok(!lstrcmpA(val, "apple"),
12555 "Expected val to be unchanged, got \"%s\"\n", val);
12556 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12557
12558 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12560
12561 /* Patches key exists */
12562 size = MAX_PATH;
12563 lstrcpyA(val, "apple");
12564 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12565 MSIINSTALLCONTEXT_USERUNMANAGED,
12566 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12567 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12568 ok(!lstrcmpA(val, "apple"),
12569 "Expected val to be unchanged, got \"%s\"\n", val);
12570 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12571
12572 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
12573 lstrcatA(keypath, prod_squashed);
12574
12575 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
12576 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12577
12578 /* current user product key exists */
12579 size = MAX_PATH;
12580 lstrcpyA(val, "apple");
12581 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12582 MSIINSTALLCONTEXT_USERUNMANAGED,
12583 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12584 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12585 ok(!lstrcmpA(val, "apple"),
12586 "Expected val to be unchanged, got \"%s\"\n", val);
12587 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12588
12589 res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
12590 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12591
12592 /* Patches key exists */
12593 size = MAX_PATH;
12594 lstrcpyA(val, "apple");
12595 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12596 MSIINSTALLCONTEXT_USERUNMANAGED,
12597 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12598 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12599 ok(!lstrcmpA(val, "apple"),
12600 "Expected val to be unchanged, got \"%s\"\n", val);
12601 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12602
12603 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12604 (const BYTE *)"transforms", 11);
12605 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12606
12607 /* specific patch value exists */
12608 size = MAX_PATH;
12609 lstrcpyA(val, "apple");
12610 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12611 MSIINSTALLCONTEXT_USERUNMANAGED,
12612 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12613 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12614 ok(!lstrcmpA(val, "apple"),
12615 "Expected val to be unchanged, got \"%s\"\n", val);
12616 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12617
12618 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12619 lstrcatA(keypath, usersid);
12620 lstrcatA(keypath, "\\Patches\\");
12621 lstrcatA(keypath, patch_squashed);
12622
12623 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12624 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12625
12626 /* UserData Patches key exists */
12627 size = MAX_PATH;
12628 lstrcpyA(val, "apple");
12629 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12630 MSIINSTALLCONTEXT_USERUNMANAGED,
12631 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12633 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12634 ok(size == 0, "Expected 0, got %d\n", size);
12635
12636 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12637 (const BYTE *)"pack", 5);
12638 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12639
12640 /* LocalPatch value exists */
12641 size = MAX_PATH;
12642 lstrcpyA(val, "apple");
12643 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12644 MSIINSTALLCONTEXT_USERUNMANAGED,
12645 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12646 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12647 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12648 ok(size == 4, "Expected 4, got %d\n", size);
12649
12650 size = MAX_PATH;
12651 lstrcpyA(val, "apple");
12652 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12653 MSIINSTALLCONTEXT_USERUNMANAGED,
12654 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12656 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12657 ok(size == 10, "Expected 10, got %d\n", size);
12658
12659 RegDeleteValueA(prodpatches, patch_squashed);
12660 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12661 RegCloseKey(prodpatches);
12662 RegDeleteKeyA(prodkey, "");
12663 RegCloseKey(prodkey);
12664
12665 /* UserData is sufficient for all properties
12666 * except INSTALLPROPERTY_TRANSFORMS
12667 */
12668 size = MAX_PATH;
12669 lstrcpyA(val, "apple");
12670 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12671 MSIINSTALLCONTEXT_USERUNMANAGED,
12672 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12674 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12675 ok(size == 4, "Expected 4, got %d\n", size);
12676
12677 /* UserData is sufficient for all properties
12678 * except INSTALLPROPERTY_TRANSFORMS
12679 */
12680 size = MAX_PATH;
12681 lstrcpyA(val, "apple");
12682 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12683 MSIINSTALLCONTEXT_USERUNMANAGED,
12684 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12685 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12686 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12687 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12688
12689 RegDeleteValueA(udpatch, "LocalPackage");
12690 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12691 RegCloseKey(udpatch);
12692 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12693 RegCloseKey(hpatch);
12694 delete_key(patches, "", access & KEY_WOW64_64KEY);
12695 RegCloseKey(patches);
12696 delete_key(props, "", access & KEY_WOW64_64KEY);
12697 RegCloseKey(props);
12698 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12699 RegCloseKey(udprod);
12700
12701 /* MSIINSTALLCONTEXT_MACHINE */
12702
12703 size = MAX_PATH;
12704 lstrcpyA(val, "apple");
12705 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12706 MSIINSTALLCONTEXT_MACHINE,
12707 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12708 ok(r == ERROR_UNKNOWN_PRODUCT,
12709 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12710 ok(!lstrcmpA(val, "apple"),
12711 "Expected val to be unchanged, got \"%s\"\n", val);
12712 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12713
12714 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12715 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
12716 lstrcatA(keypath, prod_squashed);
12717
12718 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12719 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12720
12721 /* local UserData product key exists */
12722 size = MAX_PATH;
12723 lstrcpyA(val, "apple");
12724 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12725 MSIINSTALLCONTEXT_MACHINE,
12726 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12727 ok(r == ERROR_UNKNOWN_PRODUCT,
12728 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12729 ok(!lstrcmpA(val, "apple"),
12730 "Expected val to be unchanged, got \"%s\"\n", val);
12731 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12732
12733 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12734 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12735
12736 /* InstallProperties key exists */
12737 size = MAX_PATH;
12738 lstrcpyA(val, "apple");
12739 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12740 MSIINSTALLCONTEXT_MACHINE,
12741 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12742 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12743 ok(!lstrcmpA(val, "apple"),
12744 "Expected val to be unchanged, got \"%s\"\n", val);
12745 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12746
12747 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12748 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12749
12750 /* Patches key exists */
12751 size = MAX_PATH;
12752 lstrcpyA(val, "apple");
12753 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12754 MSIINSTALLCONTEXT_MACHINE,
12755 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12756 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12757 ok(!lstrcmpA(val, "apple"),
12758 "Expected val to be unchanged, got \"%s\"\n", val);
12759 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12760
12761 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12762 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12763
12764 /* Patches key exists */
12765 size = MAX_PATH;
12766 lstrcpyA(val, "apple");
12767 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12768 MSIINSTALLCONTEXT_MACHINE,
12769 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12770 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12771 ok(!lstrcmpA(val, "apple"),
12772 "Expected val to be unchanged, got \"%s\"\n", val);
12773 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12774
12775 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
12776 lstrcatA(keypath, prod_squashed);
12777
12778 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
12779 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12780
12781 /* local product key exists */
12782 size = MAX_PATH;
12783 lstrcpyA(val, "apple");
12784 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12785 MSIINSTALLCONTEXT_MACHINE,
12786 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12787 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12788 ok(!lstrcmpA(val, "apple"),
12789 "Expected val to be unchanged, got \"%s\"\n", val);
12790 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12791
12792 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
12793 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12794
12795 /* Patches key exists */
12796 size = MAX_PATH;
12797 lstrcpyA(val, "apple");
12798 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12799 MSIINSTALLCONTEXT_MACHINE,
12800 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12801 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12802 ok(!lstrcmpA(val, "apple"),
12803 "Expected val to be unchanged, got \"%s\"\n", val);
12804 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12805
12806 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12807 (const BYTE *)"transforms", 11);
12808 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12809
12810 /* specific patch value exists */
12811 size = MAX_PATH;
12812 lstrcpyA(val, "apple");
12813 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12814 MSIINSTALLCONTEXT_MACHINE,
12815 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12816 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12817 ok(!lstrcmpA(val, "apple"),
12818 "Expected val to be unchanged, got \"%s\"\n", val);
12819 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12820
12821 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12822 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
12823 lstrcatA(keypath, patch_squashed);
12824
12825 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12826 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12827
12828 /* UserData Patches key exists */
12829 size = MAX_PATH;
12830 lstrcpyA(val, "apple");
12831 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12832 MSIINSTALLCONTEXT_MACHINE,
12833 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12834 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12835 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12836 ok(size == 0, "Expected 0, got %d\n", size);
12837
12838 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12839 (const BYTE *)"pack", 5);
12840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12841
12842 /* LocalPatch value exists */
12843 size = MAX_PATH;
12844 lstrcpyA(val, "apple");
12845 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12846 MSIINSTALLCONTEXT_MACHINE,
12847 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12849 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12850 ok(size == 4, "Expected 4, got %d\n", size);
12851
12852 size = MAX_PATH;
12853 lstrcpyA(val, "apple");
12854 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12855 MSIINSTALLCONTEXT_MACHINE,
12856 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12857 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12858 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12859 ok(size == 10, "Expected 10, got %d\n", size);
12860
12861 RegDeleteValueA(prodpatches, patch_squashed);
12862 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12863 RegCloseKey(prodpatches);
12864 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12865 RegCloseKey(prodkey);
12866
12867 /* UserData is sufficient for all properties
12868 * except INSTALLPROPERTY_TRANSFORMS
12869 */
12870 size = MAX_PATH;
12871 lstrcpyA(val, "apple");
12872 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12873 MSIINSTALLCONTEXT_MACHINE,
12874 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12875 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12876 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12877 ok(size == 4, "Expected 4, got %d\n", size);
12878
12879 /* UserData is sufficient for all properties
12880 * except INSTALLPROPERTY_TRANSFORMS
12881 */
12882 size = MAX_PATH;
12883 lstrcpyA(val, "apple");
12884 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12885 MSIINSTALLCONTEXT_MACHINE,
12886 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12887 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12888 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12889 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12890
12891 RegDeleteValueA(udpatch, "LocalPackage");
12892 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12893 RegCloseKey(udpatch);
12894 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12895 RegCloseKey(hpatch);
12896 delete_key(patches, "", access & KEY_WOW64_64KEY);
12897 RegCloseKey(patches);
12898 delete_key(props, "", access & KEY_WOW64_64KEY);
12899 RegCloseKey(props);
12900 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12901 RegCloseKey(udprod);
12902 LocalFree(usersid);
12903 }
12904
12905 static void test_MsiGetPatchInfo(void)
12906 {
12907 UINT r;
12908 char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
12909 char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
12910 WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
12911 HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
12912 HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
12913 DWORD size;
12914 LONG res;
12915 REGSAM access = KEY_ALL_ACCESS;
12916
12917 create_test_guid(patch_code, patch_squashed);
12918 create_test_guid(prod_code, prod_squashed);
12919 MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
12920
12921 if (is_wow64)
12922 access |= KEY_WOW64_64KEY;
12923
12924 r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
12925 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12926
12927 r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
12928 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12929
12930 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
12931 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
12932
12933 size = 0;
12934 r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
12935 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12936
12937 r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
12938 ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
12939
12940 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
12941 lstrcatA(keypath, prod_squashed);
12942
12943 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
12944 if (res == ERROR_ACCESS_DENIED)
12945 {
12946 skip("Not enough rights to perform tests\n");
12947 return;
12948 }
12949 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12950
12951 /* product key exists */
12952 size = MAX_PATH;
12953 lstrcpyA(val, "apple");
12954 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12955 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12956 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
12957 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12958
12959 res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
12960 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12961
12962 /* patches key exists */
12963 size = MAX_PATH;
12964 lstrcpyA(val, "apple");
12965 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12966 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12967 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12968 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12969
12970 res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
12971 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12972
12973 /* patch key exists */
12974 size = MAX_PATH;
12975 lstrcpyA(val, "apple");
12976 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12977 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12978 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12979 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12980
12981 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12982 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
12983 lstrcatA(keypath, prod_squashed);
12984
12985 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
12986 if (res == ERROR_ACCESS_DENIED)
12987 {
12988 skip("Not enough rights to perform tests\n");
12989 goto done;
12990 }
12991 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
12992
12993 /* UserData product key exists */
12994 size = MAX_PATH;
12995 lstrcpyA(val, "apple");
12996 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12997 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12998 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12999 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13000
13001 res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
13002 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13003
13004 /* InstallProperties key exists */
13005 size = MAX_PATH;
13006 lstrcpyA(val, "apple");
13007 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13008 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13009 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
13010 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13011
13012 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
13013 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13014
13015 /* UserData Patches key exists */
13016 size = MAX_PATH;
13017 lstrcpyA(val, "apple");
13018 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13019 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13020 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
13021 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13022
13023 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
13024 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13025
13026 res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
13027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13028
13029 /* UserData product patch key exists */
13030 size = MAX_PATH;
13031 lstrcpyA(val, "apple");
13032 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13033 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13034 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
13035 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13036
13037 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
13038 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
13039 lstrcatA(keypath, patch_squashed);
13040
13041 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
13042 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13043
13044 res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
13045 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13046
13047 /* UserData Patch key exists */
13048 size = 0;
13049 lstrcpyA(val, "apple");
13050 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13051 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
13052 ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
13053 ok(size == 11, "expected 11 got %u\n", size);
13054
13055 size = MAX_PATH;
13056 lstrcpyA(val, "apple");
13057 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13058 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
13059 ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
13060 ok(size == 11, "expected 11 got %u\n", size);
13061
13062 size = 0;
13063 valW[0] = 0;
13064 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
13065 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
13066 ok(!valW[0], "expected 0 got %u\n", valW[0]);
13067 ok(size == 11, "expected 11 got %u\n", size);
13068
13069 size = MAX_PATH;
13070 valW[0] = 0;
13071 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
13072 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
13073 ok(valW[0], "expected > 0 got %u\n", valW[0]);
13074 ok(size == 11, "expected 11 got %u\n", size);
13075
13076 delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
13077 RegCloseKey(hkey_udproductpatch);
13078 delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
13079 RegCloseKey(hkey_udproductpatches);
13080 delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
13081 RegCloseKey(hkey_udpatch);
13082 delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
13083 RegCloseKey(hkey_udpatches);
13084 delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
13085 RegCloseKey(hkey_udprops);
13086 delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
13087 RegCloseKey(hkey_udproduct);
13088
13089 done:
13090 delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
13091 RegCloseKey(hkey_patches);
13092 delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
13093 RegCloseKey(hkey_product);
13094 delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
13095 RegCloseKey(hkey_patch);
13096 }
13097
13098 static void test_MsiEnumProducts(void)
13099 {
13100 UINT r;
13101 BOOL found1, found2, found3;
13102 DWORD index;
13103 char product1[39], product2[39], product3[39], guid[39];
13104 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
13105 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
13106 char *usersid;
13107 HKEY key1, key2, key3;
13108 REGSAM access = KEY_ALL_ACCESS;
13109
13110 create_test_guid(product1, product_squashed1);
13111 create_test_guid(product2, product_squashed2);
13112 create_test_guid(product3, product_squashed3);
13113 usersid = get_user_sid();
13114
13115 if (is_wow64)
13116 access |= KEY_WOW64_64KEY;
13117
13118 strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
13119 strcat(keypath2, usersid);
13120 strcat(keypath2, "\\Installer\\Products\\");
13121 strcat(keypath2, product_squashed2);
13122
13123 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
13124 if (r == ERROR_ACCESS_DENIED)
13125 {
13126 skip("Not enough rights to perform tests\n");
13127 LocalFree(usersid);
13128 return;
13129 }
13130 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13131
13132 strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
13133 strcat(keypath1, product_squashed1);
13134
13135 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
13136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13137
13138 strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
13139 strcat(keypath3, product_squashed3);
13140
13141 r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
13142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13143
13144 index = 0;
13145 r = MsiEnumProductsA(index, guid);
13146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13147
13148 r = MsiEnumProductsA(index, NULL);
13149 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
13150
13151 index = 2;
13152 r = MsiEnumProductsA(index, guid);
13153 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
13154
13155 index = 0;
13156 r = MsiEnumProductsA(index, guid);
13157 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13158
13159 found1 = found2 = found3 = FALSE;
13160 while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
13161 {
13162 if (!strcmp(product1, guid)) found1 = TRUE;
13163 if (!strcmp(product2, guid)) found2 = TRUE;
13164 if (!strcmp(product3, guid)) found3 = TRUE;
13165 index++;
13166 }
13167 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
13168 ok(found1, "product1 not found\n");
13169 ok(found2, "product2 not found\n");
13170 ok(found3, "product3 not found\n");
13171
13172 delete_key(key1, "", access & KEY_WOW64_64KEY);
13173 delete_key(key2, "", access & KEY_WOW64_64KEY);
13174 RegDeleteKeyA(key3, "");
13175 RegCloseKey(key1);
13176 RegCloseKey(key2);
13177 RegCloseKey(key3);
13178 LocalFree(usersid);
13179 }
13180
13181 static void test_MsiGetFileSignatureInformation(void)
13182 {
13183 HRESULT hr;
13184 const CERT_CONTEXT *cert;
13185 DWORD len;
13186
13187 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
13188 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13189
13190 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
13191 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13192
13193 hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
13194 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13195
13196 hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
13197 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13198
13199 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
13200 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13201
13202 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
13203 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13204
13205 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
13206 todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
13207
13208 create_file( "signature.bin", "signature", sizeof("signature") );
13209
13210 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
13211 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13212
13213 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
13214 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13215
13216 cert = (const CERT_CONTEXT *)0xdeadbeef;
13217 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
13218 todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
13219 ok(cert == NULL, "got %p\n", cert);
13220
13221 DeleteFileA( "signature.bin" );
13222 }
13223
13224 static void test_MsiEnumProductsEx(void)
13225 {
13226 UINT r;
13227 DWORD len, index;
13228 MSIINSTALLCONTEXT context;
13229 char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
13230 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
13231 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
13232 HKEY key1 = NULL, key2 = NULL, key3 = NULL;
13233 REGSAM access = KEY_ALL_ACCESS;
13234 char *usersid = get_user_sid();
13235
13236 if (!pMsiEnumProductsExA)
13237 {
13238 win_skip("MsiEnumProductsExA not implemented\n");
13239 return;
13240 }
13241
13242 create_test_guid( product0, NULL );
13243 create_test_guid( product1, product_squashed1 );
13244 create_test_guid( product2, product_squashed2 );
13245 create_test_guid( product3, product_squashed3 );
13246
13247 if (is_wow64) access |= KEY_WOW64_64KEY;
13248
13249 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
13250 strcat( keypath2, usersid );
13251 strcat( keypath2, "\\Installer\\Products\\" );
13252 strcat( keypath2, product_squashed2 );
13253
13254 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13255 if (r == ERROR_ACCESS_DENIED)
13256 {
13257 skip( "insufficient rights\n" );
13258 goto done;
13259 }
13260 ok( r == ERROR_SUCCESS, "got %u\n", r );
13261
13262 strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
13263 strcat( keypath1, product_squashed1 );
13264
13265 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13266 ok( r == ERROR_SUCCESS, "got %u\n", r );
13267
13268 strcpy( keypath3, usersid );
13269 strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
13270 strcat( keypath3, product_squashed3 );
13271
13272 r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
13273 ok( r == ERROR_SUCCESS, "got %u\n", r );
13274
13275 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
13276 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13277
13278 len = sizeof(sid);
13279 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
13280 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13281 ok( len == sizeof(sid), "got %u\n", len );
13282
13283 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
13284 ok( r == ERROR_SUCCESS, "got %u\n", r );
13285
13286 sid[0] = 0;
13287 len = sizeof(sid);
13288 r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
13289 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
13290 ok( len == sizeof(sid), "got %u\n", len );
13291 ok( !sid[0], "got %s\n", sid );
13292
13293 sid[0] = 0;
13294 len = sizeof(sid);
13295 r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
13296 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
13297 ok( len == sizeof(sid), "got %u\n", len );
13298 ok( !sid[0], "got %s\n", sid );
13299
13300 sid[0] = 0;
13301 len = 0;
13302 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
13303 ok( r == ERROR_MORE_DATA, "got %u\n", r );
13304 ok( len, "length unchanged\n" );
13305 ok( !sid[0], "got %s\n", sid );
13306
13307 guid[0] = 0;
13308 context = 0xdeadbeef;
13309 sid[0] = 0;
13310 len = sizeof(sid);
13311 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13312 ok( r == ERROR_SUCCESS, "got %u\n", r );
13313 ok( guid[0], "empty guid\n" );
13314 ok( context != 0xdeadbeef, "context unchanged\n" );
13315 ok( !len, "got %u\n", len );
13316 ok( !sid[0], "got %s\n", sid );
13317
13318 guid[0] = 0;
13319 context = 0xdeadbeef;
13320 sid[0] = 0;
13321 len = sizeof(sid);
13322 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13323 ok( r == ERROR_SUCCESS, "got %u\n", r );
13324 ok( guid[0], "empty guid\n" );
13325 ok( context != 0xdeadbeef, "context unchanged\n" );
13326 ok( !len, "got %u\n", len );
13327 ok( !sid[0], "got %s\n", sid );
13328
13329 guid[0] = 0;
13330 context = 0xdeadbeef;
13331 sid[0] = 0;
13332 len = sizeof(sid);
13333 r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13334 if (r == ERROR_ACCESS_DENIED)
13335 {
13336 skip( "insufficient rights\n" );
13337 goto done;
13338 }
13339 ok( r == ERROR_SUCCESS, "got %u\n", r );
13340 ok( guid[0], "empty guid\n" );
13341 ok( context != 0xdeadbeef, "context unchanged\n" );
13342 ok( !len, "got %u\n", len );
13343 ok( !sid[0], "got %s\n", sid );
13344
13345 index = 0;
13346 guid[0] = 0;
13347 context = 0xdeadbeef;
13348 sid[0] = 0;
13349 len = sizeof(sid);
13350 while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13351 {
13352 if (!strcmp( product1, guid ))
13353 {
13354 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13355 ok( !sid[0], "got \"%s\"\n", sid );
13356 ok( !len, "unexpected length %u\n", len );
13357 }
13358 if (!strcmp( product2, guid ))
13359 {
13360 ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
13361 ok( sid[0], "empty sid\n" );
13362 ok( len == strlen(sid), "unexpected length %u\n", len );
13363 }
13364 if (!strcmp( product3, guid ))
13365 {
13366 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13367 ok( sid[0], "empty sid\n" );
13368 ok( len == strlen(sid), "unexpected length %u\n", len );
13369 }
13370 index++;
13371 guid[0] = 0;
13372 context = 0xdeadbeef;
13373 sid[0] = 0;
13374 len = sizeof(sid);
13375 }
13376
13377 done:
13378 delete_key( key1, "", access );
13379 delete_key( key2, "", access );
13380 delete_key( key3, "", access );
13381 RegCloseKey( key1 );
13382 RegCloseKey( key2 );
13383 RegCloseKey( key3 );
13384 LocalFree( usersid );
13385 }
13386
13387 static void test_MsiEnumComponents(void)
13388 {
13389 UINT r;
13390 BOOL found1, found2;
13391 DWORD index;
13392 char comp1[39], comp2[39], guid[39];
13393 char comp_squashed1[33], comp_squashed2[33];
13394 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13395 REGSAM access = KEY_ALL_ACCESS;
13396 char *usersid = get_user_sid();
13397 HKEY key1 = NULL, key2 = NULL;
13398
13399 create_test_guid( comp1, comp_squashed1 );
13400 create_test_guid( comp2, comp_squashed2 );
13401
13402 if (is_wow64) access |= KEY_WOW64_64KEY;
13403
13404 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13405 strcat( keypath1, "S-1-5-18\\Components\\" );
13406 strcat( keypath1, comp_squashed1 );
13407
13408 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13409 if (r == ERROR_ACCESS_DENIED)
13410 {
13411 skip( "insufficient rights\n" );
13412 goto done;
13413 }
13414 ok( r == ERROR_SUCCESS, "got %u\n", r );
13415
13416 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13417 strcat( keypath2, usersid );
13418 strcat( keypath2, "\\Components\\" );
13419 strcat( keypath2, comp_squashed2 );
13420
13421 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13422 if (r == ERROR_ACCESS_DENIED)
13423 {
13424 skip( "insufficient rights\n" );
13425 goto done;
13426 }
13427
13428 r = MsiEnumComponentsA( 0, NULL );
13429 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13430
13431 index = 0;
13432 guid[0] = 0;
13433 found1 = found2 = FALSE;
13434 while (!MsiEnumComponentsA( index, guid ))
13435 {
13436 if (!strcmp( guid, comp1 )) found1 = TRUE;
13437 if (!strcmp( guid, comp2 )) found2 = TRUE;
13438 ok( guid[0], "empty guid\n" );
13439 guid[0] = 0;
13440 index++;
13441 }
13442 ok( found1, "comp1 not found\n" );
13443 ok( found2, "comp2 not found\n" );
13444
13445 done:
13446 delete_key( key1, "", access );
13447 delete_key( key2, "", access );
13448 RegCloseKey( key1 );
13449 RegCloseKey( key2 );
13450 LocalFree( usersid );
13451 }
13452
13453 static void test_MsiEnumComponentsEx(void)
13454 {
13455 UINT r;
13456 BOOL found1, found2;
13457 DWORD len, index;
13458 MSIINSTALLCONTEXT context;
13459 char comp1[39], comp2[39], guid[39], sid[128];
13460 char comp_squashed1[33], comp_squashed2[33];
13461 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13462 HKEY key1 = NULL, key2 = NULL;
13463 REGSAM access = KEY_ALL_ACCESS;
13464 char *usersid = get_user_sid();
13465
13466 if (!pMsiEnumComponentsExA)
13467 {
13468 win_skip( "MsiEnumComponentsExA not implemented\n" );
13469 return;
13470 }
13471 create_test_guid( comp1, comp_squashed1 );
13472 create_test_guid( comp2, comp_squashed2 );
13473
13474 if (is_wow64) access |= KEY_WOW64_64KEY;
13475
13476 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13477 strcat( keypath1, "S-1-5-18\\Components\\" );
13478 strcat( keypath1, comp_squashed1 );
13479
13480 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13481 if (r == ERROR_ACCESS_DENIED)
13482 {
13483 skip( "insufficient rights\n" );
13484 goto done;
13485 }
13486 ok( r == ERROR_SUCCESS, "got %u\n", r );
13487
13488 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13489 strcat( keypath2, usersid );
13490 strcat( keypath2, "\\Components\\" );
13491 strcat( keypath2, comp_squashed2 );
13492
13493 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13494 if (r == ERROR_ACCESS_DENIED)
13495 {
13496 skip( "insufficient rights\n" );
13497 goto done;
13498 }
13499 ok( r == ERROR_SUCCESS, "got %u\n", r );
13500 r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
13501 sizeof("c:\\doesnotexist"));
13502 ok( r == ERROR_SUCCESS, "got %u\n", r );
13503
13504 index = 0;
13505 guid[0] = 0;
13506 context = 0xdeadbeef;
13507 sid[0] = 0;
13508 len = sizeof(sid);
13509 found1 = found2 = FALSE;
13510 while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13511 {
13512 if (!strcmp( comp1, guid ))
13513 {
13514 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13515 ok( !sid[0], "got \"%s\"\n", sid );
13516 ok( !len, "unexpected length %u\n", len );
13517 found1 = TRUE;
13518 }
13519 if (!strcmp( comp2, guid ))
13520 {
13521 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13522 ok( sid[0], "empty sid\n" );
13523 ok( len == strlen(sid), "unexpected length %u\n", len );
13524 found2 = TRUE;
13525 }
13526 index++;
13527 guid[0] = 0;
13528 context = 0xdeadbeef;
13529 sid[0] = 0;
13530 len = sizeof(sid);
13531 }
13532 ok( found1, "comp1 not found\n" );
13533 ok( found2, "comp2 not found\n" );
13534
13535 r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
13536 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13537
13538 r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
13539 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13540
13541 done:
13542 RegDeleteValueA( key2, comp_squashed2 );
13543 delete_key( key1, "", access );
13544 delete_key( key2, "", access );
13545 RegCloseKey( key1 );
13546 RegCloseKey( key2 );
13547 LocalFree( usersid );
13548 }
13549
13550 static void test_MsiConfigureProductEx(void)
13551 {
13552 UINT r;
13553 LONG res;
13554 DWORD type, size;
13555 HKEY props, source;
13556 CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
13557 REGSAM access = KEY_ALL_ACCESS;
13558
13559 if (is_process_limited())
13560 {
13561 skip("process is limited\n");
13562 return;
13563 }
13564
13565 CreateDirectoryA("msitest", NULL);
13566 create_file("msitest\\hydrogen", "hydrogen", 500);
13567 create_file("msitest\\helium", "helium", 500);
13568 create_file("msitest\\lithium", "lithium", 500);
13569
13570 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13571
13572 if (is_wow64)
13573 access |= KEY_WOW64_64KEY;
13574
13575 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13576
13577 /* NULL szProduct */
13578 r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
13579 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13580 ok(r == ERROR_INVALID_PARAMETER,
13581 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13582
13583 /* empty szProduct */
13584 r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
13585 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13586 ok(r == ERROR_INVALID_PARAMETER,
13587 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13588
13589 /* garbage szProduct */
13590 r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
13591 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13592 ok(r == ERROR_INVALID_PARAMETER,
13593 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13594
13595 /* guid without brackets */
13596 r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
13597 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13598 "PROPVAR=42");
13599 ok(r == ERROR_INVALID_PARAMETER,
13600 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13601
13602 /* guid with brackets */
13603 r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
13604 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13605 "PROPVAR=42");
13606 ok(r == ERROR_UNKNOWN_PRODUCT,
13607 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13608
13609 /* same length as guid, but random */
13610 r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
13611 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13612 "PROPVAR=42");
13613 ok(r == ERROR_UNKNOWN_PRODUCT,
13614 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13615
13616 /* product not installed yet */
13617 r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
13618 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13619 "PROPVAR=42");
13620 ok(r == ERROR_UNKNOWN_PRODUCT,
13621 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13622
13623 /* install the product, per-user unmanaged */
13624 r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
13625 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13626 {
13627 skip("Not enough rights to perform tests\n");
13628 goto error;
13629 }
13630 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13631 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13632 ok(pf_exists("msitest\\helium"), "File not installed\n");
13633 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13634 ok(pf_exists("msitest"), "File not installed\n");
13635
13636 /* product is installed per-user managed, remove it */
13637 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13638 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13639 "PROPVAR=42");
13640 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13641 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13642 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13643 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13644 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13645
13646 /* product has been removed */
13647 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13648 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13649 "PROPVAR=42");
13650 ok(r == ERROR_UNKNOWN_PRODUCT,
13651 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13652
13653 /* install the product, machine */
13654 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13656 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13657 ok(pf_exists("msitest\\helium"), "File not installed\n");
13658 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13659 ok(pf_exists("msitest"), "File not installed\n");
13660
13661 /* product is installed machine, remove it */
13662 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13663 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13664 "PROPVAR=42");
13665 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13666 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13667 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13668 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13669 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13670
13671 /* product has been removed */
13672 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13673 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13674 "PROPVAR=42");
13675 ok(r == ERROR_UNKNOWN_PRODUCT,
13676 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13677
13678 /* install the product, machine */
13679 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13680 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13681 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13682 ok(pf_exists("msitest\\helium"), "File not installed\n");
13683 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13684 ok(pf_exists("msitest"), "File not installed\n");
13685
13686 DeleteFileA(msifile);
13687
13688 /* msifile is removed */
13689 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13690 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13691 "PROPVAR=42");
13692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13693 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13694 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13695 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13696 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13697
13698 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13699
13700 /* install the product, machine */
13701 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13703 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13704 ok(pf_exists("msitest\\helium"), "File not installed\n");
13705 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13706 ok(pf_exists("msitest"), "File not installed\n");
13707
13708 DeleteFileA(msifile);
13709
13710 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13711 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13712 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13713
13714 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
13715 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13716
13717 type = REG_SZ;
13718 size = MAX_PATH;
13719 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13720 (LPBYTE)localpackage, &size);
13721 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13722
13723 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13724 (const BYTE *)"C:\\idontexist.msi", 18);
13725 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13726
13727 /* LocalPackage is used to find the cached msi package */
13728 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13729 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13730 "PROPVAR=42");
13731 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
13732 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13733 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13734 ok(pf_exists("msitest\\helium"), "File not installed\n");
13735 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13736 ok(pf_exists("msitest"), "File not installed\n");
13737
13738 RegCloseKey(props);
13739 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13740
13741 /* LastUsedSource can be used as a last resort */
13742 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13743 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13744 "PROPVAR=42");
13745 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13746 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13747 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13748 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13749 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13750 DeleteFileA( localpackage );
13751
13752 /* install the product, machine */
13753 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13755 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13756 ok(pf_exists("msitest\\helium"), "File not installed\n");
13757 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13758 ok(pf_exists("msitest"), "File not installed\n");
13759
13760 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13761 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13762 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13763
13764 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
13765 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13766
13767 type = REG_SZ;
13768 size = MAX_PATH;
13769 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13770 (LPBYTE)localpackage, &size);
13771 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13772
13773 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13774 (const BYTE *)"C:\\idontexist.msi", 18);
13775 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13776
13777 lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
13778 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\SourceList");
13779
13780 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source);
13781 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13782
13783 type = REG_SZ;
13784 size = MAX_PATH;
13785 res = RegQueryValueExA(source, "PackageName", NULL, &type,
13786 (LPBYTE)packagename, &size);
13787 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13788
13789 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13790 (const BYTE *)"idontexist.msi", 15);
13791 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13792
13793 /* SourceList is altered */
13794 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13795 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13796 "PROPVAR=42");
13797 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
13798 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13799 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13800 ok(pf_exists("msitest\\helium"), "File not installed\n");
13801 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13802 ok(pf_exists("msitest"), "File not installed\n");
13803
13804 /* restore PackageName */
13805 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13806 (const BYTE *)packagename, lstrlenA(packagename) + 1);
13807 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13808
13809 /* restore LocalPackage */
13810 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13811 (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
13812 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13813
13814 /* finally remove the product */
13815 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13816 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13817 "PROPVAR=42");
13818 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13819 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13820 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13821 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13822 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13823
13824 RegCloseKey(source);
13825 RegCloseKey(props);
13826
13827 error:
13828 DeleteFileA("msitest\\hydrogen");
13829 DeleteFileA("msitest\\helium");
13830 DeleteFileA("msitest\\lithium");
13831 RemoveDirectoryA("msitest");
13832 DeleteFileA(msifile);
13833 }
13834
13835 static void test_MsiSetFeatureAttributes(void)
13836 {
13837 UINT r;
13838 DWORD attrs;
13839 char path[MAX_PATH];
13840 MSIHANDLE package;
13841
13842 if (is_process_limited())
13843 {
13844 skip("process is limited\n");
13845 return;
13846 }
13847 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
13848
13849 strcpy( path, CURR_DIR );
13850 strcat( path, "\\" );
13851 strcat( path, msifile );
13852
13853 r = MsiOpenPackageA( path, &package );
13854 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13855 {
13856 skip("Not enough rights to perform tests\n");
13857 DeleteFileA( msifile );
13858 return;
13859 }
13860 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13861
13862 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13863 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r);
13864
13865 r = MsiDoActionA( package, "CostInitialize" );
13866 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13867
13868 r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13869 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
13870
13871 r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13872 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13873
13874 r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13875 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13876
13877 r = MsiSetFeatureAttributesA( package, "One", 0 );
13878 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13879
13880 attrs = 0xdeadbeef;
13881 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13882 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13883 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
13884 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
13885
13886 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13887 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13888
13889 attrs = 0;
13890 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13891 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13892 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
13893 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
13894
13895 r = MsiDoActionA( package, "FileCost" );
13896 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13897
13898 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE );
13899 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13900
13901 attrs = 0;
13902 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13903 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13904 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE,
13905 "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs);
13906
13907 r = MsiDoActionA( package, "CostFinalize" );
13908 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13909
13910 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13911 ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r);
13912
13913 MsiCloseHandle( package );
13914 DeleteFileA( msifile );
13915 }
13916
13917 static void test_MsiGetFeatureInfo(void)
13918 {
13919 UINT r;
13920 MSIHANDLE package;
13921 char title[32], help[32], path[MAX_PATH];
13922 DWORD attrs, title_len, help_len;
13923
13924 if (is_process_limited())
13925 {
13926 skip("process is limited\n");
13927 return;
13928 }
13929 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
13930
13931 strcpy( path, CURR_DIR );
13932 strcat( path, "\\" );
13933 strcat( path, msifile );
13934
13935 r = MsiOpenPackageA( path, &package );
13936 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13937 {
13938 skip("Not enough rights to perform tests\n");
13939 DeleteFileA( msifile );
13940 return;
13941 }
13942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13943
13944 r = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL );
13945 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13946
13947 r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
13948 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13949
13950 r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
13951 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13952
13953 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
13954 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13955
13956 r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
13957 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
13958
13959 title_len = help_len = 0;
13960 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
13961 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13962 ok(title_len == 3, "expected 3, got %u\n", title_len);
13963 ok(help_len == 3, "expected 3, got %u\n", help_len);
13964
13965 title[0] = help[0] = 0;
13966 title_len = help_len = 0;
13967 r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
13968 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
13969 ok(title_len == 3, "expected 3, got %u\n", title_len);
13970 ok(help_len == 3, "expected 3, got %u\n", help_len);
13971
13972 attrs = 0;
13973 title[0] = help[0] = 0;
13974 title_len = sizeof(title);
13975 help_len = sizeof(help);
13976 r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
13977 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13978 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
13979 ok(title_len == 3, "expected 3, got %u\n", title_len);
13980 ok(help_len == 3, "expected 3, got %u\n", help_len);
13981 ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
13982 ok(!strcmp(help, "One"), "expected \"One\", got \"%s\"\n", help);
13983
13984 attrs = 0;
13985 title[0] = help[0] = 0;
13986 title_len = sizeof(title);
13987 help_len = sizeof(help);
13988 r = MsiGetFeatureInfoA( package, "Two", &attrs, title, &title_len, help, &help_len );
13989 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13990 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
13991 ok(!title_len, "expected 0, got %u\n", title_len);
13992 ok(!help_len, "expected 0, got %u\n", help_len);
13993 ok(!title[0], "expected \"\", got \"%s\"\n", title);
13994 ok(!help[0], "expected \"\", got \"%s\"\n", help);
13995
13996 MsiCloseHandle( package );
13997 DeleteFileA( msifile );
13998 }
13999
14000 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
14001 {
14002 return IDOK;
14003 }
14004
14005 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
14006 {
14007 return IDOK;
14008 }
14009
14010 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
14011 {
14012 return IDOK;
14013 }
14014
14015 static void test_MsiSetExternalUI(void)
14016 {
14017 INSTALLUI_HANDLERA ret_a;
14018 INSTALLUI_HANDLERW ret_w;
14019 INSTALLUI_HANDLER_RECORD prev;
14020 UINT error;
14021
14022 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
14023 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
14024
14025 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
14026 ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
14027
14028 /* Not present before Installer 3.1 */
14029 if (!pMsiSetExternalUIRecord) {
14030 win_skip("MsiSetExternalUIRecord is not available\n");
14031 return;
14032 }
14033
14034 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
14035 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14036 ok(prev == NULL, "expected NULL, got %p\n", prev);
14037
14038 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
14039 error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
14040 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14041 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
14042
14043 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
14044 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
14045
14046 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
14047 ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
14048
14049 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
14050 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
14051
14052 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
14053 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
14054
14055 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
14056 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
14057 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14058 ok(prev == NULL, "expected NULL, got %p\n", prev);
14059
14060 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
14061 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
14062
14063 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
14064 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
14065
14066 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
14067 error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
14068 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14069 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
14070
14071 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
14072 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14073
14074 error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
14075 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14076 }
14077
14078 static void test_lastusedsource(void)
14079 {
14080 static const char prodcode[] = "{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}";
14081 char value[MAX_PATH], path[MAX_PATH];
14082 DWORD size;
14083 UINT r;
14084
14085 if (!pMsiSourceListGetInfoA)
14086 {
14087 win_skip("MsiSourceListGetInfoA is not available\n");
14088 return;
14089 }
14090
14091 CreateDirectoryA("msitest", NULL);
14092 create_file("maximus", "maximus", 500);
14093 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
14094 DeleteFileA("maximus");
14095
14096 create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
14097 create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
14098 create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
14099
14100 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14101
14102 /* no cabinet file */
14103
14104 size = MAX_PATH;
14105 lstrcpyA(value, "aaa");
14106 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14107 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14108 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14109 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14110
14111 r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
14112 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14113 {
14114 skip("Not enough rights to perform tests\n");
14115 goto error;
14116 }
14117 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14118
14119 lstrcpyA(path, CURR_DIR);
14120 lstrcatA(path, "\\");
14121
14122 size = MAX_PATH;
14123 lstrcpyA(value, "aaa");
14124 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14125 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14126 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14127 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14128 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
14129
14130 r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
14131 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14132
14133 /* separate cabinet file */
14134
14135 size = MAX_PATH;
14136 lstrcpyA(value, "aaa");
14137 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14138 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14139 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14140 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14141
14142 r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
14143 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14144
14145 lstrcpyA(path, CURR_DIR);
14146 lstrcatA(path, "\\");
14147
14148 size = MAX_PATH;
14149 lstrcpyA(value, "aaa");
14150 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14151 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14152 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14153 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14154 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
14155
14156 r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
14157 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14158
14159 size = MAX_PATH;
14160 lstrcpyA(value, "aaa");
14161 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14162 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14163 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14164 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14165
14166 /* embedded cabinet stream */
14167
14168 add_cabinet_storage("msifile2.msi", "test1.cab");
14169
14170 r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
14171 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14172
14173 size = MAX_PATH;
14174 lstrcpyA(value, "aaa");
14175 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14176 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14177 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14178 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14179 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
14180
14181 r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
14182 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14183
14184 size = MAX_PATH;
14185 lstrcpyA(value, "aaa");
14186 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14187 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14188 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14189 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14190
14191 error:
14192 delete_cab_files();
14193 DeleteFileA("msitest\\maximus");
14194 RemoveDirectoryA("msitest");
14195 DeleteFileA("msifile0.msi");
14196 DeleteFileA("msifile1.msi");
14197 DeleteFileA("msifile2.msi");
14198 }
14199
14200 static void test_setpropertyfolder(void)
14201 {
14202 UINT r;
14203 CHAR path[MAX_PATH];
14204 DWORD attr;
14205
14206 if (is_process_limited())
14207 {
14208 skip("process is limited\n");
14209 return;
14210 }
14211
14212 lstrcpyA(path, PROG_FILES_DIR);
14213 lstrcatA(path, "\\msitest\\added");
14214
14215 CreateDirectoryA("msitest", NULL);
14216 create_file("msitest\\maximus", "msitest\\maximus", 500);
14217
14218 create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
14219
14220 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14221
14222 r = MsiInstallProductA(msifile, NULL);
14223 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14224 {
14225 skip("Not enough rights to perform tests\n");
14226 goto error;
14227 }
14228 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14229 attr = GetFileAttributesA(path);
14230 if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
14231 {
14232 ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
14233 ok(delete_pf("msitest\\added", FALSE), "Directory not created\n");
14234 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14235 }
14236 else
14237 {
14238 trace("changing folder property not supported\n");
14239 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14240 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14241 }
14242
14243 error:
14244 DeleteFileA(msifile);
14245 DeleteFileA("msitest\\maximus");
14246 RemoveDirectoryA("msitest");
14247 }
14248
14249 static void test_sourcedir_props(void)
14250 {
14251 UINT r;
14252
14253 if (is_process_limited())
14254 {
14255 skip("process is limited\n");
14256 return;
14257 }
14258
14259 create_test_files();
14260 create_file("msitest\\sourcedir.txt", "msitest\\sourcedir.txt", 1000);
14261 create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
14262
14263 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14264
14265 /* full UI, no ResolveSource action */
14266 r = MsiInstallProductA(msifile, NULL);
14267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14268
14269 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14270 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14271
14272 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14273 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14274
14275 /* full UI, ResolveSource action */
14276 r = MsiInstallProductA(msifile, "ResolveSource=1");
14277 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14278
14279 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14281
14282 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14283 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14284
14285 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14286
14287 /* no UI, no ResolveSource action */
14288 r = MsiInstallProductA(msifile, NULL);
14289 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14290
14291 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14292 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14293
14294 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14295 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14296
14297 /* no UI, ResolveSource action */
14298 r = MsiInstallProductA(msifile, "ResolveSource=1");
14299 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14300
14301 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14302 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14303
14304 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14305 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14306
14307 DeleteFileA("msitest\\sourcedir.txt");
14308 delete_test_files();
14309 DeleteFileA(msifile);
14310 }
14311
14312 static void test_concurrentinstall(void)
14313 {
14314 UINT r;
14315 CHAR path[MAX_PATH];
14316
14317 if (is_process_limited())
14318 {
14319 skip("process is limited\n");
14320 return;
14321 }
14322
14323 CreateDirectoryA("msitest", NULL);
14324 CreateDirectoryA("msitest\\msitest", NULL);
14325 create_file("msitest\\maximus", "msitest\\maximus", 500);
14326 create_file("msitest\\msitest\\augustus", "msitest\\msitest\\augustus", 500);
14327
14328 create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
14329
14330 lstrcpyA(path, CURR_DIR);
14331 lstrcatA(path, "\\msitest\\concurrent.msi");
14332 create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
14333
14334 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14335
14336 r = MsiInstallProductA(msifile, NULL);
14337 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14338 {
14339 skip("Not enough rights to perform tests\n");
14340 goto error;
14341 }
14342 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14343 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
14344 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14345 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14346
14347 r = MsiConfigureProductA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", INSTALLLEVEL_DEFAULT,
14348 INSTALLSTATE_ABSENT);
14349 ok(r == ERROR_SUCCESS, "got %u\n", r);
14350
14351 r = MsiConfigureProductA("{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}", INSTALLLEVEL_DEFAULT,
14352 INSTALLSTATE_ABSENT);
14353 ok(r == ERROR_SUCCESS, "got %u\n", r);
14354
14355 error:
14356 DeleteFileA(path);
14357 DeleteFileA(msifile);
14358 DeleteFileA("msitest\\msitest\\augustus");
14359 DeleteFileA("msitest\\maximus");
14360 RemoveDirectoryA("msitest\\msitest");
14361 RemoveDirectoryA("msitest");
14362 }
14363
14364 static void test_command_line_parsing(void)
14365 {
14366 UINT r;
14367 const char *cmd;
14368
14369 if (is_process_limited())
14370 {
14371 skip("process is limited\n");
14372 return;
14373 }
14374
14375 create_test_files();
14376 create_database(msifile, cl_tables, sizeof(cl_tables)/sizeof(msi_table));
14377
14378 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14379
14380 cmd = " ";
14381 r = MsiInstallProductA(msifile, cmd);
14382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14383
14384 cmd = "=";
14385 r = MsiInstallProductA(msifile, cmd);
14386 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14387
14388 cmd = "==";
14389 r = MsiInstallProductA(msifile, cmd);
14390 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14391
14392 cmd = "one";
14393 r = MsiInstallProductA(msifile, cmd);
14394 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14395
14396 cmd = "=one";
14397 r = MsiInstallProductA(msifile, cmd);
14398 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14399
14400 cmd = "P=";
14401 r = MsiInstallProductA(msifile, cmd);
14402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14403
14404 cmd = " P=";
14405 r = MsiInstallProductA(msifile, cmd);
14406 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14407
14408 cmd = "P= ";
14409 r = MsiInstallProductA(msifile, cmd);
14410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14411
14412 cmd = "P=\"";
14413 r = MsiInstallProductA(msifile, cmd);
14414 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14415
14416 cmd = "P=\"\"";
14417 r = MsiInstallProductA(msifile, cmd);
14418 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14419
14420 cmd = "P=\"\"\"";
14421 r = MsiInstallProductA(msifile, cmd);
14422 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14423
14424 cmd = "P=\"\"\"\"";
14425 r = MsiInstallProductA(msifile, cmd);
14426 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14427
14428 cmd = "P=\" ";
14429 r = MsiInstallProductA(msifile, cmd);
14430 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14431
14432 cmd = "P= \"";
14433 r = MsiInstallProductA(msifile, cmd);
14434 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14435
14436 cmd = "P= \"\" ";
14437 r = MsiInstallProductA(msifile, cmd);
14438 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14439
14440 cmd = "P=\" \"";
14441 r = MsiInstallProductA(msifile, cmd);
14442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14443
14444 cmd = "P=one";
14445 r = MsiInstallProductA(msifile, cmd);
14446 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14447
14448 cmd = "P= one";
14449 r = MsiInstallProductA(msifile, cmd);
14450 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14451
14452 cmd = "P=\"one";
14453 r = MsiInstallProductA(msifile, cmd);
14454 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14455
14456 cmd = "P=one\"";
14457 r = MsiInstallProductA(msifile, cmd);
14458 todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14459
14460 cmd = "P=\"one\"";
14461 r = MsiInstallProductA(msifile, cmd);
14462 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14463
14464 cmd = "P= \"one\" ";
14465 r = MsiInstallProductA(msifile, cmd);
14466 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14467
14468 cmd = "P=\"one\"\"";
14469 r = MsiInstallProductA(msifile, cmd);
14470 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14471
14472 cmd = "P=\"\"one\"";
14473 r = MsiInstallProductA(msifile, cmd);
14474 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14475
14476 cmd = "P=\"\"one\"\"";
14477 r = MsiInstallProductA(msifile, cmd);
14478 todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14479
14480 cmd = "P=\"one two\"";
14481 r = MsiInstallProductA(msifile, cmd);
14482 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14483
14484 cmd = "P=\"\"\"one\"\" two\"";
14485 r = MsiInstallProductA(msifile, cmd);
14486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14487
14488 cmd = "P=\"\"\"one\"\" two\" Q=three";
14489 r = MsiInstallProductA(msifile, cmd);
14490 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14491
14492 cmd = "P=\"\" Q=\"two\"";
14493 r = MsiInstallProductA(msifile, cmd);
14494 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14495
14496 cmd = "P=\"one\" Q=\"two\"";
14497 r = MsiInstallProductA(msifile, cmd);
14498 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14499
14500 cmd = "P=\"one=two\"";
14501 r = MsiInstallProductA(msifile, cmd);
14502 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14503
14504 cmd = "Q=\"\" P=\"one\"";
14505 r = MsiInstallProductA(msifile, cmd);
14506 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14507
14508 cmd = "P=\"\"\"one\"\"\" Q=\"two\"";
14509 r = MsiInstallProductA(msifile, cmd);
14510 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14511
14512 cmd = "P=\"one \"\"two\"\"\" Q=\"three\"";
14513 r = MsiInstallProductA(msifile, cmd);
14514 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14515
14516 cmd = "P=\"\"\"one\"\" two\" Q=\"three\"";
14517 r = MsiInstallProductA(msifile, cmd);
14518 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14519
14520 DeleteFileA(msifile);
14521 delete_test_files();
14522 }
14523
14524 START_TEST(msi)
14525 {
14526 DWORD len;
14527 char temp_path[MAX_PATH], prev_path[MAX_PATH];
14528
14529 #ifdef __REACTOS__
14530 if (!winetest_interactive &&
14531 !strcmp(winetest_platform, "windows"))
14532 {
14533 skip("ROSTESTS-180: Skipping msi_winetest:msi because it hangs on WHS-Testbot. Set winetest_interactive to run it anyway.\n");
14534 return;
14535 }
14536 #endif
14537
14538 init_functionpointers();
14539
14540 if (pIsWow64Process)
14541 pIsWow64Process(GetCurrentProcess(), &is_wow64);
14542
14543 GetCurrentDirectoryA(MAX_PATH, prev_path);
14544 GetTempPathA(MAX_PATH, temp_path);
14545 SetCurrentDirectoryA(temp_path);
14546
14547 lstrcpyA(CURR_DIR, temp_path);
14548 len = lstrlenA(CURR_DIR);
14549
14550 if(len && (CURR_DIR[len - 1] == '\\'))
14551 CURR_DIR[len - 1] = 0;
14552
14553 ok(get_system_dirs(), "failed to retrieve system dirs\n");
14554
14555 test_usefeature();
14556 test_null();
14557 test_getcomponentpath();
14558 test_MsiGetFileHash();
14559
14560 if (!pConvertSidToStringSidA)
14561 win_skip("ConvertSidToStringSidA not implemented\n");
14562 else
14563 {
14564 /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
14565 test_MsiQueryProductState();
14566 test_MsiQueryFeatureState();
14567 test_MsiQueryComponentState();
14568 test_MsiGetComponentPath();
14569 test_MsiProvideComponent();
14570 test_MsiGetProductCode();
14571 test_MsiEnumClients();
14572 test_MsiGetProductInfo();
14573 test_MsiGetProductInfoEx();
14574 test_MsiGetUserInfo();
14575 test_MsiOpenProduct();
14576 test_MsiEnumPatchesEx();
14577 test_MsiEnumPatches();
14578 test_MsiGetPatchInfoEx();
14579 test_MsiGetPatchInfo();
14580 test_MsiEnumProducts();
14581 test_MsiEnumProductsEx();
14582 test_MsiEnumComponents();
14583 test_MsiEnumComponentsEx();
14584 }
14585 test_MsiGetFileVersion();
14586 test_MsiGetFileSignatureInformation();
14587 test_MsiConfigureProductEx();
14588 test_MsiSetFeatureAttributes();
14589 test_MsiGetFeatureInfo();
14590 test_MsiSetExternalUI();
14591 test_lastusedsource();
14592 test_setpropertyfolder();
14593 test_sourcedir_props();
14594 if (pMsiGetComponentPathExA)
14595 test_concurrentinstall();
14596 test_command_line_parsing();
14597 test_MsiProvideQualifiedComponentEx();
14598
14599 SetCurrentDirectoryA(prev_path);
14600 }