be9d6d8265c78eb16b2c9957ba1c97297ceb0c43
[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 mcp_component_dat[] =
561 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
562 "s72\tS38\ts72\ti2\tS255\tS72\n"
563 "Component\tComponent\n"
564 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
565 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
566 "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
567
568 static const char mcp_feature_dat[] =
569 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
570 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
571 "Feature\tFeature\n"
572 "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
573 "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
574 "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
575
576 static const char mcp_feature_comp_dat[] =
577 "Feature_\tComponent_\n"
578 "s38\ts72\n"
579 "FeatureComponents\tFeature_\tComponent_\n"
580 "hydroxyl\thydrogen\n"
581 "heliox\thelium\n"
582 "lithia\tlithium";
583
584 static const char mcp_file_dat[] =
585 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
586 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
587 "File\tFile\n"
588 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
589 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
590 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
591
592 static const char lus_component_dat[] =
593 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
594 "s72\tS38\ts72\ti2\tS255\tS72\n"
595 "Component\tComponent\n"
596 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
597
598 static const char lus_feature_dat[] =
599 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
600 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
601 "Feature\tFeature\n"
602 "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
603 "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
604
605 static const char lus_file_dat[] =
606 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
607 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
608 "File\tFile\n"
609 "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
610
611 static const char lus_feature_comp_dat[] =
612 "Feature_\tComponent_\n"
613 "s38\ts72\n"
614 "FeatureComponents\tFeature_\tComponent_\n"
615 "feature\tmaximus\n"
616 "montecristo\tmaximus";
617
618 static const char lus_install_exec_seq_dat[] =
619 "Action\tCondition\tSequence\n"
620 "s72\tS255\tI2\n"
621 "InstallExecuteSequence\tAction\n"
622 "ValidateProductID\t\t700\n"
623 "CostInitialize\t\t800\n"
624 "FileCost\t\t900\n"
625 "CostFinalize\t\t1000\n"
626 "InstallValidate\t\t1400\n"
627 "InstallInitialize\t\t1500\n"
628 "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
629 "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
630 "RemoveFiles\t\t3500\n"
631 "InstallFiles\t\t4000\n"
632 "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
633 "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
634 "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
635 "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
636 "InstallFinalize\t\t6600";
637
638 static const char lus0_media_dat[] =
639 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
640 "i2\ti4\tL64\tS255\tS32\tS72\n"
641 "Media\tDiskId\n"
642 "1\t1\t\t\tDISK1\t\n";
643
644 static const char lus1_media_dat[] =
645 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
646 "i2\ti4\tL64\tS255\tS32\tS72\n"
647 "Media\tDiskId\n"
648 "1\t1\t\ttest1.cab\tDISK1\t\n";
649
650 static const char lus2_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#test1.cab\tDISK1\t\n";
655
656 static const char spf_custom_action_dat[] =
657 "Action\tType\tSource\tTarget\tISComments\n"
658 "s72\ti2\tS64\tS0\tS255\n"
659 "CustomAction\tAction\n"
660 "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
661
662 static const char spf_install_exec_seq_dat[] =
663 "Action\tCondition\tSequence\n"
664 "s72\tS255\tI2\n"
665 "InstallExecuteSequence\tAction\n"
666 "CostFinalize\t\t1000\n"
667 "CostInitialize\t\t800\n"
668 "FileCost\t\t900\n"
669 "SetFolderProp\t\t950\n"
670 "InstallFiles\t\t4000\n"
671 "InstallServices\t\t5000\n"
672 "InstallFinalize\t\t6600\n"
673 "InstallInitialize\t\t1500\n"
674 "InstallValidate\t\t1400\n"
675 "LaunchConditions\t\t100";
676
677 static const char spf_install_ui_seq_dat[] =
678 "Action\tCondition\tSequence\n"
679 "s72\tS255\tI2\n"
680 "InstallUISequence\tAction\n"
681 "CostInitialize\t\t800\n"
682 "FileCost\t\t900\n"
683 "CostFinalize\t\t1000\n"
684 "ExecuteAction\t\t1100\n";
685
686 static const char sd_file_dat[] =
687 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
688 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
689 "File\tFile\n"
690 "sourcedir.txt\tsourcedir\tsourcedir.txt\t1000\t\t\t8192\t1\n";
691
692 static const char sd_feature_dat[] =
693 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
694 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
695 "Feature\tFeature\n"
696 "sourcedir\t\t\tsourcedir feature\t1\t2\tMSITESTDIR\t0\n";
697
698 static const char sd_feature_comp_dat[] =
699 "Feature_\tComponent_\n"
700 "s38\ts72\n"
701 "FeatureComponents\tFeature_\tComponent_\n"
702 "sourcedir\tsourcedir\n";
703
704 static const char sd_component_dat[] =
705 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
706 "s72\tS38\ts72\ti2\tS255\tS72\n"
707 "Component\tComponent\n"
708 "sourcedir\t{DD422F92-3ED8-49B5-A0B7-F266F98357DF}\tMSITESTDIR\t0\t\tsourcedir.txt\n";
709
710 static const char sd_install_ui_seq_dat[] =
711 "Action\tCondition\tSequence\n"
712 "s72\tS255\tI2\n"
713 "InstallUISequence\tAction\n"
714 "TestSourceDirProp1\tnot SourceDir and not SOURCEDIR and not Installed\t99\n"
715 "AppSearch\t\t100\n"
716 "TestSourceDirProp2\tnot SourceDir and not SOURCEDIR and not Installed\t101\n"
717 "LaunchConditions\tnot Installed \t110\n"
718 "TestSourceDirProp3\tnot SourceDir and not SOURCEDIR and not Installed\t111\n"
719 "FindRelatedProducts\t\t120\n"
720 "TestSourceDirProp4\tnot SourceDir and not SOURCEDIR and not Installed\t121\n"
721 "CCPSearch\t\t130\n"
722 "TestSourceDirProp5\tnot SourceDir and not SOURCEDIR and not Installed\t131\n"
723 "RMCCPSearch\t\t140\n"
724 "TestSourceDirProp6\tnot SourceDir and not SOURCEDIR and not Installed\t141\n"
725 "ValidateProductID\t\t150\n"
726 "TestSourceDirProp7\tnot SourceDir and not SOURCEDIR and not Installed\t151\n"
727 "CostInitialize\t\t800\n"
728 "TestSourceDirProp8\tnot SourceDir and not SOURCEDIR and not Installed\t801\n"
729 "FileCost\t\t900\n"
730 "TestSourceDirProp9\tnot SourceDir and not SOURCEDIR and not Installed\t901\n"
731 "IsolateComponents\t\t1000\n"
732 "TestSourceDirProp10\tnot SourceDir and not SOURCEDIR and not Installed\t1001\n"
733 "CostFinalize\t\t1100\n"
734 "TestSourceDirProp11\tnot SourceDir and not SOURCEDIR and not Installed\t1101\n"
735 "MigrateFeatureStates\t\t1200\n"
736 "TestSourceDirProp12\tnot SourceDir and not SOURCEDIR and not Installed\t1201\n"
737 "ExecuteAction\t\t1300\n"
738 "TestSourceDirProp13\tnot SourceDir and not SOURCEDIR and not Installed\t1301\n";
739
740 static const char sd_install_exec_seq_dat[] =
741 "Action\tCondition\tSequence\n"
742 "s72\tS255\tI2\n"
743 "InstallExecuteSequence\tAction\n"
744 "TestSourceDirProp14\tSourceDir and SOURCEDIR and not Installed\t99\n"
745 "LaunchConditions\t\t100\n"
746 "TestSourceDirProp15\tSourceDir and SOURCEDIR and not Installed\t101\n"
747 "ValidateProductID\t\t700\n"
748 "TestSourceDirProp16\tSourceDir and SOURCEDIR and not Installed\t701\n"
749 "CostInitialize\t\t800\n"
750 "TestSourceDirProp17\tSourceDir and SOURCEDIR and not Installed\t801\n"
751 "ResolveSource\tResolveSource and not Installed\t850\n"
752 "TestSourceDirProp18\tResolveSource and not SourceDir and not SOURCEDIR and not Installed\t851\n"
753 "TestSourceDirProp19\tnot ResolveSource and SourceDir and SOURCEDIR and not Installed\t852\n"
754 "FileCost\t\t900\n"
755 "TestSourceDirProp20\tSourceDir and SOURCEDIR and not Installed\t901\n"
756 "IsolateComponents\t\t1000\n"
757 "TestSourceDirProp21\tSourceDir and SOURCEDIR and not Installed\t1001\n"
758 "CostFinalize\t\t1100\n"
759 "TestSourceDirProp22\tSourceDir and SOURCEDIR and not Installed\t1101\n"
760 "MigrateFeatureStates\t\t1200\n"
761 "TestSourceDirProp23\tSourceDir and SOURCEDIR and not Installed\t1201\n"
762 "InstallValidate\t\t1400\n"
763 "TestSourceDirProp24\tSourceDir and SOURCEDIR and not Installed\t1401\n"
764 "InstallInitialize\t\t1500\n"
765 "TestSourceDirProp25\tSourceDir and SOURCEDIR and not Installed\t1501\n"
766 "ProcessComponents\t\t1600\n"
767 "TestSourceDirProp26\tnot SourceDir and not SOURCEDIR and not Installed\t1601\n"
768 "UnpublishFeatures\t\t1800\n"
769 "TestSourceDirProp27\tnot SourceDir and not SOURCEDIR and not Installed\t1801\n"
770 "RemoveFiles\t\t3500\n"
771 "TestSourceDirProp28\tnot SourceDir and not SOURCEDIR and not Installed\t3501\n"
772 "InstallFiles\t\t4000\n"
773 "TestSourceDirProp29\tnot SourceDir and not SOURCEDIR and not Installed\t4001\n"
774 "RegisterUser\t\t6000\n"
775 "TestSourceDirProp30\tnot SourceDir and not SOURCEDIR and not Installed\t6001\n"
776 "RegisterProduct\t\t6100\n"
777 "TestSourceDirProp31\tnot SourceDir and not SOURCEDIR and not Installed\t6101\n"
778 "PublishFeatures\t\t6300\n"
779 "TestSourceDirProp32\tnot SourceDir and not SOURCEDIR and not Installed\t6301\n"
780 "PublishProduct\t\t6400\n"
781 "TestSourceDirProp33\tnot SourceDir and not SOURCEDIR and not Installed\t6401\n"
782 "InstallExecute\t\t6500\n"
783 "TestSourceDirProp34\tnot SourceDir and not SOURCEDIR and not Installed\t6501\n"
784 "InstallFinalize\t\t6600\n"
785 "TestSourceDirProp35\tnot SourceDir and not SOURCEDIR and not Installed\t6601\n";
786
787 static const char sd_custom_action_dat[] =
788 "Action\tType\tSource\tTarget\tISComments\n"
789 "s72\ti2\tS64\tS0\tS255\n"
790 "CustomAction\tAction\n"
791 "TestSourceDirProp1\t19\t\tTest 1 failed\t\n"
792 "TestSourceDirProp2\t19\t\tTest 2 failed\t\n"
793 "TestSourceDirProp3\t19\t\tTest 3 failed\t\n"
794 "TestSourceDirProp4\t19\t\tTest 4 failed\t\n"
795 "TestSourceDirProp5\t19\t\tTest 5 failed\t\n"
796 "TestSourceDirProp6\t19\t\tTest 6 failed\t\n"
797 "TestSourceDirProp7\t19\t\tTest 7 failed\t\n"
798 "TestSourceDirProp8\t19\t\tTest 8 failed\t\n"
799 "TestSourceDirProp9\t19\t\tTest 9 failed\t\n"
800 "TestSourceDirProp10\t19\t\tTest 10 failed\t\n"
801 "TestSourceDirProp11\t19\t\tTest 11 failed\t\n"
802 "TestSourceDirProp12\t19\t\tTest 12 failed\t\n"
803 "TestSourceDirProp13\t19\t\tTest 13 failed\t\n"
804 "TestSourceDirProp14\t19\t\tTest 14 failed\t\n"
805 "TestSourceDirProp15\t19\t\tTest 15 failed\t\n"
806 "TestSourceDirProp16\t19\t\tTest 16 failed\t\n"
807 "TestSourceDirProp17\t19\t\tTest 17 failed\t\n"
808 "TestSourceDirProp18\t19\t\tTest 18 failed\t\n"
809 "TestSourceDirProp19\t19\t\tTest 19 failed\t\n"
810 "TestSourceDirProp20\t19\t\tTest 20 failed\t\n"
811 "TestSourceDirProp21\t19\t\tTest 21 failed\t\n"
812 "TestSourceDirProp22\t19\t\tTest 22 failed\t\n"
813 "TestSourceDirProp23\t19\t\tTest 23 failed\t\n"
814 "TestSourceDirProp24\t19\t\tTest 24 failed\t\n"
815 "TestSourceDirProp25\t19\t\tTest 25 failed\t\n"
816 "TestSourceDirProp26\t19\t\tTest 26 failed\t\n"
817 "TestSourceDirProp27\t19\t\tTest 27 failed\t\n"
818 "TestSourceDirProp28\t19\t\tTest 28 failed\t\n"
819 "TestSourceDirProp29\t19\t\tTest 29 failed\t\n"
820 "TestSourceDirProp30\t19\t\tTest 30 failed\t\n"
821 "TestSourceDirProp31\t19\t\tTest 31 failed\t\n"
822 "TestSourceDirProp32\t19\t\tTest 32 failed\t\n"
823 "TestSourceDirProp33\t19\t\tTest 33 failed\t\n"
824 "TestSourceDirProp34\t19\t\tTest 34 failed\t\n"
825 "TestSourceDirProp35\t19\t\tTest 35 failed\t\n";
826
827 static const char ci_install_exec_seq_dat[] =
828 "Action\tCondition\tSequence\n"
829 "s72\tS255\tI2\n"
830 "InstallExecuteSequence\tAction\n"
831 "CostFinalize\t\t1000\n"
832 "CostInitialize\t\t800\n"
833 "FileCost\t\t900\n"
834 "InstallFiles\t\t4000\n"
835 "InstallServices\t\t5000\n"
836 "InstallFinalize\t\t6600\n"
837 "InstallInitialize\t\t1500\n"
838 "RunInstall\t\t1600\n"
839 "InstallValidate\t\t1400\n"
840 "LaunchConditions\t\t100";
841
842 static const char ci_custom_action_dat[] =
843 "Action\tType\tSource\tTarget\tISComments\n"
844 "s72\ti2\tS64\tS0\tS255\n"
845 "CustomAction\tAction\n"
846 "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
847
848 static const char ci_component_dat[] =
849 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
850 "s72\tS38\ts72\ti2\tS255\tS72\n"
851 "Component\tComponent\n"
852 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
853
854 static const char ci2_component_dat[] =
855 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
856 "s72\tS38\ts72\ti2\tS255\tS72\n"
857 "Component\tComponent\n"
858 "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
859
860 static const char ci2_feature_comp_dat[] =
861 "Feature_\tComponent_\n"
862 "s38\ts72\n"
863 "FeatureComponents\tFeature_\tComponent_\n"
864 "feature\taugustus";
865
866 static const char ci2_file_dat[] =
867 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
868 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
869 "File\tFile\n"
870 "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
871
872 static const char cl_custom_action_dat[] =
873 "Action\tType\tSource\tTarget\tISComments\n"
874 "s72\ti2\tS64\tS0\tS255\n"
875 "CustomAction\tAction\n"
876 "TestCommandlineProp\t19\t\tTest1\t\n";
877
878 static const char cl_install_exec_seq_dat[] =
879 "Action\tCondition\tSequence\n"
880 "s72\tS255\tI2\n"
881 "InstallExecuteSequence\tAction\n"
882 "LaunchConditions\t\t100\n"
883 "ValidateProductID\t\t700\n"
884 "CostInitialize\t\t800\n"
885 "FileCost\t\t900\n"
886 "CostFinalize\t\t1000\n"
887 "TestCommandlineProp\tP=\"one\"\t1100\n"
888 "InstallInitialize\t\t1500\n"
889 "ProcessComponents\t\t1600\n"
890 "InstallValidate\t\t1400\n"
891 "InstallFinalize\t\t5000\n";
892
893 typedef struct _msi_table
894 {
895 const CHAR *filename;
896 const CHAR *data;
897 int size;
898 } msi_table;
899
900 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
901
902 static const msi_table tables[] =
903 {
904 ADD_TABLE(directory),
905 ADD_TABLE(component),
906 ADD_TABLE(feature),
907 ADD_TABLE(feature_comp),
908 ADD_TABLE(file),
909 ADD_TABLE(install_exec_seq),
910 ADD_TABLE(media),
911 ADD_TABLE(property),
912 };
913
914 static const msi_table mcp_tables[] =
915 {
916 ADD_TABLE(directory),
917 ADD_TABLE(mcp_component),
918 ADD_TABLE(mcp_feature),
919 ADD_TABLE(mcp_feature_comp),
920 ADD_TABLE(mcp_file),
921 ADD_TABLE(install_exec_seq),
922 ADD_TABLE(media),
923 ADD_TABLE(property)
924 };
925
926 static const msi_table lus0_tables[] =
927 {
928 ADD_TABLE(lus_component),
929 ADD_TABLE(directory),
930 ADD_TABLE(lus_feature),
931 ADD_TABLE(lus_feature_comp),
932 ADD_TABLE(lus_file),
933 ADD_TABLE(lus_install_exec_seq),
934 ADD_TABLE(lus0_media),
935 ADD_TABLE(property)
936 };
937
938 static const msi_table lus1_tables[] =
939 {
940 ADD_TABLE(lus_component),
941 ADD_TABLE(directory),
942 ADD_TABLE(lus_feature),
943 ADD_TABLE(lus_feature_comp),
944 ADD_TABLE(lus_file),
945 ADD_TABLE(lus_install_exec_seq),
946 ADD_TABLE(lus1_media),
947 ADD_TABLE(property)
948 };
949
950 static const msi_table lus2_tables[] =
951 {
952 ADD_TABLE(lus_component),
953 ADD_TABLE(directory),
954 ADD_TABLE(lus_feature),
955 ADD_TABLE(lus_feature_comp),
956 ADD_TABLE(lus_file),
957 ADD_TABLE(lus_install_exec_seq),
958 ADD_TABLE(lus2_media),
959 ADD_TABLE(property)
960 };
961
962 static const msi_table spf_tables[] =
963 {
964 ADD_TABLE(lus_component),
965 ADD_TABLE(directory),
966 ADD_TABLE(lus_feature),
967 ADD_TABLE(lus_feature_comp),
968 ADD_TABLE(lus_file),
969 ADD_TABLE(lus0_media),
970 ADD_TABLE(property),
971 ADD_TABLE(spf_custom_action),
972 ADD_TABLE(spf_install_exec_seq),
973 ADD_TABLE(spf_install_ui_seq)
974 };
975
976 static const msi_table sd_tables[] =
977 {
978 ADD_TABLE(directory),
979 ADD_TABLE(sd_component),
980 ADD_TABLE(sd_feature),
981 ADD_TABLE(sd_feature_comp),
982 ADD_TABLE(sd_file),
983 ADD_TABLE(sd_install_exec_seq),
984 ADD_TABLE(sd_install_ui_seq),
985 ADD_TABLE(sd_custom_action),
986 ADD_TABLE(media),
987 ADD_TABLE(property)
988 };
989
990 static const msi_table ci_tables[] =
991 {
992 ADD_TABLE(ci_component),
993 ADD_TABLE(directory),
994 ADD_TABLE(lus_feature),
995 ADD_TABLE(lus_feature_comp),
996 ADD_TABLE(lus_file),
997 ADD_TABLE(ci_install_exec_seq),
998 ADD_TABLE(lus0_media),
999 ADD_TABLE(property),
1000 ADD_TABLE(ci_custom_action),
1001 };
1002
1003 static const msi_table ci2_tables[] =
1004 {
1005 ADD_TABLE(ci2_component),
1006 ADD_TABLE(directory),
1007 ADD_TABLE(lus_feature),
1008 ADD_TABLE(ci2_feature_comp),
1009 ADD_TABLE(ci2_file),
1010 ADD_TABLE(install_exec_seq),
1011 ADD_TABLE(lus0_media),
1012 ADD_TABLE(property),
1013 };
1014
1015 static const msi_table cl_tables[] =
1016 {
1017 ADD_TABLE(component),
1018 ADD_TABLE(directory),
1019 ADD_TABLE(feature),
1020 ADD_TABLE(feature_comp),
1021 ADD_TABLE(file),
1022 ADD_TABLE(cl_custom_action),
1023 ADD_TABLE(cl_install_exec_seq),
1024 ADD_TABLE(media),
1025 ADD_TABLE(property)
1026 };
1027
1028 static void write_file(const CHAR *filename, const char *data, int data_size)
1029 {
1030 DWORD size;
1031
1032 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
1033 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1034 WriteFile(hf, data, data_size, &size, NULL);
1035 CloseHandle(hf);
1036 }
1037
1038 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
1039 {
1040 MSIHANDLE summary;
1041 UINT r;
1042
1043 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1044 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1045
1046 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
1047 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1048
1049 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1050 "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
1051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1052
1053 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
1054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1055
1056 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
1057 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1058
1059 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1061
1062 /* write the summary changes back to the stream */
1063 r = MsiSummaryInfoPersist(summary);
1064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1065
1066 MsiCloseHandle(summary);
1067 }
1068
1069 #define create_database(name, tables, num_tables) \
1070 create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
1071
1072 #define create_database_template(name, tables, num_tables, version, template) \
1073 create_database_wordcount(name, tables, num_tables, version, 0, template);
1074
1075 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
1076 int num_tables, INT version, INT wordcount,
1077 const char *template)
1078 {
1079 MSIHANDLE db;
1080 UINT r;
1081 WCHAR *nameW;
1082 int j, len;
1083
1084 len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
1085 if (!(nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return;
1086 MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
1087
1088 r = MsiOpenDatabaseW(nameW, MSIDBOPEN_CREATE, &db);
1089 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1090
1091 /* import the tables into the database */
1092 for (j = 0; j < num_tables; j++)
1093 {
1094 const msi_table *table = &tables[j];
1095
1096 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1097
1098 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1099 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1100
1101 DeleteFileA(table->filename);
1102 }
1103
1104 write_msi_summary_info(db, version, wordcount, template);
1105
1106 r = MsiDatabaseCommit(db);
1107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1108
1109 MsiCloseHandle(db);
1110 HeapFree( GetProcessHeap(), 0, nameW );
1111 }
1112
1113 static UINT run_query(MSIHANDLE hdb, const char *query)
1114 {
1115 MSIHANDLE hview = 0;
1116 UINT r;
1117
1118 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1119 if (r != ERROR_SUCCESS)
1120 return r;
1121
1122 r = MsiViewExecute(hview, 0);
1123 if (r == ERROR_SUCCESS)
1124 r = MsiViewClose(hview);
1125 MsiCloseHandle(hview);
1126 return r;
1127 }
1128
1129 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
1130 {
1131 UINT res;
1132 MSIHANDLE suminfo;
1133
1134 /* build summary info */
1135 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
1136 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
1137
1138 res = MsiSummaryInfoSetPropertyA(suminfo, 2, VT_LPSTR, 0, NULL,
1139 "Installation Database");
1140 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1141
1142 res = MsiSummaryInfoSetPropertyA(suminfo, 3, VT_LPSTR, 0, NULL,
1143 "Installation Database");
1144 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1145
1146 res = MsiSummaryInfoSetPropertyA(suminfo, 4, VT_LPSTR, 0, NULL,
1147 "Wine Hackers");
1148 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1149
1150 res = MsiSummaryInfoSetPropertyA(suminfo, 7, VT_LPSTR, 0, NULL,
1151 ";1033");
1152 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1153
1154 res = MsiSummaryInfoSetPropertyA(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1155 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
1156 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1157
1158 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
1159 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1160
1161 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
1162 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1163
1164 res = MsiSummaryInfoPersist(suminfo);
1165 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
1166
1167 res = MsiCloseHandle(suminfo);
1168 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
1169
1170 return res;
1171 }
1172
1173 static MSIHANDLE create_package_db(LPSTR prodcode)
1174 {
1175 MSIHANDLE hdb = 0;
1176 CHAR query[MAX_PATH];
1177 UINT res;
1178
1179 DeleteFileA(msifile);
1180
1181 /* create an empty database */
1182 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
1183 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1184 if (res != ERROR_SUCCESS)
1185 return hdb;
1186
1187 res = MsiDatabaseCommit(hdb);
1188 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1189
1190 set_summary_info(hdb, prodcode);
1191
1192 res = run_query(hdb,
1193 "CREATE TABLE `Directory` ( "
1194 "`Directory` CHAR(255) NOT NULL, "
1195 "`Directory_Parent` CHAR(255), "
1196 "`DefaultDir` CHAR(255) NOT NULL "
1197 "PRIMARY KEY `Directory`)");
1198 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1199
1200 res = run_query(hdb,
1201 "CREATE TABLE `Property` ( "
1202 "`Property` CHAR(72) NOT NULL, "
1203 "`Value` CHAR(255) "
1204 "PRIMARY KEY `Property`)");
1205 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1206
1207 sprintf(query, "INSERT INTO `Property` "
1208 "(`Property`, `Value`) "
1209 "VALUES( 'ProductCode', '%s' )", prodcode);
1210 res = run_query(hdb, query);
1211 ok(res == ERROR_SUCCESS , "Failed\n");
1212
1213 res = MsiDatabaseCommit(hdb);
1214 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1215
1216 return hdb;
1217 }
1218
1219 static void test_usefeature(void)
1220 {
1221 INSTALLSTATE r;
1222
1223 if (!pMsiUseFeatureExA)
1224 {
1225 win_skip("MsiUseFeatureExA not implemented\n");
1226 return;
1227 }
1228
1229 r = MsiQueryFeatureStateA(NULL, NULL);
1230 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1231
1232 r = MsiQueryFeatureStateA("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
1233 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1234
1235 r = pMsiUseFeatureExA(NULL,NULL,0,0);
1236 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1237
1238 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
1239 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1240
1241 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1242 NULL, -2, 0 );
1243 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1244
1245 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
1246 "WORDVIEWFiles", -2, 0 );
1247 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1248
1249 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
1250 "WORDVIEWFiles", -2, 0 );
1251 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1252
1253 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1254 "WORDVIEWFiles", -2, 1 );
1255 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1256 }
1257
1258 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
1259 {
1260 if (pRegDeleteKeyExA)
1261 return pRegDeleteKeyExA( key, subkey, access, 0 );
1262 return RegDeleteKeyA( key, subkey );
1263 }
1264
1265 static void test_null(void)
1266 {
1267 MSIHANDLE hpkg;
1268 UINT r;
1269 HKEY hkey;
1270 DWORD dwType, cbData;
1271 LPBYTE lpData = NULL;
1272 INSTALLSTATE state;
1273 REGSAM access = KEY_ALL_ACCESS;
1274
1275 if (is_wow64)
1276 access |= KEY_WOW64_64KEY;
1277
1278 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
1279 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1280
1281 state = MsiQueryProductStateW(NULL);
1282 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
1283
1284 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
1285 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1286
1287 r = MsiConfigureFeatureW(NULL, NULL, 0);
1288 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1289
1290 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
1291 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1292
1293 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
1294 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1295
1296 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
1297 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
1298
1299 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
1300 * necessary registry values */
1301
1302 /* empty product string */
1303 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
1304 if (r == ERROR_ACCESS_DENIED)
1305 {
1306 skip("Not enough rights to perform tests\n");
1307 return;
1308 }
1309 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1310
1311 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1312 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
1313 if ( r == ERROR_SUCCESS )
1314 {
1315 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
1316 if (!lpData)
1317 skip("Out of memory\n");
1318 else
1319 {
1320 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1321 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1322 }
1323 }
1324
1325 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1326 if (r == ERROR_ACCESS_DENIED)
1327 {
1328 skip("Not enough rights to perform tests\n");
1329 HeapFree(GetProcessHeap(), 0, lpData);
1330 RegCloseKey(hkey);
1331 return;
1332 }
1333 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1334
1335 r = MsiGetProductInfoA("", "", NULL, NULL);
1336 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1337
1338 if (lpData)
1339 {
1340 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
1341 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1342
1343 HeapFree(GetProcessHeap(), 0, lpData);
1344 }
1345 else
1346 {
1347 r = RegDeleteValueA(hkey, NULL);
1348 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1349 }
1350
1351 r = RegCloseKey(hkey);
1352 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1353
1354 /* empty attribute */
1355 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1356 0, NULL, 0, access, NULL, &hkey, NULL);
1357 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1358
1359 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1360 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1361
1362 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
1363 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
1364
1365 r = RegCloseKey(hkey);
1366 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1367
1368 r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1369 access & KEY_WOW64_64KEY);
1370 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1371 }
1372
1373 static void test_getcomponentpath(void)
1374 {
1375 INSTALLSTATE r;
1376 char buffer[0x100];
1377 DWORD sz;
1378
1379 if(!pMsiGetComponentPathA)
1380 return;
1381
1382 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
1383 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1384
1385 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
1386 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1387
1388 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
1389 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1390
1391 sz = sizeof buffer;
1392 buffer[0]=0;
1393 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
1394 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1395
1396 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
1397 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
1398 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1399
1400 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1401 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
1402 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1403
1404 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1405 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
1406 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1407
1408 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
1409 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
1410 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1411 }
1412
1413 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
1414 {
1415 HANDLE file;
1416 DWORD written;
1417
1418 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1419 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1420 WriteFile(file, data, strlen(data), &written, NULL);
1421
1422 if (size)
1423 {
1424 SetFilePointer(file, size, NULL, FILE_BEGIN);
1425 SetEndOfFile(file);
1426 }
1427
1428 CloseHandle(file);
1429 }
1430
1431 static void create_test_files(void)
1432 {
1433 CreateDirectoryA("msitest", NULL);
1434 create_file("msitest\\one.txt", "msitest\\one.txt", 100);
1435 CreateDirectoryA("msitest\\first", NULL);
1436 create_file("msitest\\first\\two.txt", "msitest\\first\\two.txt", 100);
1437 CreateDirectoryA("msitest\\second", NULL);
1438 create_file("msitest\\second\\three.txt", "msitest\\second\\three.txt", 100);
1439
1440 create_file("four.txt", "four.txt", 100);
1441 create_file("five.txt", "five.txt", 100);
1442 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1443
1444 create_file("msitest\\filename", "msitest\\filename", 100);
1445 create_file("msitest\\service.exe", "msitest\\service.exe", 100);
1446
1447 DeleteFileA("four.txt");
1448 DeleteFileA("five.txt");
1449 }
1450
1451 static void delete_test_files(void)
1452 {
1453 DeleteFileA("msitest.msi");
1454 DeleteFileA("msitest.cab");
1455 DeleteFileA("msitest\\second\\three.txt");
1456 DeleteFileA("msitest\\first\\two.txt");
1457 DeleteFileA("msitest\\one.txt");
1458 DeleteFileA("msitest\\service.exe");
1459 DeleteFileA("msitest\\filename");
1460 RemoveDirectoryA("msitest\\second");
1461 RemoveDirectoryA("msitest\\first");
1462 RemoveDirectoryA("msitest");
1463 }
1464
1465 #define HASHSIZE sizeof(MSIFILEHASHINFO)
1466
1467 static const struct
1468 {
1469 LPCSTR data;
1470 DWORD size;
1471 MSIFILEHASHINFO hash;
1472 } hash_data[] =
1473 {
1474 { "", 0,
1475 { HASHSIZE,
1476 { 0, 0, 0, 0 },
1477 },
1478 },
1479
1480 { "abc", 0,
1481 { HASHSIZE,
1482 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
1483 },
1484 },
1485
1486 { "C:\\Program Files\\msitest\\caesar\n", 0,
1487 { HASHSIZE,
1488 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
1489 },
1490 },
1491
1492 { "C:\\Program Files\\msitest\\caesar\n", 500,
1493 { HASHSIZE,
1494 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
1495 },
1496 },
1497 };
1498
1499 static void test_MsiGetFileHash(void)
1500 {
1501 const char name[] = "msitest.bin";
1502 UINT r;
1503 MSIFILEHASHINFO hash;
1504 DWORD i;
1505
1506 if (!pMsiGetFileHashA)
1507 {
1508 win_skip("MsiGetFileHash not implemented\n");
1509 return;
1510 }
1511
1512 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1513
1514 /* szFilePath is NULL */
1515 r = pMsiGetFileHashA(NULL, 0, &hash);
1516 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1517
1518 /* szFilePath is empty */
1519 r = pMsiGetFileHashA("", 0, &hash);
1520 ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
1521 "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
1522
1523 /* szFilePath is nonexistent */
1524 r = pMsiGetFileHashA(name, 0, &hash);
1525 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
1526
1527 /* dwOptions is non-zero */
1528 r = pMsiGetFileHashA(name, 1, &hash);
1529 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1530
1531 /* pHash.dwFileHashInfoSize is not correct */
1532 hash.dwFileHashInfoSize = 0;
1533 r = pMsiGetFileHashA(name, 0, &hash);
1534 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1535
1536 /* pHash is NULL */
1537 r = pMsiGetFileHashA(name, 0, NULL);
1538 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1539
1540 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
1541 {
1542 int ret;
1543
1544 create_file(name, hash_data[i].data, hash_data[i].size);
1545
1546 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
1547 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1548
1549 r = pMsiGetFileHashA(name, 0, &hash);
1550 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1551
1552 ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
1553 ok(!ret, "Hash incorrect\n");
1554
1555 DeleteFileA(name);
1556 }
1557 }
1558
1559 /* copied from dlls/msi/registry.c */
1560 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
1561 {
1562 DWORD i,n=1;
1563 GUID guid;
1564
1565 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
1566 return FALSE;
1567
1568 for(i=0; i<8; i++)
1569 out[7-i] = in[n++];
1570 n++;
1571 for(i=0; i<4; i++)
1572 out[11-i] = in[n++];
1573 n++;
1574 for(i=0; i<4; i++)
1575 out[15-i] = in[n++];
1576 n++;
1577 for(i=0; i<2; i++)
1578 {
1579 out[17+i*2] = in[n++];
1580 out[16+i*2] = in[n++];
1581 }
1582 n++;
1583 for( ; i<8; i++)
1584 {
1585 out[17+i*2] = in[n++];
1586 out[16+i*2] = in[n++];
1587 }
1588 out[32]=0;
1589 return TRUE;
1590 }
1591
1592 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
1593 {
1594 WCHAR guidW[MAX_PATH];
1595 WCHAR squashedW[MAX_PATH];
1596 GUID guid;
1597 HRESULT hr;
1598 int size;
1599
1600 hr = CoCreateGuid(&guid);
1601 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1602
1603 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1604 ok(size == 39, "Expected 39, got %d\n", hr);
1605
1606 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
1607 if (squashed)
1608 {
1609 squash_guid(guidW, squashedW);
1610 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1611 }
1612 }
1613
1614 static char *get_user_sid(void)
1615 {
1616 HANDLE token;
1617 DWORD size = 0;
1618 TOKEN_USER *user;
1619 char *usersid = NULL;
1620
1621 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1622 GetTokenInformation(token, TokenUser, NULL, size, &size);
1623
1624 user = HeapAlloc(GetProcessHeap(), 0, size);
1625 GetTokenInformation(token, TokenUser, user, size, &size);
1626 pConvertSidToStringSidA(user->User.Sid, &usersid);
1627 HeapFree(GetProcessHeap(), 0, user);
1628
1629 CloseHandle(token);
1630 return usersid;
1631 }
1632
1633 static void test_MsiQueryProductState(void)
1634 {
1635 CHAR prodcode[MAX_PATH];
1636 CHAR prod_squashed[MAX_PATH];
1637 CHAR keypath[MAX_PATH*2];
1638 LPSTR usersid;
1639 INSTALLSTATE state;
1640 LONG res;
1641 HKEY userkey, localkey, props;
1642 HKEY prodkey;
1643 DWORD data, error;
1644 REGSAM access = KEY_ALL_ACCESS;
1645
1646 create_test_guid(prodcode, prod_squashed);
1647 usersid = get_user_sid();
1648
1649 if (is_wow64)
1650 access |= KEY_WOW64_64KEY;
1651
1652 /* NULL prodcode */
1653 SetLastError(0xdeadbeef);
1654 state = MsiQueryProductStateA(NULL);
1655 error = GetLastError();
1656 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1657 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1658
1659 /* empty prodcode */
1660 SetLastError(0xdeadbeef);
1661 state = MsiQueryProductStateA("");
1662 error = GetLastError();
1663 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1664 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1665
1666 /* garbage prodcode */
1667 SetLastError(0xdeadbeef);
1668 state = MsiQueryProductStateA("garbage");
1669 error = GetLastError();
1670 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1671 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1672
1673 /* guid without brackets */
1674 SetLastError(0xdeadbeef);
1675 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
1676 error = GetLastError();
1677 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1678 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1679
1680 /* guid with brackets */
1681 SetLastError(0xdeadbeef);
1682 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
1683 error = GetLastError();
1684 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1685 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1686 "expected ERROR_SUCCESS, got %u\n", error);
1687
1688 /* same length as guid, but random */
1689 SetLastError(0xdeadbeef);
1690 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
1691 error = GetLastError();
1692 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1693 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1694
1695 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1696
1697 SetLastError(0xdeadbeef);
1698 state = MsiQueryProductStateA(prodcode);
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 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1705 lstrcatA(keypath, prod_squashed);
1706
1707 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1708 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1709
1710 /* user product key exists */
1711 SetLastError(0xdeadbeef);
1712 state = MsiQueryProductStateA(prodcode);
1713 error = GetLastError();
1714 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1715 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1716 "expected ERROR_SUCCESS, got %u\n", error);
1717
1718 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
1719 lstrcatA(keypath, prodcode);
1720
1721 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1722 if (res == ERROR_ACCESS_DENIED)
1723 {
1724 skip("Not enough rights to perform tests\n");
1725 RegDeleteKeyA(userkey, "");
1726 RegCloseKey(userkey);
1727 LocalFree(usersid);
1728 return;
1729 }
1730 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1731
1732 /* local uninstall key exists */
1733 SetLastError(0xdeadbeef);
1734 state = MsiQueryProductStateA(prodcode);
1735 error = GetLastError();
1736 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1737 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1738 "expected ERROR_SUCCESS, got %u\n", error);
1739
1740 data = 1;
1741 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1742 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1743
1744 /* WindowsInstaller value exists */
1745 SetLastError(0xdeadbeef);
1746 state = MsiQueryProductStateA(prodcode);
1747 error = GetLastError();
1748 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1749 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1750 "expected ERROR_SUCCESS, got %u\n", error);
1751
1752 RegDeleteValueA(localkey, "WindowsInstaller");
1753 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1754
1755 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1756 lstrcatA(keypath, usersid);
1757 lstrcatA(keypath, "\\Products\\");
1758 lstrcatA(keypath, prod_squashed);
1759
1760 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1761 if (res == ERROR_ACCESS_DENIED)
1762 {
1763 skip("Not enough rights to perform tests\n");
1764 RegDeleteKeyA(userkey, "");
1765 RegCloseKey(userkey);
1766 LocalFree(usersid);
1767 return;
1768 }
1769 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1770
1771 /* local product key exists */
1772 SetLastError(0xdeadbeef);
1773 state = MsiQueryProductStateA(prodcode);
1774 error = GetLastError();
1775 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1776 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1777 "expected ERROR_SUCCESS, got %u\n", error);
1778
1779 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1780 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1781
1782 /* install properties key exists */
1783 SetLastError(0xdeadbeef);
1784 state = MsiQueryProductStateA(prodcode);
1785 error = GetLastError();
1786 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1787 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1788 "expected ERROR_SUCCESS, got %u\n", error);
1789
1790 data = 1;
1791 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1792 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1793
1794 /* WindowsInstaller value exists */
1795 SetLastError(0xdeadbeef);
1796 state = MsiQueryProductStateA(prodcode);
1797 error = GetLastError();
1798 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1799 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1800 "expected ERROR_SUCCESS, got %u\n", error);
1801
1802 data = 2;
1803 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1804 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1805
1806 /* WindowsInstaller value is not 1 */
1807 SetLastError(0xdeadbeef);
1808 state = MsiQueryProductStateA(prodcode);
1809 error = GetLastError();
1810 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1811 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1812 "expected ERROR_SUCCESS, got %u\n", error);
1813
1814 RegDeleteKeyA(userkey, "");
1815
1816 /* user product key does not exist */
1817 SetLastError(0xdeadbeef);
1818 state = MsiQueryProductStateA(prodcode);
1819 error = GetLastError();
1820 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1821 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1822 "expected ERROR_SUCCESS, got %u\n", error);
1823
1824 RegDeleteValueA(props, "WindowsInstaller");
1825 delete_key(props, "", access & KEY_WOW64_64KEY);
1826 RegCloseKey(props);
1827 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1828 RegCloseKey(localkey);
1829 RegDeleteKeyA(userkey, "");
1830 RegCloseKey(userkey);
1831
1832 /* MSIINSTALLCONTEXT_USERMANAGED */
1833
1834 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1835 lstrcatA(keypath, usersid);
1836 lstrcatA(keypath, "\\Installer\\Products\\");
1837 lstrcatA(keypath, prod_squashed);
1838
1839 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1841
1842 state = MsiQueryProductStateA(prodcode);
1843 ok(state == INSTALLSTATE_ADVERTISED,
1844 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1845
1846 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1847 lstrcatA(keypath, usersid);
1848 lstrcatA(keypath, "\\Products\\");
1849 lstrcatA(keypath, prod_squashed);
1850
1851 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1852 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1853
1854 state = MsiQueryProductStateA(prodcode);
1855 ok(state == INSTALLSTATE_ADVERTISED,
1856 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1857
1858 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1859 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1860
1861 state = MsiQueryProductStateA(prodcode);
1862 ok(state == INSTALLSTATE_ADVERTISED,
1863 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1864
1865 data = 1;
1866 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1867 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1868
1869 /* WindowsInstaller value exists */
1870 state = MsiQueryProductStateA(prodcode);
1871 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1872
1873 RegDeleteValueA(props, "WindowsInstaller");
1874 delete_key(props, "", access & KEY_WOW64_64KEY);
1875 RegCloseKey(props);
1876 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1877 RegCloseKey(localkey);
1878 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1879 RegCloseKey(prodkey);
1880
1881 /* MSIINSTALLCONTEXT_MACHINE */
1882
1883 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1884 lstrcatA(keypath, prod_squashed);
1885
1886 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1887 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1888
1889 state = MsiQueryProductStateA(prodcode);
1890 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1891
1892 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1893 lstrcatA(keypath, "S-1-5-18\\Products\\");
1894 lstrcatA(keypath, prod_squashed);
1895
1896 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1897 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1898
1899 state = MsiQueryProductStateA(prodcode);
1900 ok(state == INSTALLSTATE_ADVERTISED,
1901 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1902
1903 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1904 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1905
1906 state = MsiQueryProductStateA(prodcode);
1907 ok(state == INSTALLSTATE_ADVERTISED,
1908 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1909
1910 data = 1;
1911 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1912 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1913
1914 /* WindowsInstaller value exists */
1915 state = MsiQueryProductStateA(prodcode);
1916 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1917
1918 RegDeleteValueA(props, "WindowsInstaller");
1919 delete_key(props, "", access & KEY_WOW64_64KEY);
1920 RegCloseKey(props);
1921 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1922 RegCloseKey(localkey);
1923 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1924 RegCloseKey(prodkey);
1925
1926 LocalFree(usersid);
1927 }
1928
1929 static const char table_enc85[] =
1930 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
1931 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
1932 "yz{}~";
1933
1934 /*
1935 * Encodes a base85 guid given a GUID pointer
1936 * Caller should provide a 21 character buffer for the encoded string.
1937 */
1938 static void encode_base85_guid( GUID *guid, LPWSTR str )
1939 {
1940 unsigned int x, *p, i;
1941
1942 p = (unsigned int*) guid;
1943 for( i=0; i<4; i++ )
1944 {
1945 x = p[i];
1946 *str++ = table_enc85[x%85];
1947 x = x/85;
1948 *str++ = table_enc85[x%85];
1949 x = x/85;
1950 *str++ = table_enc85[x%85];
1951 x = x/85;
1952 *str++ = table_enc85[x%85];
1953 x = x/85;
1954 *str++ = table_enc85[x%85];
1955 }
1956 *str = 0;
1957 }
1958
1959 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
1960 {
1961 WCHAR guidW[MAX_PATH];
1962 WCHAR base85W[MAX_PATH];
1963 WCHAR squashedW[MAX_PATH];
1964 GUID guid;
1965 HRESULT hr;
1966 int size;
1967
1968 hr = CoCreateGuid(&guid);
1969 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1970
1971 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1972 ok(size == 39, "Expected 39, got %d\n", hr);
1973
1974 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1975 encode_base85_guid(&guid, base85W);
1976 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1977 squash_guid(guidW, squashedW);
1978 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1979 }
1980
1981 static void test_MsiQueryFeatureState(void)
1982 {
1983 HKEY userkey, localkey, compkey, compkey2;
1984 CHAR prodcode[MAX_PATH];
1985 CHAR prod_squashed[MAX_PATH];
1986 CHAR component[MAX_PATH];
1987 CHAR comp_base85[MAX_PATH];
1988 CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
1989 CHAR keypath[MAX_PATH*2];
1990 INSTALLSTATE state;
1991 LPSTR usersid;
1992 LONG res;
1993 REGSAM access = KEY_ALL_ACCESS;
1994 DWORD error;
1995
1996 create_test_guid(prodcode, prod_squashed);
1997 compose_base85_guid(component, comp_base85, comp_squashed);
1998 compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
1999 usersid = get_user_sid();
2000
2001 if (is_wow64)
2002 access |= KEY_WOW64_64KEY;
2003
2004 /* NULL prodcode */
2005 SetLastError(0xdeadbeef);
2006 state = MsiQueryFeatureStateA(NULL, "feature");
2007 error = GetLastError();
2008 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2009 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2010
2011 /* empty prodcode */
2012 SetLastError(0xdeadbeef);
2013 state = MsiQueryFeatureStateA("", "feature");
2014 error = GetLastError();
2015 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2016 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2017
2018 /* garbage prodcode */
2019 SetLastError(0xdeadbeef);
2020 state = MsiQueryFeatureStateA("garbage", "feature");
2021 error = GetLastError();
2022 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2023 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2024
2025 /* guid without brackets */
2026 SetLastError(0xdeadbeef);
2027 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
2028 error = GetLastError();
2029 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2030 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2031
2032 /* guid with brackets */
2033 SetLastError(0xdeadbeef);
2034 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
2035 error = GetLastError();
2036 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2037 ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
2038 "expected ERROR_SUCCESS, got %u\n", error);
2039
2040 /* same length as guid, but random */
2041 SetLastError(0xdeadbeef);
2042 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
2043 error = GetLastError();
2044 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2045 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2046
2047 /* NULL szFeature */
2048 SetLastError(0xdeadbeef);
2049 state = MsiQueryFeatureStateA(prodcode, NULL);
2050 error = GetLastError();
2051 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2052 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2053
2054 /* empty szFeature */
2055 SetLastError(0xdeadbeef);
2056 state = MsiQueryFeatureStateA(prodcode, "");
2057 error = GetLastError();
2058 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2059 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2060 "expected ERROR_SUCCESS, got %u\n", error);
2061
2062 /* feature key does not exist yet */
2063 SetLastError(0xdeadbeef);
2064 state = MsiQueryFeatureStateA(prodcode, "feature");
2065 error = GetLastError();
2066 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2067 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2068 "expected ERROR_SUCCESS, got %u\n", error);
2069
2070 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2071
2072 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
2073 lstrcatA(keypath, prod_squashed);
2074
2075 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2076 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2077
2078 /* feature key exists */
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 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
2087 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2088
2089 /* feature value exists */
2090 SetLastError(0xdeadbeef);
2091 state = MsiQueryFeatureStateA(prodcode, "feature");
2092 error = GetLastError();
2093 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2094 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2095 "expected ERROR_SUCCESS, got %u\n", error);
2096
2097 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2098 lstrcatA(keypath, usersid);
2099 lstrcatA(keypath, "\\Products\\");
2100 lstrcatA(keypath, prod_squashed);
2101 lstrcatA(keypath, "\\Features");
2102
2103 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2104 if (res == ERROR_ACCESS_DENIED)
2105 {
2106 skip("Not enough rights to perform tests\n");
2107 RegDeleteKeyA(userkey, "");
2108 RegCloseKey(userkey);
2109 LocalFree(usersid);
2110 return;
2111 }
2112 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2113
2114 /* userdata features key exists */
2115 SetLastError(0xdeadbeef);
2116 state = MsiQueryFeatureStateA(prodcode, "feature");
2117 error = GetLastError();
2118 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2119 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2120 "expected ERROR_SUCCESS, got %u\n", error);
2121
2122 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2123 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2124
2125 SetLastError(0xdeadbeef);
2126 state = MsiQueryFeatureStateA(prodcode, "feature");
2127 error = GetLastError();
2128 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2129 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2130 "expected ERROR_SUCCESS, got %u\n", error);
2131
2132 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2133 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2134
2135 SetLastError(0xdeadbeef);
2136 state = MsiQueryFeatureStateA(prodcode, "feature");
2137 error = GetLastError();
2138 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2139 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2140 "expected ERROR_SUCCESS, got %u\n", error);
2141
2142 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2143 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2144
2145 SetLastError(0xdeadbeef);
2146 state = MsiQueryFeatureStateA(prodcode, "feature");
2147 error = GetLastError();
2148 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2149 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2150 "expected ERROR_SUCCESS, got %u\n", error);
2151
2152 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2153 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2154
2155 SetLastError(0xdeadbeef);
2156 state = MsiQueryFeatureStateA(prodcode, "feature");
2157 error = GetLastError();
2158 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2159 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2160 "expected ERROR_SUCCESS, got %u\n", error);
2161
2162 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2163 lstrcatA(keypath, usersid);
2164 lstrcatA(keypath, "\\Components\\");
2165 lstrcatA(keypath, comp_squashed);
2166
2167 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2168 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2169
2170 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2171 lstrcatA(keypath, usersid);
2172 lstrcatA(keypath, "\\Components\\");
2173 lstrcatA(keypath, comp_squashed2);
2174
2175 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2176 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2177
2178 SetLastError(0xdeadbeef);
2179 state = MsiQueryFeatureStateA(prodcode, "feature");
2180 error = GetLastError();
2181 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2182 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2183 "expected ERROR_SUCCESS, got %u\n", error);
2184
2185 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2186 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2187
2188 SetLastError(0xdeadbeef);
2189 state = MsiQueryFeatureStateA(prodcode, "feature");
2190 error = GetLastError();
2191 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2192 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2193 "expected ERROR_SUCCESS, got %u\n", error);
2194
2195 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2196 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2197
2198 SetLastError(0xdeadbeef);
2199 state = MsiQueryFeatureStateA(prodcode, "feature");
2200 error = GetLastError();
2201 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2202 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2203 "expected ERROR_SUCCESS, got %u\n", error);
2204
2205 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2206 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2207
2208 /* INSTALLSTATE_LOCAL */
2209 SetLastError(0xdeadbeef);
2210 state = MsiQueryFeatureStateA(prodcode, "feature");
2211 error = GetLastError();
2212 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2213 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2214 "expected ERROR_SUCCESS, got %u\n", error);
2215
2216 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2217 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2218
2219 /* INSTALLSTATE_SOURCE */
2220 SetLastError(0xdeadbeef);
2221 state = MsiQueryFeatureStateA(prodcode, "feature");
2222 error = GetLastError();
2223 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2224 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2225 "expected ERROR_SUCCESS, got %u\n", error);
2226
2227 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2228 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2229
2230 /* bad INSTALLSTATE_SOURCE */
2231 SetLastError(0xdeadbeef);
2232 state = MsiQueryFeatureStateA(prodcode, "feature");
2233 error = GetLastError();
2234 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2235 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2236 "expected ERROR_SUCCESS, got %u\n", error);
2237
2238 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2239 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2240
2241 /* INSTALLSTATE_SOURCE */
2242 SetLastError(0xdeadbeef);
2243 state = MsiQueryFeatureStateA(prodcode, "feature");
2244 error = GetLastError();
2245 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2246 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2247 "expected ERROR_SUCCESS, got %u\n", error);
2248
2249 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2250 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2251
2252 /* bad INSTALLSTATE_SOURCE */
2253 SetLastError(0xdeadbeef);
2254 state = MsiQueryFeatureStateA(prodcode, "feature");
2255 error = GetLastError();
2256 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2257 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2258 "expected ERROR_SUCCESS, got %u\n", error);
2259
2260 RegDeleteValueA(compkey, prod_squashed);
2261 RegDeleteValueA(compkey2, prod_squashed);
2262 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2263 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2264 RegDeleteValueA(localkey, "feature");
2265 RegDeleteValueA(userkey, "feature");
2266 RegDeleteKeyA(userkey, "");
2267 RegCloseKey(compkey);
2268 RegCloseKey(compkey2);
2269 RegCloseKey(localkey);
2270 RegCloseKey(userkey);
2271
2272 /* MSIINSTALLCONTEXT_USERMANAGED */
2273
2274 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2275 lstrcatA(keypath, usersid);
2276 lstrcatA(keypath, "\\Installer\\Features\\");
2277 lstrcatA(keypath, prod_squashed);
2278
2279 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2280 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2281
2282 /* feature key exists */
2283 state = MsiQueryFeatureStateA(prodcode, "feature");
2284 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2285
2286 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2287 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2288
2289 /* feature value exists */
2290 state = MsiQueryFeatureStateA(prodcode, "feature");
2291 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2292
2293 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2294 lstrcatA(keypath, usersid);
2295 lstrcatA(keypath, "\\Products\\");
2296 lstrcatA(keypath, prod_squashed);
2297 lstrcatA(keypath, "\\Features");
2298
2299 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2301
2302 /* userdata features key exists */
2303 state = MsiQueryFeatureStateA(prodcode, "feature");
2304 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2305
2306 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2307 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2308
2309 state = MsiQueryFeatureStateA(prodcode, "feature");
2310 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2311
2312 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2313 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2314
2315 state = MsiQueryFeatureStateA(prodcode, "feature");
2316 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2317
2318 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2319 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2320
2321 state = MsiQueryFeatureStateA(prodcode, "feature");
2322 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2323
2324 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2325 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2326
2327 state = MsiQueryFeatureStateA(prodcode, "feature");
2328 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2329
2330 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2331 lstrcatA(keypath, usersid);
2332 lstrcatA(keypath, "\\Components\\");
2333 lstrcatA(keypath, comp_squashed);
2334
2335 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2336 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2337
2338 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2339 lstrcatA(keypath, usersid);
2340 lstrcatA(keypath, "\\Components\\");
2341 lstrcatA(keypath, comp_squashed2);
2342
2343 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2344 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2345
2346 state = MsiQueryFeatureStateA(prodcode, "feature");
2347 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2348
2349 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2350 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2351
2352 state = MsiQueryFeatureStateA(prodcode, "feature");
2353 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2354
2355 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2356 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2357
2358 state = MsiQueryFeatureStateA(prodcode, "feature");
2359 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2360
2361 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2362 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2363
2364 state = MsiQueryFeatureStateA(prodcode, "feature");
2365 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2366
2367 RegDeleteValueA(compkey, prod_squashed);
2368 RegDeleteValueA(compkey2, prod_squashed);
2369 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2370 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2371 RegDeleteValueA(localkey, "feature");
2372 RegDeleteValueA(userkey, "feature");
2373 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2374 RegCloseKey(compkey);
2375 RegCloseKey(compkey2);
2376 RegCloseKey(localkey);
2377 RegCloseKey(userkey);
2378
2379 /* MSIINSTALLCONTEXT_MACHINE */
2380
2381 lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
2382 lstrcatA(keypath, prod_squashed);
2383
2384 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2385 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2386
2387 /* feature key exists */
2388 state = MsiQueryFeatureStateA(prodcode, "feature");
2389 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2390
2391 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2392 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2393
2394 /* feature value exists */
2395 state = MsiQueryFeatureStateA(prodcode, "feature");
2396 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2397
2398 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2399 lstrcatA(keypath, "S-1-5-18\\Products\\");
2400 lstrcatA(keypath, prod_squashed);
2401 lstrcatA(keypath, "\\Features");
2402
2403 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2404 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2405
2406 /* userdata features key exists */
2407 state = MsiQueryFeatureStateA(prodcode, "feature");
2408 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2409
2410 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2411 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2412
2413 state = MsiQueryFeatureStateA(prodcode, "feature");
2414 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2415
2416 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2417 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2418
2419 state = MsiQueryFeatureStateA(prodcode, "feature");
2420 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2421
2422 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2424
2425 state = MsiQueryFeatureStateA(prodcode, "feature");
2426 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2427
2428 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2429 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2430
2431 state = MsiQueryFeatureStateA(prodcode, "feature");
2432 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2433
2434 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2435 lstrcatA(keypath, "S-1-5-18\\Components\\");
2436 lstrcatA(keypath, comp_squashed);
2437
2438 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2440
2441 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2442 lstrcatA(keypath, "S-1-5-18\\Components\\");
2443 lstrcatA(keypath, comp_squashed2);
2444
2445 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2446 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2447
2448 state = MsiQueryFeatureStateA(prodcode, "feature");
2449 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2450
2451 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2452 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2453
2454 state = MsiQueryFeatureStateA(prodcode, "feature");
2455 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2456
2457 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2458 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2459
2460 state = MsiQueryFeatureStateA(prodcode, "feature");
2461 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2462
2463 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2464 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2465
2466 state = MsiQueryFeatureStateA(prodcode, "feature");
2467 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2468
2469 RegDeleteValueA(compkey, prod_squashed);
2470 RegDeleteValueA(compkey2, prod_squashed);
2471 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2472 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2473 RegDeleteValueA(localkey, "feature");
2474 RegDeleteValueA(userkey, "feature");
2475 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2476 RegCloseKey(compkey);
2477 RegCloseKey(compkey2);
2478 RegCloseKey(localkey);
2479 RegCloseKey(userkey);
2480 LocalFree(usersid);
2481 }
2482
2483 static void test_MsiQueryComponentState(void)
2484 {
2485 HKEY compkey, prodkey;
2486 CHAR prodcode[MAX_PATH];
2487 CHAR prod_squashed[MAX_PATH];
2488 CHAR component[MAX_PATH];
2489 CHAR comp_base85[MAX_PATH];
2490 CHAR comp_squashed[MAX_PATH];
2491 CHAR keypath[MAX_PATH];
2492 INSTALLSTATE state;
2493 LPSTR usersid;
2494 LONG res;
2495 UINT r;
2496 REGSAM access = KEY_ALL_ACCESS;
2497 DWORD error;
2498
2499 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
2500
2501 if (!pMsiQueryComponentStateA)
2502 {
2503 win_skip("MsiQueryComponentStateA not implemented\n");
2504 return;
2505 }
2506
2507 create_test_guid(prodcode, prod_squashed);
2508 compose_base85_guid(component, comp_base85, comp_squashed);
2509 usersid = get_user_sid();
2510
2511 if (is_wow64)
2512 access |= KEY_WOW64_64KEY;
2513
2514 /* NULL szProductCode */
2515 state = MAGIC_ERROR;
2516 SetLastError(0xdeadbeef);
2517 r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2518 error = GetLastError();
2519 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2520 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2521 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2522
2523 /* empty szProductCode */
2524 state = MAGIC_ERROR;
2525 SetLastError(0xdeadbeef);
2526 r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2527 error = GetLastError();
2528 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2529 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2530 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2531
2532 /* random szProductCode */
2533 state = MAGIC_ERROR;
2534 SetLastError(0xdeadbeef);
2535 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2536 error = GetLastError();
2537 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2538 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2539 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2540
2541 /* GUID-length szProductCode */
2542 state = MAGIC_ERROR;
2543 SetLastError(0xdeadbeef);
2544 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2545 error = GetLastError();
2546 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2547 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2548 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2549
2550 /* GUID-length with brackets */
2551 state = MAGIC_ERROR;
2552 SetLastError(0xdeadbeef);
2553 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2554 error = GetLastError();
2555 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2556 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2557 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2558
2559 /* actual GUID */
2560 state = MAGIC_ERROR;
2561 SetLastError(0xdeadbeef);
2562 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2563 error = GetLastError();
2564 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2565 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2566 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2567
2568 state = MAGIC_ERROR;
2569 SetLastError(0xdeadbeef);
2570 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2571 error = GetLastError();
2572 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2573 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2574 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2575
2576 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2577 lstrcatA(keypath, prod_squashed);
2578
2579 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2580 if (res == ERROR_ACCESS_DENIED)
2581 {
2582 skip("Not enough rights to perform tests\n");
2583 LocalFree(usersid);
2584 return;
2585 }
2586 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2587
2588 state = MAGIC_ERROR;
2589 SetLastError(0xdeadbeef);
2590 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2591 error = GetLastError();
2592 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2593 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2594 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2595
2596 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2597 RegCloseKey(prodkey);
2598
2599 /* create local system product key */
2600 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
2601 lstrcatA(keypath, prod_squashed);
2602 lstrcatA(keypath, "\\InstallProperties");
2603
2604 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2605 if (res == ERROR_ACCESS_DENIED)
2606 {
2607 skip("Not enough rights to perform tests\n");
2608 LocalFree(usersid);
2609 return;
2610 }
2611 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2612
2613 /* local system product key exists */
2614 state = MAGIC_ERROR;
2615 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2616 error = GetLastError();
2617 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2618 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2619 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2620
2621 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2622 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2623
2624 /* LocalPackage value exists */
2625 state = MAGIC_ERROR;
2626 SetLastError(0xdeadbeef);
2627 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2628 error = GetLastError();
2629 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2630 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2631 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2632
2633 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
2634 lstrcatA(keypath, comp_squashed);
2635
2636 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2637 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2638
2639 /* component key exists */
2640 state = MAGIC_ERROR;
2641 SetLastError(0xdeadbeef);
2642 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2643 error = GetLastError();
2644 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2645 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2646 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2647
2648 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2649 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2650
2651 /* component\product exists */
2652 state = MAGIC_ERROR;
2653 SetLastError(0xdeadbeef);
2654 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2655 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2656 error = GetLastError();
2657 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2658 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2659 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2660
2661 /* NULL component, product exists */
2662 state = MAGIC_ERROR;
2663 SetLastError(0xdeadbeef);
2664 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
2665 error = GetLastError();
2666 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2667 ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
2668 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2669
2670 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2671 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2672
2673 /* INSTALLSTATE_LOCAL */
2674 state = MAGIC_ERROR;
2675 SetLastError(0xdeadbeef);
2676 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2677 error = GetLastError();
2678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2679 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2680 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2681
2682 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2684
2685 /* INSTALLSTATE_SOURCE */
2686 state = MAGIC_ERROR;
2687 SetLastError(0xdeadbeef);
2688 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2689 error = GetLastError();
2690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2691 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2692 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2693
2694 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2695 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2696
2697 /* bad INSTALLSTATE_SOURCE */
2698 state = MAGIC_ERROR;
2699 SetLastError(0xdeadbeef);
2700 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2701 error = GetLastError();
2702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2703 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2704 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2705
2706 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2707 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2708
2709 /* INSTALLSTATE_SOURCE */
2710 state = MAGIC_ERROR;
2711 SetLastError(0xdeadbeef);
2712 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2713 error = GetLastError();
2714 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2715 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2716 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2717
2718 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
2719 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2720
2721 /* registry component */
2722 state = MAGIC_ERROR;
2723 SetLastError(0xdeadbeef);
2724 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2725 error = GetLastError();
2726 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2727 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2728 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2729
2730 RegDeleteValueA(prodkey, "LocalPackage");
2731 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2732 RegDeleteValueA(compkey, prod_squashed);
2733 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2734 RegCloseKey(prodkey);
2735 RegCloseKey(compkey);
2736
2737 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2738
2739 state = MAGIC_ERROR;
2740 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2741 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2742 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2743
2744 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2745 lstrcatA(keypath, prod_squashed);
2746
2747 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2748 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2749
2750 state = MAGIC_ERROR;
2751 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2752 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2753 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2754
2755 RegDeleteKeyA(prodkey, "");
2756 RegCloseKey(prodkey);
2757
2758 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2759 lstrcatA(keypath, usersid);
2760 lstrcatA(keypath, "\\Products\\");
2761 lstrcatA(keypath, prod_squashed);
2762 lstrcatA(keypath, "\\InstallProperties");
2763
2764 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2765 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2766
2767 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2768 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2769
2770 RegCloseKey(prodkey);
2771
2772 state = MAGIC_ERROR;
2773 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2774 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2775 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2776
2777 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2778 lstrcatA(keypath, usersid);
2779 lstrcatA(keypath, "\\Components\\");
2780 lstrcatA(keypath, comp_squashed);
2781
2782 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2783 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2784
2785 /* component key exists */
2786 state = MAGIC_ERROR;
2787 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2788 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2789 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2790
2791 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2792 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2793
2794 /* component\product exists */
2795 state = MAGIC_ERROR;
2796 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2798 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2799 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2800
2801 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2802 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2803
2804 state = MAGIC_ERROR;
2805 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2806 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2807 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2808
2809 /* MSIINSTALLCONTEXT_USERMANAGED */
2810
2811 state = MAGIC_ERROR;
2812 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2813 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2814 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2815
2816 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2817 lstrcatA(keypath, prod_squashed);
2818
2819 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2820 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2821
2822 state = MAGIC_ERROR;
2823 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2824 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2825 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2826
2827 RegDeleteKeyA(prodkey, "");
2828 RegCloseKey(prodkey);
2829
2830 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2831 lstrcatA(keypath, usersid);
2832 lstrcatA(keypath, "\\Installer\\Products\\");
2833 lstrcatA(keypath, prod_squashed);
2834
2835 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2836 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2837
2838 state = MAGIC_ERROR;
2839 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2840 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2841 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2842
2843 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2844 RegCloseKey(prodkey);
2845
2846 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2847 lstrcatA(keypath, usersid);
2848 lstrcatA(keypath, "\\Products\\");
2849 lstrcatA(keypath, prod_squashed);
2850 lstrcatA(keypath, "\\InstallProperties");
2851
2852 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2853 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2854
2855 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2857
2858 state = MAGIC_ERROR;
2859 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2861 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2862
2863 RegDeleteValueA(prodkey, "LocalPackage");
2864 RegDeleteValueA(prodkey, "ManagedLocalPackage");
2865 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2866 RegDeleteValueA(compkey, prod_squashed);
2867 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2868 RegCloseKey(prodkey);
2869 RegCloseKey(compkey);
2870 LocalFree(usersid);
2871 }
2872
2873 static void test_MsiGetComponentPath(void)
2874 {
2875 HKEY compkey, prodkey, installprop;
2876 CHAR prodcode[MAX_PATH];
2877 CHAR prod_squashed[MAX_PATH];
2878 CHAR component[MAX_PATH];
2879 CHAR comp_base85[MAX_PATH];
2880 CHAR comp_squashed[MAX_PATH];
2881 CHAR keypath[MAX_PATH];
2882 CHAR path[MAX_PATH];
2883 INSTALLSTATE state;
2884 LPSTR usersid;
2885 DWORD size, val;
2886 REGSAM access = KEY_ALL_ACCESS;
2887 LONG res;
2888
2889 create_test_guid(prodcode, prod_squashed);
2890 compose_base85_guid(component, comp_base85, comp_squashed);
2891 usersid = get_user_sid();
2892
2893 if (is_wow64)
2894 access |= KEY_WOW64_64KEY;
2895
2896 /* NULL szProduct */
2897 size = MAX_PATH;
2898 state = MsiGetComponentPathA(NULL, component, path, &size);
2899 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2900 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2901
2902 /* NULL szComponent */
2903 size = MAX_PATH;
2904 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
2905 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2906 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2907
2908 size = MAX_PATH;
2909 state = MsiLocateComponentA(NULL, path, &size);
2910 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2911 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2912
2913 /* NULL lpPathBuf */
2914 size = MAX_PATH;
2915 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
2916 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2917 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2918
2919 size = MAX_PATH;
2920 state = MsiLocateComponentA(component, NULL, &size);
2921 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2922 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2923
2924 /* NULL pcchBuf */
2925 size = MAX_PATH;
2926 state = MsiGetComponentPathA(prodcode, component, path, NULL);
2927 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2928 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2929
2930 size = MAX_PATH;
2931 state = MsiLocateComponentA(component, path, NULL);
2932 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2933 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2934
2935 /* all params valid */
2936 size = MAX_PATH;
2937 state = MsiGetComponentPathA(prodcode, component, path, &size);
2938 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2939 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2940
2941 size = MAX_PATH;
2942 state = MsiLocateComponentA(component, path, &size);
2943 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2944 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2945
2946 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2947 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2948 lstrcatA(keypath, comp_squashed);
2949
2950 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2951 if (res == ERROR_ACCESS_DENIED)
2952 {
2953 skip("Not enough rights to perform tests\n");
2954 LocalFree(usersid);
2955 return;
2956 }
2957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2958
2959 /* local system component key exists */
2960 size = MAX_PATH;
2961 state = MsiGetComponentPathA(prodcode, component, path, &size);
2962 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2963 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2964
2965 size = MAX_PATH;
2966 state = MsiLocateComponentA(component, path, &size);
2967 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2968 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2969
2970 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2971 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2972
2973 /* product value exists */
2974 path[0] = 0;
2975 size = MAX_PATH;
2976 state = MsiGetComponentPathA(prodcode, component, path, &size);
2977 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2978 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2979 ok(size == 10, "Expected 10, got %d\n", size);
2980
2981 path[0] = 0;
2982 size = MAX_PATH;
2983 state = MsiLocateComponentA(component, path, &size);
2984 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2985 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2986 ok(size == 10, "Expected 10, got %d\n", size);
2987
2988 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2989 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2990 lstrcatA(keypath, prod_squashed);
2991 lstrcatA(keypath, "\\InstallProperties");
2992
2993 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2994 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2995
2996 val = 1;
2997 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2998 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2999
3000 /* install properties key exists */
3001 path[0] = 0;
3002 size = MAX_PATH;
3003 state = MsiGetComponentPathA(prodcode, component, path, &size);
3004 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3005 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3006 ok(size == 10, "Expected 10, got %d\n", size);
3007
3008 path[0] = 0;
3009 size = MAX_PATH;
3010 state = MsiLocateComponentA(component, path, &size);
3011 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3012 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3013 ok(size == 10, "Expected 10, got %d\n", size);
3014
3015 create_file("C:\\imapath", "C:\\imapath", 11);
3016
3017 /* file exists */
3018 path[0] = 'a';
3019 size = 0;
3020 state = MsiGetComponentPathA(prodcode, component, path, &size);
3021 ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
3022 ok(path[0] == 'a', "got %s\n", path);
3023 ok(size == 10, "Expected 10, got %d\n", size);
3024
3025 path[0] = 0;
3026 size = MAX_PATH;
3027 state = MsiGetComponentPathA(prodcode, component, path, &size);
3028 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3029 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3030 ok(size == 10, "Expected 10, got %d\n", size);
3031
3032 size = 0;
3033 path[0] = 'a';
3034 state = MsiLocateComponentA(component, path, &size);
3035 ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
3036 ok(path[0] == 'a', "got %s\n", path);
3037 ok(size == 10, "Expected 10, got %d\n", size);
3038
3039 path[0] = 0;
3040 size = MAX_PATH;
3041 state = MsiLocateComponentA(component, path, &size);
3042 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3043 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3044 ok(size == 10, "Expected 10, got %d\n", size);
3045
3046 RegDeleteValueA(compkey, prod_squashed);
3047 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3048 RegDeleteValueA(installprop, "WindowsInstaller");
3049 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3050 RegCloseKey(compkey);
3051 RegCloseKey(installprop);
3052 DeleteFileA("C:\\imapath");
3053
3054 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3055 lstrcatA(keypath, "Installer\\UserData\\");
3056 lstrcatA(keypath, usersid);
3057 lstrcatA(keypath, "\\Components\\");
3058 lstrcatA(keypath, comp_squashed);
3059
3060 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3061 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3062
3063 /* user managed component key exists */
3064 size = MAX_PATH;
3065 state = MsiGetComponentPathA(prodcode, component, path, &size);
3066 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3067 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3068
3069 size = MAX_PATH;
3070 state = MsiLocateComponentA(component, path, &size);
3071 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3072 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3073
3074 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3075 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3076
3077 /* product value exists */
3078 path[0] = 0;
3079 size = MAX_PATH;
3080 state = MsiGetComponentPathA(prodcode, component, path, &size);
3081 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3082 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3083 ok(size == 10, "Expected 10, got %d\n", size);
3084
3085 path[0] = 0;
3086 size = MAX_PATH;
3087 state = MsiLocateComponentA(component, path, &size);
3088 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3089 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3090 ok(size == 10, "Expected 10, got %d\n", size);
3091
3092 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3093 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3094 lstrcatA(keypath, prod_squashed);
3095 lstrcatA(keypath, "\\InstallProperties");
3096
3097 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3098 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3099
3100 val = 1;
3101 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3103
3104 /* install properties key exists */
3105 path[0] = 0;
3106 size = MAX_PATH;
3107 state = MsiGetComponentPathA(prodcode, component, path, &size);
3108 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3109 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3110 ok(size == 10, "Expected 10, got %d\n", size);
3111
3112 path[0] = 0;
3113 size = MAX_PATH;
3114 state = MsiLocateComponentA(component, path, &size);
3115 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3116 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3117 ok(size == 10, "Expected 10, got %d\n", size);
3118
3119 create_file("C:\\imapath", "C:\\imapath", 11);
3120
3121 /* file exists */
3122 path[0] = 0;
3123 size = MAX_PATH;
3124 state = MsiGetComponentPathA(prodcode, component, path, &size);
3125 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3126 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3127 ok(size == 10, "Expected 10, got %d\n", size);
3128
3129 path[0] = 0;
3130 size = MAX_PATH;
3131 state = MsiLocateComponentA(component, path, &size);
3132 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3133 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3134 ok(size == 10, "Expected 10, got %d\n", size);
3135
3136 RegDeleteValueA(compkey, prod_squashed);
3137 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3138 RegDeleteValueA(installprop, "WindowsInstaller");
3139 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3140 RegCloseKey(compkey);
3141 RegCloseKey(installprop);
3142 DeleteFileA("C:\\imapath");
3143
3144 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3145 lstrcatA(keypath, "Installer\\Managed\\");
3146 lstrcatA(keypath, usersid);
3147 lstrcatA(keypath, "\\Installer\\Products\\");
3148 lstrcatA(keypath, prod_squashed);
3149
3150 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3151 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3152
3153 /* user managed product key exists */
3154 size = MAX_PATH;
3155 state = MsiGetComponentPathA(prodcode, component, path, &size);
3156 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3157 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3158
3159 size = MAX_PATH;
3160 state = MsiLocateComponentA(component, path, &size);
3161 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3162 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3163
3164 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3165 lstrcatA(keypath, "Installer\\UserData\\");
3166 lstrcatA(keypath, usersid);
3167 lstrcatA(keypath, "\\Components\\");
3168 lstrcatA(keypath, comp_squashed);
3169
3170 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3171 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3172
3173 /* user managed component key exists */
3174 size = MAX_PATH;
3175 state = MsiGetComponentPathA(prodcode, component, path, &size);
3176 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3177 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3178
3179 size = MAX_PATH;
3180 state = MsiLocateComponentA(component, path, &size);
3181 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3182 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3183
3184 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3185 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3186
3187 /* product value exists */
3188 path[0] = 0;
3189 size = MAX_PATH;
3190 state = MsiGetComponentPathA(prodcode, component, path, &size);
3191 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3192 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3193 ok(size == 10, "Expected 10, got %d\n", size);
3194
3195 path[0] = 0;
3196 size = MAX_PATH;
3197 state = MsiLocateComponentA(component, path, &size);
3198 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3199 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3200 ok(size == 10, "Expected 10, got %d\n", size);
3201
3202 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3203 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3204 lstrcatA(keypath, prod_squashed);
3205 lstrcatA(keypath, "\\InstallProperties");
3206
3207 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3208 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3209
3210 val = 1;
3211 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3213
3214 /* install properties key exists */
3215 path[0] = 0;
3216 size = MAX_PATH;
3217 state = MsiGetComponentPathA(prodcode, component, path, &size);
3218 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3219 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3220 ok(size == 10, "Expected 10, got %d\n", size);
3221
3222 path[0] = 0;
3223 size = MAX_PATH;
3224 state = MsiLocateComponentA(component, path, &size);
3225 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3226 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3227 ok(size == 10, "Expected 10, got %d\n", size);
3228
3229 create_file("C:\\imapath", "C:\\imapath", 11);
3230
3231 /* file exists */
3232 path[0] = 0;
3233 size = MAX_PATH;
3234 state = MsiGetComponentPathA(prodcode, component, path, &size);
3235 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3236 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3237 ok(size == 10, "Expected 10, got %d\n", size);
3238
3239 path[0] = 0;
3240 size = MAX_PATH;
3241 state = MsiLocateComponentA(component, path, &size);
3242 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3243 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3244 ok(size == 10, "Expected 10, got %d\n", size);
3245
3246 RegDeleteValueA(compkey, prod_squashed);
3247 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3248 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3249 RegDeleteValueA(installprop, "WindowsInstaller");
3250 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3251 RegCloseKey(prodkey);
3252 RegCloseKey(compkey);
3253 RegCloseKey(installprop);
3254 DeleteFileA("C:\\imapath");
3255
3256 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3257 lstrcatA(keypath, prod_squashed);
3258
3259 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3260 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3261
3262 /* user unmanaged product key exists */
3263 size = MAX_PATH;
3264 state = MsiGetComponentPathA(prodcode, component, path, &size);
3265 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3266 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3267
3268 size = MAX_PATH;
3269 state = MsiLocateComponentA(component, path, &size);
3270 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3271 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3272
3273 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3274 lstrcatA(keypath, "Installer\\UserData\\");
3275 lstrcatA(keypath, usersid);
3276 lstrcatA(keypath, "\\Components\\");
3277 lstrcatA(keypath, comp_squashed);
3278
3279 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3280 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3281
3282 /* user unmanaged component key exists */
3283 size = MAX_PATH;
3284 state = MsiGetComponentPathA(prodcode, component, path, &size);
3285 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3286 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3287
3288 size = MAX_PATH;
3289 state = MsiLocateComponentA(component, path, &size);
3290 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3291 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3292
3293 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3294 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3295
3296 /* product value exists */
3297 path[0] = 0;
3298 size = MAX_PATH;
3299 state = MsiGetComponentPathA(prodcode, component, path, &size);
3300 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3301 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3302 ok(size == 10, "Expected 10, got %d\n", size);
3303
3304 path[0] = 0;
3305 size = MAX_PATH;
3306 state = MsiLocateComponentA(component, path, &size);
3307 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3308 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3309 ok(size == 10, "Expected 10, got %d\n", size);
3310
3311 create_file("C:\\imapath", "C:\\imapath", 11);
3312
3313 /* file exists */
3314 path[0] = 0;
3315 size = MAX_PATH;
3316 state = MsiGetComponentPathA(prodcode, component, path, &size);
3317 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3318 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3319 ok(size == 10, "Expected 10, got %d\n", size);
3320
3321 path[0] = 0;
3322 size = MAX_PATH;
3323 state = MsiLocateComponentA(component, path, &size);
3324 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3325 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3326 ok(size == 10, "Expected 10, got %d\n", size);
3327
3328 RegDeleteValueA(compkey, prod_squashed);
3329 RegDeleteKeyA(prodkey, "");
3330 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3331 RegCloseKey(prodkey);
3332 RegCloseKey(compkey);
3333 DeleteFileA("C:\\imapath");
3334
3335 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3336 lstrcatA(keypath, prod_squashed);
3337
3338 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3339 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3340
3341 /* local classes product key exists */
3342 size = MAX_PATH;
3343 state = MsiGetComponentPathA(prodcode, component, path, &size);
3344 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3345 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3346
3347 size = MAX_PATH;
3348 state = MsiLocateComponentA(component, path, &size);
3349 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3350 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3351
3352 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3353 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3354 lstrcatA(keypath, comp_squashed);
3355
3356 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3357 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3358
3359 /* local user component key exists */
3360 size = MAX_PATH;
3361 state = MsiGetComponentPathA(prodcode, component, path, &size);
3362 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3363 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3364
3365 size = MAX_PATH;
3366 state = MsiLocateComponentA(component, path, &size);
3367 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3368 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3369
3370 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3372
3373 /* product value exists */
3374 path[0] = 0;
3375 size = MAX_PATH;
3376 state = MsiGetComponentPathA(prodcode, component, path, &size);
3377 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3378 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3379 ok(size == 10, "Expected 10, got %d\n", size);
3380
3381 path[0] = 0;
3382 size = MAX_PATH;
3383 state = MsiLocateComponentA(component, path, &size);
3384 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3385 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3386 ok(size == 10, "Expected 10, got %d\n", size);
3387
3388 create_file("C:\\imapath", "C:\\imapath", 11);
3389
3390 /* file exists */
3391 path[0] = 0;
3392 size = MAX_PATH;
3393 state = MsiGetComponentPathA(prodcode, component, path, &size);
3394 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3395 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3396 ok(size == 10, "Expected 10, got %d\n", size);
3397
3398 path[0] = 0;
3399 size = MAX_PATH;
3400 state = MsiLocateComponentA(component, path, &size);
3401 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3402 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3403 ok(size == 10, "Expected 10, got %d\n", size);
3404
3405 RegDeleteValueA(compkey, prod_squashed);
3406 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3407 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3408 RegCloseKey(prodkey);
3409 RegCloseKey(compkey);
3410 DeleteFileA("C:\\imapath");
3411 LocalFree(usersid);
3412 }
3413
3414 static void test_MsiProvideComponent(void)
3415 {
3416 static const WCHAR sourcedirW[] =
3417 {'s','o','u','r','c','e','d','i','r',0};
3418 static const WCHAR productW[] =
3419 {'{','3','8','8','4','7','3','3','8','-','1','B','B','C','-','4','1','0','4','-',
3420 '8','1','A','C','-','2','F','A','A','C','7','E','C','D','D','C','D','}',0};
3421 static const WCHAR componentW[] =
3422 {'{','D','D','4','2','2','F','9','2','-','3','E','D','8','-','4','9','B','5','-',
3423 'A','0','B','7','-','F','2','6','6','F','9','8','3','5','7','D','F','}',0};
3424 INSTALLSTATE state;
3425 char buf[0x100];
3426 WCHAR bufW[0x100];
3427 DWORD len, len2;
3428 UINT r;
3429
3430 if (is_process_limited())
3431 {
3432 skip("process is limited\n");
3433 return;
3434 }
3435
3436 create_test_files();
3437 create_file("msitest\\sourcedir.txt", "msitest\\sourcedir.txt", 1000);
3438 create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
3439
3440 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3441
3442 buf[0] = 0;
3443 len = sizeof(buf);
3444 r = pMsiProvideComponentA("{90120000-0070-0000-0000-4000000FF1CE}",
3445 "{17961602-C4E2-482E-800A-DF6E627549CF}",
3446 "ProductFiles", INSTALLMODE_NODETECTION, buf, &len);
3447 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
3448
3449 r = MsiInstallProductA(msifile, NULL);
3450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3451
3452 state = MsiQueryFeatureStateA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir");
3453 ok(state == INSTALLSTATE_LOCAL, "got %d\n", state);
3454
3455 buf[0] = 0;
3456 len = sizeof(buf);
3457 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3458 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3459 INSTALLMODE_NODETECTION, buf, &len);
3460 ok(r == ERROR_SUCCESS, "got %u\n", r);
3461 ok(buf[0], "empty path\n");
3462 ok(len == lstrlenA(buf), "got %u\n", len);
3463
3464 len2 = 0;
3465 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3466 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3467 INSTALLMODE_NODETECTION, NULL, &len2);
3468 ok(r == ERROR_SUCCESS, "got %u\n", r);
3469 ok(len2 == len, "got %u\n", len2);
3470
3471 len2 = 0;
3472 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3473 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3474 INSTALLMODE_NODETECTION, buf, &len2);
3475 ok(r == ERROR_MORE_DATA, "got %u\n", r);
3476 ok(len2 == len, "got %u\n", len2);
3477
3478 /* wide version */
3479
3480 bufW[0] = 0;
3481 len = sizeof(buf);
3482 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3483 INSTALLMODE_NODETECTION, bufW, &len);
3484 ok(r == ERROR_SUCCESS, "got %u\n", r);
3485 ok(bufW[0], "empty path\n");
3486 ok(len == lstrlenW(bufW), "got %u\n", len);
3487
3488 len2 = 0;
3489 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3490 INSTALLMODE_NODETECTION, NULL, &len2);
3491 ok(r == ERROR_SUCCESS, "got %u\n", r);
3492 ok(len2 == len, "got %u\n", len2);
3493
3494 len2 = 0;
3495 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3496 INSTALLMODE_NODETECTION, bufW, &len2);
3497 ok(r == ERROR_MORE_DATA, "got %u\n", r);
3498 ok(len2 == len, "got %u\n", len2);
3499
3500 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3501 ok(r == ERROR_SUCCESS, "got %u\n", r);
3502
3503 DeleteFileA("msitest\\sourcedir.txt");
3504 delete_test_files();
3505 DeleteFileA(msifile);
3506 }
3507
3508 static void test_MsiGetProductCode(void)
3509 {
3510 HKEY compkey, prodkey;
3511 CHAR prodcode[MAX_PATH];
3512 CHAR prod_squashed[MAX_PATH];
3513 CHAR prodcode2[MAX_PATH];
3514 CHAR prod2_squashed[MAX_PATH];
3515 CHAR component[MAX_PATH];
3516 CHAR comp_base85[MAX_PATH];
3517 CHAR comp_squashed[MAX_PATH];
3518 CHAR keypath[MAX_PATH];
3519 CHAR product[MAX_PATH];
3520 LPSTR usersid;
3521 LONG res;
3522 UINT r;
3523 REGSAM access = KEY_ALL_ACCESS;
3524
3525 create_test_guid(prodcode, prod_squashed);
3526 create_test_guid(prodcode2, prod2_squashed);
3527 compose_base85_guid(component, comp_base85, comp_squashed);
3528 usersid = get_user_sid();
3529
3530 if (is_wow64)
3531 access |= KEY_WOW64_64KEY;
3532
3533 /* szComponent is NULL */
3534 lstrcpyA(product, "prod");
3535 r = MsiGetProductCodeA(NULL, product);
3536 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3537 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3538
3539 /* szComponent is empty */
3540 lstrcpyA(product, "prod");
3541 r = MsiGetProductCodeA("", product);
3542 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3543 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3544
3545 /* garbage szComponent */
3546 lstrcpyA(product, "prod");
3547 r = MsiGetProductCodeA("garbage", product);
3548 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3549 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3550
3551 /* guid without brackets */
3552 lstrcpyA(product, "prod");
3553 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
3554 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3555 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3556
3557 /* guid with brackets */
3558 lstrcpyA(product, "prod");
3559 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
3560 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3561 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3562
3563 /* same length as guid, but random */
3564 lstrcpyA(product, "prod");
3565 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
3566 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3567 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3568
3569 /* all params correct, szComponent not published */
3570 lstrcpyA(product, "prod");
3571 r = MsiGetProductCodeA(component, product);
3572 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3573 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3574
3575 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3576 lstrcatA(keypath, "Installer\\UserData\\");
3577 lstrcatA(keypath, usersid);
3578 lstrcatA(keypath, "\\Components\\");
3579 lstrcatA(keypath, comp_squashed);
3580
3581 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3582 if (res == ERROR_ACCESS_DENIED)
3583 {
3584 skip("Not enough rights to perform tests\n");
3585 LocalFree(usersid);
3586 return;
3587 }
3588 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3589
3590 /* user unmanaged component key exists */
3591 lstrcpyA(product, "prod");
3592 r = MsiGetProductCodeA(component, product);
3593 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3594 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3595
3596 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3597 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3598
3599 /* product value exists */
3600 lstrcpyA(product, "prod");
3601 r = MsiGetProductCodeA(component, product);
3602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3603 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3604
3605 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3606 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3607
3608 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3609 lstrcatA(keypath, "Installer\\Managed\\");
3610 lstrcatA(keypath, usersid);
3611 lstrcatA(keypath, "\\Installer\\Products\\");
3612 lstrcatA(keypath, prod_squashed);
3613
3614 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3615 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3616
3617 /* user managed product key of first product exists */
3618 lstrcpyA(product, "prod");
3619 r = MsiGetProductCodeA(component, product);
3620 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3621 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3622
3623 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3624 RegCloseKey(prodkey);
3625
3626 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3627 lstrcatA(keypath, prod_squashed);
3628
3629 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3630 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3631
3632 /* user unmanaged product key exists */
3633 lstrcpyA(product, "prod");
3634 r = MsiGetProductCodeA(component, product);
3635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3636 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3637
3638 RegDeleteKeyA(prodkey, "");
3639 RegCloseKey(prodkey);
3640
3641 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3642 lstrcatA(keypath, prod_squashed);
3643
3644 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3645 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3646
3647 /* local classes product key exists */
3648 lstrcpyA(product, "prod");
3649 r = MsiGetProductCodeA(component, product);
3650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3651 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3652
3653 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3654 RegCloseKey(prodkey);
3655
3656 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3657 lstrcatA(keypath, "Installer\\Managed\\");
3658 lstrcatA(keypath, usersid);
3659 lstrcatA(keypath, "\\Installer\\Products\\");
3660 lstrcatA(keypath, prod2_squashed);
3661
3662 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3664
3665 /* user managed product key of second product exists */
3666 lstrcpyA(product, "prod");
3667 r = MsiGetProductCodeA(component, product);
3668 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3669 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3670
3671 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3672 RegCloseKey(prodkey);
3673 RegDeleteValueA(compkey, prod_squashed);
3674 RegDeleteValueA(compkey, prod2_squashed);
3675 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3676 RegCloseKey(compkey);
3677
3678 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3679 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3680 lstrcatA(keypath, comp_squashed);
3681
3682 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3684
3685 /* local user component key exists */
3686 lstrcpyA(product, "prod");
3687 r = MsiGetProductCodeA(component, product);
3688 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3689 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3690
3691 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3692 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3693
3694 /* product value exists */
3695 lstrcpyA(product, "prod");
3696 r = MsiGetProductCodeA(component, product);
3697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3698 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3699
3700 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3701 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3702
3703 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3704 lstrcatA(keypath, "Installer\\Managed\\");
3705 lstrcatA(keypath, usersid);
3706 lstrcatA(keypath, "\\Installer\\Products\\");
3707 lstrcatA(keypath, prod_squashed);
3708
3709 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3710 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3711
3712 /* user managed product key of first product exists */
3713 lstrcpyA(product, "prod");
3714 r = MsiGetProductCodeA(component, product);
3715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3716 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3717
3718 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3719 RegCloseKey(prodkey);
3720
3721 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3722 lstrcatA(keypath, prod_squashed);
3723
3724 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3725 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3726
3727 /* user unmanaged product key exists */
3728 lstrcpyA(product, "prod");
3729 r = MsiGetProductCodeA(component, product);
3730 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3731 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3732
3733 RegDeleteKeyA(prodkey, "");
3734 RegCloseKey(prodkey);
3735
3736 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3737 lstrcatA(keypath, prod_squashed);
3738
3739 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3740 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3741
3742 /* local classes product key exists */
3743 lstrcpyA(product, "prod");
3744 r = MsiGetProductCodeA(component, product);
3745 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3746 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3747
3748 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3749 RegCloseKey(prodkey);
3750
3751 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3752 lstrcatA(keypath, "Installer\\Managed\\");
3753 lstrcatA(keypath, usersid);
3754 lstrcatA(keypath, "\\Installer\\Products\\");
3755 lstrcatA(keypath, prod2_squashed);
3756
3757 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3758 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3759
3760 /* user managed product key of second product exists */
3761 lstrcpyA(product, "prod");
3762 r = MsiGetProductCodeA(component, product);
3763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3764 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3765
3766 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3767 RegCloseKey(prodkey);
3768 RegDeleteValueA(compkey, prod_squashed);
3769 RegDeleteValueA(compkey, prod2_squashed);
3770 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3771 RegCloseKey(compkey);
3772 LocalFree(usersid);
3773 }
3774
3775 static void test_MsiEnumClients(void)
3776 {
3777 HKEY compkey;
3778 CHAR prodcode[MAX_PATH];
3779 CHAR prod_squashed[MAX_PATH];
3780 CHAR prodcode2[MAX_PATH];
3781 CHAR prod2_squashed[MAX_PATH];
3782 CHAR component[MAX_PATH];
3783 CHAR comp_base85[MAX_PATH];
3784 CHAR comp_squashed[MAX_PATH];
3785 CHAR product[MAX_PATH];
3786 CHAR keypath[MAX_PATH];
3787 LPSTR usersid;
3788 LONG res;
3789 UINT r;
3790 REGSAM access = KEY_ALL_ACCESS;
3791
3792 create_test_guid(prodcode, prod_squashed);
3793 create_test_guid(prodcode2, prod2_squashed);
3794 compose_base85_guid(component, comp_base85, comp_squashed);
3795 usersid = get_user_sid();
3796
3797 if (is_wow64)
3798 access |= KEY_WOW64_64KEY;
3799
3800 /* NULL szComponent */
3801 product[0] = '\0';
3802 r = MsiEnumClientsA(NULL, 0, product);
3803 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3804 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3805
3806 /* empty szComponent */
3807 product[0] = '\0';
3808 r = MsiEnumClientsA("", 0, product);
3809 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3810 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3811
3812 /* NULL lpProductBuf */
3813 r = MsiEnumClientsA(component, 0, NULL);
3814 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3815
3816 /* all params correct, component missing */
3817 product[0] = '\0';
3818 r = MsiEnumClientsA(component, 0, product);
3819 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3820 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3821
3822 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3823 lstrcatA(keypath, "Installer\\UserData\\");
3824 lstrcatA(keypath, usersid);
3825 lstrcatA(keypath, "\\Components\\");
3826 lstrcatA(keypath, comp_squashed);
3827
3828 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3829 if (res == ERROR_ACCESS_DENIED)
3830 {
3831 skip("Not enough rights to perform tests\n");
3832 LocalFree(usersid);
3833 return;
3834 }
3835 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3836
3837 /* user unmanaged component key exists */
3838 product[0] = '\0';
3839 r = MsiEnumClientsA(component, 0, product);
3840 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3841 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3842
3843 /* index > 0, no products exist */
3844 product[0] = '\0';
3845 r = MsiEnumClientsA(component, 1, product);
3846 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3847 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3848
3849 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3850 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3851
3852 /* product value exists */
3853 r = MsiEnumClientsA(component, 0, product);
3854 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3855 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3856
3857 /* try index 0 again */
3858 product[0] = '\0';
3859 r = MsiEnumClientsA(component, 0, product);
3860 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3861 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3862
3863 /* try index 1, second product value does not exist */
3864 product[0] = '\0';
3865 r = MsiEnumClientsA(component, 1, product);
3866 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3867 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3868
3869 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3870 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3871
3872 /* try index 1, second product value does exist */
3873 product[0] = '\0';
3874 r = MsiEnumClientsA(component, 1, product);
3875 todo_wine
3876 {
3877 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3878 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3879 }
3880
3881 /* start the enumeration over */
3882 product[0] = '\0';
3883 r = MsiEnumClientsA(component, 0, product);
3884 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3885 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3886 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3887
3888 /* correctly query second product */
3889 product[0] = '\0';
3890 r = MsiEnumClientsA(component, 1, product);
3891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3892 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3893 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3894
3895 RegDeleteValueA(compkey, prod_squashed);
3896 RegDeleteValueA(compkey, prod2_squashed);
3897 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3898 RegCloseKey(compkey);
3899
3900 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3901 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3902 lstrcatA(keypath, comp_squashed);
3903
3904 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3905 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3906
3907 /* user local component key exists */
3908 product[0] = '\0';
3909 r = MsiEnumClientsA(component, 0, product);
3910 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3911 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3912
3913 /* index > 0, no products exist */
3914 product[0] = '\0';
3915 r = MsiEnumClientsA(component, 1, product);
3916 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3917 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3918
3919 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3920 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3921
3922 /* product value exists */
3923 product[0] = '\0';
3924 r = MsiEnumClientsA(component, 0, product);
3925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3926 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3927
3928 /* try index 0 again */
3929 product[0] = '\0';
3930 r = MsiEnumClientsA(component, 0, product);
3931 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3932
3933 /* try index 1, second product value does not exist */
3934 product[0] = '\0';
3935 r = MsiEnumClientsA(component, 1, product);
3936 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3937 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3938
3939 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3940 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3941
3942 /* try index 1, second product value does exist */
3943 product[0] = '\0';
3944 r = MsiEnumClientsA(component, 1, product);
3945 todo_wine
3946 {
3947 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3948 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3949 }
3950
3951 /* start the enumeration over */
3952 product[0] = '\0';
3953 r = MsiEnumClientsA(component, 0, product);
3954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3955 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3956 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3957
3958 /* correctly query second product */
3959 product[0] = '\0';
3960 r = MsiEnumClientsA(component, 1, product);
3961 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3962 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3963 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3964
3965 RegDeleteValueA(compkey, prod_squashed);
3966 RegDeleteValueA(compkey, prod2_squashed);
3967 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3968 RegCloseKey(compkey);
3969 LocalFree(usersid);
3970 }
3971
3972 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
3973 LPSTR *langcheck, LPDWORD langchecksz)
3974 {
3975 LPSTR version;
3976 VS_FIXEDFILEINFO *ffi;
3977 DWORD size = GetFileVersionInfoSizeA(path, NULL);
3978 USHORT *lang;
3979
3980 version = HeapAlloc(GetProcessHeap(), 0, size);
3981 GetFileVersionInfoA(path, 0, size, version);
3982
3983 VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
3984 *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3985 sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
3986 LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
3987 LOWORD(ffi->dwFileVersionLS));
3988 *verchecksz = lstrlenA(*vercheck);
3989
3990 VerQueryValueA(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
3991 *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3992 sprintf(*langcheck, "%d", *lang);
3993 *langchecksz = lstrlenA(*langcheck);
3994
3995 HeapFree(GetProcessHeap(), 0, version);
3996 }
3997
3998 static void test_MsiGetFileVersion(void)
3999 {
4000 UINT r;
4001 DWORD versz, langsz;
4002 char version[MAX_PATH];
4003 char lang[MAX_PATH];
4004 char path[MAX_PATH];
4005 LPSTR vercheck, langcheck;
4006 DWORD verchecksz, langchecksz;
4007
4008 /* NULL szFilePath */
4009 r = MsiGetFileVersionA(NULL, NULL, NULL, NULL, NULL);
4010 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4011
4012 versz = MAX_PATH;
4013 langsz = MAX_PATH;
4014 lstrcpyA(version, "version");
4015 lstrcpyA(lang, "lang");
4016 r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
4017 ok(r == ERROR_INVALID_PARAMETER,
4018 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4019 ok(!lstrcmpA(version, "version"),
4020 "Expected version to be unchanged, got %s\n", version);
4021 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4022 ok(!lstrcmpA(lang, "lang"),
4023 "Expected lang to be unchanged, got %s\n", lang);
4024 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4025
4026 /* empty szFilePath */
4027 r = MsiGetFileVersionA("", NULL, NULL, NULL, NULL);
4028 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4029
4030 versz = MAX_PATH;
4031 langsz = MAX_PATH;
4032 lstrcpyA(version, "version");
4033 lstrcpyA(lang, "lang");
4034 r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
4035 ok(r == ERROR_FILE_NOT_FOUND,
4036 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4037 ok(!lstrcmpA(version, "version"),
4038 "Expected version to be unchanged, got %s\n", version);
4039 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4040 ok(!lstrcmpA(lang, "lang"),
4041 "Expected lang to be unchanged, got %s\n", lang);
4042 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4043
4044 /* nonexistent szFilePath */
4045 versz = MAX_PATH;
4046 langsz = MAX_PATH;
4047 lstrcpyA(version, "version");
4048 lstrcpyA(lang, "lang");
4049 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4050 ok(r == ERROR_FILE_NOT_FOUND,
4051 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4052 ok(!lstrcmpA(version, "version"),
4053 "Expected version to be unchanged, got %s\n", version);
4054 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4055 ok(!lstrcmpA(lang, "lang"),
4056 "Expected lang to be unchanged, got %s\n", lang);
4057 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4058
4059 /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
4060 versz = MAX_PATH;
4061 langsz = MAX_PATH;
4062 lstrcpyA(version, "version");
4063 lstrcpyA(lang, "lang");
4064 r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
4065 ok(r == ERROR_INVALID_PARAMETER,
4066 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4067 ok(!lstrcmpA(version, "version"),
4068 "Expected version to be unchanged, got %s\n", version);
4069 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4070 ok(!lstrcmpA(lang, "lang"),
4071 "Expected lang to be unchanged, got %s\n", lang);
4072 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4073
4074 /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
4075 versz = MAX_PATH;
4076 langsz = MAX_PATH;
4077 lstrcpyA(version, "version");
4078 lstrcpyA(lang, "lang");
4079 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
4080 ok(r == ERROR_INVALID_PARAMETER,
4081 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4082 ok(!lstrcmpA(version, "version"),
4083 "Expected version to be unchanged, got %s\n", version);
4084 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4085 ok(!lstrcmpA(lang, "lang"),
4086 "Expected lang to be unchanged, got %s\n", lang);
4087 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4088
4089 /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
4090 versz = 0;
4091 langsz = MAX_PATH;
4092 lstrcpyA(version, "version");
4093 lstrcpyA(lang, "lang");
4094 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4095 ok(r == ERROR_FILE_NOT_FOUND,
4096 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4097 ok(!lstrcmpA(version, "version"),
4098 "Expected version to be unchanged, got %s\n", version);
4099 ok(versz == 0, "Expected 0, got %d\n", versz);
4100 ok(!lstrcmpA(lang, "lang"),
4101 "Expected lang to be unchanged, got %s\n", lang);
4102 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4103
4104 /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
4105 versz = MAX_PATH;
4106 langsz = 0;
4107 lstrcpyA(version, "version");
4108 lstrcpyA(lang, "lang");
4109 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4110 ok(r == ERROR_FILE_NOT_FOUND,
4111 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4112 ok(!lstrcmpA(version, "version"),
4113 "Expected version to be unchanged, got %s\n", version);
4114 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4115 ok(!lstrcmpA(lang, "lang"),
4116 "Expected lang to be unchanged, got %s\n", lang);
4117 ok(langsz == 0, "Expected 0, got %d\n", langsz);
4118
4119 /* nonexistent szFilePath, rest NULL */
4120 r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
4121 ok(r == ERROR_FILE_NOT_FOUND,
4122 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4123
4124 create_file("ver.txt", "ver.txt", 20);
4125
4126 /* file exists, no version information */
4127 r = MsiGetFileVersionA("ver.txt", NULL, NULL, NULL, NULL);
4128 ok(r == ERROR_FILE_INVALID, "Expected ERROR_FILE_INVALID, got %d\n", r);
4129
4130 versz = MAX_PATH;
4131 langsz = MAX_PATH;
4132 lstrcpyA(version, "version");
4133 lstrcpyA(lang, "lang");
4134 r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
4135 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4136 ok(!lstrcmpA(version, "version"),
4137 "Expected version to be unchanged, got %s\n", version);
4138 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4139 ok(!lstrcmpA(lang, "lang"),
4140 "Expected lang to be unchanged, got %s\n", lang);
4141 ok(r == ERROR_FILE_INVALID,
4142 "Expected ERROR_FILE_INVALID, got %d\n", r);
4143
4144 DeleteFileA("ver.txt");
4145
4146 /* relative path, has version information */
4147 versz = MAX_PATH;
4148 langsz = MAX_PATH;
4149 lstrcpyA(version, "version");
4150 lstrcpyA(lang, "lang");
4151 r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
4152 todo_wine
4153 {
4154 ok(r == ERROR_FILE_NOT_FOUND,
4155 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4156 ok(!lstrcmpA(version, "version"),
4157 "Expected version to be unchanged, got %s\n", version);
4158 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4159 ok(!lstrcmpA(lang, "lang"),
4160 "Expected lang to be unchanged, got %s\n", lang);
4161 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4162 }
4163
4164 GetSystemDirectoryA(path, MAX_PATH);
4165 lstrcatA(path, "\\kernel32.dll");
4166
4167 get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
4168
4169 /* absolute path, has version information */
4170 versz = MAX_PATH;
4171 langsz = MAX_PATH;
4172 lstrcpyA(version, "version");
4173 lstrcpyA(lang, "lang");
4174 r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
4175 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4176 if (langchecksz && !langsz)
4177 {
4178 win_skip("broken MsiGetFileVersionA detected\n");
4179 HeapFree(GetProcessHeap(), 0, vercheck);
4180 HeapFree(GetProcessHeap(), 0, langcheck);
4181 return;
4182 }
4183 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4184 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4185 ok(!lstrcmpA(version, vercheck),
4186 "Expected %s, got %s\n", vercheck, version);
4187
4188 /* only check version */
4189 versz = MAX_PATH;
4190 lstrcpyA(version, "version");
4191 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4193 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4194 ok(!lstrcmpA(version, vercheck),
4195 "Expected %s, got %s\n", vercheck, version);
4196
4197 /* only check language */
4198 langsz = MAX_PATH;
4199 lstrcpyA(lang, "lang");
4200 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4201 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4202 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4203
4204 /* check neither version nor language */
4205 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4206 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4207
4208 /* get pcchVersionBuf */
4209 versz = MAX_PATH;
4210 r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
4211 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4212 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4213
4214 /* get pcchLangBuf */
4215 langsz = MAX_PATH;
4216 r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
4217 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4218 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4219
4220 /* pcchVersionBuf not big enough */
4221 versz = 5;
4222 lstrcpyA(version, "version");
4223 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4224 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4225 ok(!strncmp(version, vercheck, 4),
4226 "Expected first 4 characters of \"%s\", got \"%s\"\n", vercheck, version);
4227 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4228
4229 /* pcchLangBuf not big enough */
4230 langsz = 4;
4231 lstrcpyA(lang, "lang");
4232 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4233 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4234 ok(lstrcmpA(lang, "lang"), "lang not set\n");
4235 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4236
4237 /* pcchVersionBuf big enough, pcchLangBuf not big enough */
4238 versz = MAX_PATH;
4239 langsz = 0;
4240 lstrcpyA(version, "version");
4241 r = MsiGetFileVersionA(path, version, &versz, NULL, &langsz);
4242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4243 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4244 ok(!lstrcmpA(version, vercheck), "Expected \"%s\", got \"%s\"\n", vercheck, version);
4245 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4246
4247 /* pcchVersionBuf not big enough, pcchLangBuf big enough */
4248 versz = 5;
4249 langsz = MAX_PATH;
4250 lstrcpyA(lang, "lang");
4251 r = MsiGetFileVersionA(path, NULL, &versz, lang, &langsz);
4252 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4253 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4254 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4255 ok(strstr(lang, langcheck) != NULL, "expected %s in %s\n", langcheck, lang);
4256
4257 /* NULL pcchVersionBuf and pcchLangBuf */
4258 r = MsiGetFileVersionA(path, version, NULL, lang, NULL);
4259 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4260
4261 /* All NULL except szFilePath */
4262 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4263 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4264
4265 HeapFree(GetProcessHeap(), 0, vercheck);
4266 HeapFree(GetProcessHeap(), 0, langcheck);
4267 }
4268
4269 static void test_MsiGetProductInfo(void)
4270 {
4271 UINT r;
4272 LONG res;
4273 HKEY propkey, source;
4274 HKEY prodkey, localkey;
4275 CHAR prodcode[MAX_PATH];
4276 CHAR prod_squashed[MAX_PATH];
4277 CHAR packcode[MAX_PATH];
4278 CHAR pack_squashed[MAX_PATH];
4279 CHAR buf[MAX_PATH];
4280 CHAR keypath[MAX_PATH];
4281 LPSTR usersid;
4282 DWORD sz, val = 42;
4283 REGSAM access = KEY_ALL_ACCESS;
4284
4285 create_test_guid(prodcode, prod_squashed);
4286 create_test_guid(packcode, pack_squashed);
4287 usersid = get_user_sid();
4288
4289 if (is_wow64)
4290 access |= KEY_WOW64_64KEY;
4291
4292 /* NULL szProduct */
4293 sz = MAX_PATH;
4294 lstrcpyA(buf, "apple");
4295 r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4296 ok(r == ERROR_INVALID_PARAMETER,
4297 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4298 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4299 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4300
4301 /* empty szProduct */
4302 sz = MAX_PATH;
4303 lstrcpyA(buf, "apple");
4304 r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4305 ok(r == ERROR_INVALID_PARAMETER,
4306 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4307 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4308 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4309
4310 /* garbage szProduct */
4311 sz = MAX_PATH;
4312 lstrcpyA(buf, "apple");
4313 r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4314 ok(r == ERROR_INVALID_PARAMETER,
4315 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4316 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4317 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4318
4319 /* guid without brackets */
4320 sz = MAX_PATH;
4321 lstrcpyA(buf, "apple");
4322 r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
4323 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4324 ok(r == ERROR_INVALID_PARAMETER,
4325 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4326 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4327 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4328
4329 /* guid with brackets */
4330 sz = MAX_PATH;
4331 lstrcpyA(buf, "apple");
4332 r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
4333 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4334 ok(r == ERROR_UNKNOWN_PRODUCT,
4335 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4336 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4337 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4338
4339 /* same length as guid, but random */
4340 sz = MAX_PATH;
4341 lstrcpyA(buf, "apple");
4342 r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
4343 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4344 ok(r == ERROR_INVALID_PARAMETER,
4345 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4346 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4347 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4348
4349 /* not installed, NULL szAttribute */
4350 sz = MAX_PATH;
4351 lstrcpyA(buf, "apple");
4352 r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
4353 ok(r == ERROR_INVALID_PARAMETER,
4354 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4355 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4356 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4357
4358 /* not installed, NULL lpValueBuf */
4359 sz = MAX_PATH;
4360 lstrcpyA(buf, "apple");
4361 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4362 ok(r == ERROR_UNKNOWN_PRODUCT,
4363 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4364 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4365 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4366
4367 /* not installed, NULL pcchValueBuf */
4368 sz = MAX_PATH;
4369 lstrcpyA(buf, "apple");
4370 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, NULL);
4371 ok(r == ERROR_INVALID_PARAMETER,
4372 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4373 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4374 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4375
4376 /* created guid cannot possibly be an installed product code */
4377 sz = MAX_PATH;
4378 lstrcpyA(buf, "apple");
4379 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4380 ok(r == ERROR_UNKNOWN_PRODUCT,
4381 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4382 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4383 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4384
4385 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4386 lstrcatA(keypath, usersid);
4387 lstrcatA(keypath, "\\Installer\\Products\\");
4388 lstrcatA(keypath, prod_squashed);
4389
4390 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4391 if (res == ERROR_ACCESS_DENIED)
4392 {
4393 skip("Not enough rights to perform tests\n");
4394 LocalFree(usersid);
4395 return;
4396 }
4397 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4398
4399 /* managed product code exists */
4400 sz = MAX_PATH;
4401 lstrcpyA(buf, "apple");
4402 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4403 ok(r == ERROR_UNKNOWN_PROPERTY,
4404 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4405 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4406 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4407
4408 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4409 RegCloseKey(prodkey);
4410
4411 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4412 lstrcatA(keypath, usersid);
4413 lstrcatA(keypath, "\\Products\\");
4414 lstrcatA(keypath, prod_squashed);
4415
4416 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4417 if (res == ERROR_ACCESS_DENIED)
4418 {
4419 skip("Not enough rights to perform tests\n");
4420 LocalFree(usersid);
4421 return;
4422 }
4423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4424
4425 /* local user product code exists */
4426 sz = MAX_PATH;
4427 lstrcpyA(buf, "apple");
4428 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4429 ok(r == ERROR_UNKNOWN_PRODUCT,
4430 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4431 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4432 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4433
4434 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4435 lstrcatA(keypath, usersid);
4436 lstrcatA(keypath, "\\Installer\\Products\\");
4437 lstrcatA(keypath, prod_squashed);
4438
4439 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4440 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4441
4442 /* both local and managed product code exist */
4443 sz = MAX_PATH;
4444 lstrcpyA(buf, "apple");
4445 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4446 ok(r == ERROR_UNKNOWN_PROPERTY,
4447 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4448 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4449 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4450
4451 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4452 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4453
4454 /* InstallProperties key exists */
4455 sz = MAX_PATH;
4456 lstrcpyA(buf, "apple");
4457 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4458 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4459 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4460 ok(sz == 0, "Expected 0, got %d\n", sz);
4461
4462 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4463 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4464
4465 /* HelpLink value exists */
4466 sz = MAX_PATH;
4467 lstrcpyA(buf, "apple");
4468 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4469 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4470 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4471 ok(sz == 4, "Expected 4, got %d\n", sz);
4472
4473 /* pcchBuf is NULL */
4474 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, NULL);
4475 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4476
4477 /* lpValueBuf is NULL */
4478 sz = MAX_PATH;
4479 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4481 ok(sz == 4, "Expected 4, got %d\n", sz);
4482
4483 /* lpValueBuf is NULL, pcchValueBuf is too small */
4484 sz = 2;
4485 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4487 ok(sz == 4, "Expected 4, got %d\n", sz);
4488
4489 /* lpValueBuf is non-NULL, pcchValueBuf is too small */
4490 sz = 2;
4491 lstrcpyA(buf, "apple");
4492 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4493 ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
4494 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4495 ok(sz == 4, "Expected 4, got %d\n", sz);
4496
4497 /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
4498 sz = 4;
4499 lstrcpyA(buf, "apple");
4500 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4501 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4502 ok(!lstrcmpA(buf, "apple"),
4503 "Expected buf to remain unchanged, got \"%s\"\n", buf);
4504 ok(sz == 4, "Expected 4, got %d\n", sz);
4505
4506 res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
4507 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4508
4509 /* random property not supported by MSI, value exists */
4510 sz = MAX_PATH;
4511 lstrcpyA(buf, "apple");
4512 r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
4513 ok(r == ERROR_UNKNOWN_PROPERTY,
4514 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4515 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4516 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4517
4518 RegDeleteValueA(propkey, "IMadeThis");
4519 RegDeleteValueA(propkey, "HelpLink");
4520 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4521 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4522 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4523 RegCloseKey(propkey);
4524 RegCloseKey(localkey);
4525 RegCloseKey(prodkey);
4526
4527 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4528 lstrcatA(keypath, prod_squashed);
4529
4530 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4531 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4532
4533 /* user product key exists */
4534 sz = MAX_PATH;
4535 lstrcpyA(buf, "apple");
4536 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4537 ok(r == ERROR_UNKNOWN_PROPERTY,
4538 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4539 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4540 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4541
4542 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4543 lstrcatA(keypath, usersid);
4544 lstrcatA(keypath, "\\Products\\");
4545 lstrcatA(keypath, prod_squashed);
4546
4547 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4548 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4549
4550 /* local user product key exists */
4551 sz = MAX_PATH;
4552 lstrcpyA(buf, "apple");
4553 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4554 ok(r == ERROR_UNKNOWN_PROPERTY,
4555 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4556 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4557 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4558
4559 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4560 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4561
4562 /* InstallProperties key exists */
4563 sz = MAX_PATH;
4564 lstrcpyA(buf, "apple");
4565 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4567 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4568 ok(sz == 0, "Expected 0, got %d\n", sz);
4569
4570 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4571 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4572
4573 /* HelpLink value exists */
4574 sz = MAX_PATH;
4575 lstrcpyA(buf, "apple");
4576 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4578 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4579 ok(sz == 4, "Expected 4, got %d\n", sz);
4580
4581 RegDeleteValueA(propkey, "HelpLink");
4582 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4583 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4584 RegDeleteKeyA(prodkey, "");
4585 RegCloseKey(propkey);
4586 RegCloseKey(localkey);
4587 RegCloseKey(prodkey);
4588
4589 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
4590 lstrcatA(keypath, prod_squashed);
4591
4592 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4593 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4594
4595 /* classes product key exists */
4596 sz = MAX_PATH;
4597 lstrcpyA(buf, "apple");
4598 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4599 ok(r == ERROR_UNKNOWN_PROPERTY,
4600 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4601 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4602 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4603
4604 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4605 lstrcatA(keypath, usersid);
4606 lstrcatA(keypath, "\\Products\\");
4607 lstrcatA(keypath, prod_squashed);
4608
4609 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4610 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4611
4612 /* local user product key exists */
4613 sz = MAX_PATH;
4614 lstrcpyA(buf, "apple");
4615 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4616 ok(r == ERROR_UNKNOWN_PROPERTY,
4617 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4618 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4619 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4620
4621 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4622 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4623
4624 /* InstallProperties key exists */
4625 sz = MAX_PATH;
4626 lstrcpyA(buf, "apple");
4627 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4628 ok(r == ERROR_UNKNOWN_PROPERTY,
4629 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4630 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4631 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4632
4633 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4634 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4635 RegCloseKey(propkey);
4636 RegCloseKey(localkey);
4637
4638 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4639 lstrcatA(keypath, "S-1-5-18\\\\Products\\");
4640 lstrcatA(keypath, prod_squashed);
4641
4642 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4643 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4644
4645 /* Local System product key exists */
4646 sz = MAX_PATH;
4647 lstrcpyA(buf, "apple");
4648 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4649 ok(r == ERROR_UNKNOWN_PROPERTY,
4650 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4651 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4652 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4653
4654 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4655 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4656
4657 /* InstallProperties key exists */
4658 sz = MAX_PATH;
4659 lstrcpyA(buf, "apple");
4660 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4661 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4662 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4663 ok(sz == 0, "Expected 0, got %d\n", sz);
4664
4665 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4666 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4667
4668 /* HelpLink value exists */
4669 sz = MAX_PATH;
4670 lstrcpyA(buf, "apple");
4671 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4672 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4673 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4674 ok(sz == 4, "Expected 4, got %d\n", sz);
4675
4676 res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
4677 (const BYTE *)&val, sizeof(DWORD));
4678 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4679
4680 /* HelpLink type is REG_DWORD */
4681 sz = MAX_PATH;
4682 lstrcpyA(buf, "apple");
4683 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4684 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4685 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4686 ok(sz == 2, "Expected 2, got %d\n", sz);
4687
4688 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4689 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4690
4691 /* DisplayName value exists */
4692 sz = MAX_PATH;
4693 lstrcpyA(buf, "apple");
4694 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
4695 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4696 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4697 ok(sz == 4, "Expected 4, got %d\n", sz);
4698
4699 res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
4700 (const BYTE *)&val, sizeof(DWORD));
4701 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4702
4703 /* DisplayName type is REG_DWORD */
4704 sz = MAX_PATH;
4705 lstrcpyA(buf, "apple");
4706 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
4707 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4708 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4709 ok(sz == 2, "Expected 2, got %d\n", sz);
4710
4711 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
4712 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4713
4714 /* DisplayVersion value exists */
4715 sz = MAX_PATH;
4716 lstrcpyA(buf, "apple");
4717 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
4718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4719 ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
4720 ok(sz == 5, "Expected 5, got %d\n", sz);
4721
4722 res = RegSetValueExA(propkey, "DisplayVersion", 0,
4723 REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
4724 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4725
4726 /* DisplayVersion type is REG_DWORD */
4727 sz = MAX_PATH;
4728 lstrcpyA(buf, "apple");
4729 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
4730 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4731 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4732 ok(sz == 2, "Expected 2, got %d\n", sz);
4733
4734 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
4735 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4736
4737 /* HelpTelephone value exists */
4738 sz = MAX_PATH;
4739 lstrcpyA(buf, "apple");
4740 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
4741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4742 ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
4743 ok(sz == 4, "Expected 4, got %d\n", sz);
4744
4745 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
4746 (const BYTE *)&val, sizeof(DWORD));
4747 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4748
4749 /* HelpTelephone type is REG_DWORD */
4750 sz = MAX_PATH;
4751 lstrcpyA(buf, "apple");
4752 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
4753 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4754 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4755 ok(sz == 2, "Expected 2, got %d\n", sz);
4756
4757 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4758 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4759
4760 /* InstallLocation value exists */
4761 sz = MAX_PATH;
4762 lstrcpyA(buf, "apple");
4763 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
4764 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4765 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4766 ok(sz == 3, "Expected 3, got %d\n", sz);
4767
4768 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
4769 (const BYTE *)&val, sizeof(DWORD));
4770 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4771
4772 /* InstallLocation type is REG_DWORD */
4773 sz = MAX_PATH;
4774 lstrcpyA(buf, "apple");
4775 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
4776 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4777 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4778 ok(sz == 2, "Expected 2, got %d\n", sz);
4779
4780 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4781 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4782
4783 /* InstallSource value exists */
4784 sz = MAX_PATH;
4785 lstrcpyA(buf, "apple");
4786 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
4787 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4788 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4789 ok(sz == 6, "Expected 6, got %d\n", sz);
4790
4791 res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
4792 (const BYTE *)&val, sizeof(DWORD));
4793 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4794
4795 /* InstallSource type is REG_DWORD */
4796 sz = MAX_PATH;
4797 lstrcpyA(buf, "apple");
4798 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
4799 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4800 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4801 ok(sz == 2, "Expected 2, got %d\n", sz);
4802
4803 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4804 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4805
4806 /* InstallDate value exists */
4807 sz = MAX_PATH;
4808 lstrcpyA(buf, "apple");
4809 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
4810 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4811 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4812 ok(sz == 4, "Expected 4, got %d\n", sz);
4813
4814 res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
4815 (const BYTE *)&val, sizeof(DWORD));
4816 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4817
4818 /* InstallDate type is REG_DWORD */
4819 sz = MAX_PATH;
4820 lstrcpyA(buf, "apple");
4821 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
4822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4823 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4824 ok(sz == 2, "Expected 2, got %d\n", sz);
4825
4826 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4827 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4828
4829 /* Publisher value exists */
4830 sz = MAX_PATH;
4831 lstrcpyA(buf, "apple");
4832 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHERA, buf, &sz);
4833 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4834 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4835 ok(sz == 3, "Expected 3, got %d\n", sz);
4836
4837 res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
4838 (const BYTE *)&val, sizeof(DWORD));
4839 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4840
4841 /* Publisher type is REG_DWORD */
4842 sz = MAX_PATH;
4843 lstrcpyA(buf, "apple");
4844 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHERA, buf, &sz);
4845 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4846 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4847 ok(sz == 2, "Expected 2, got %d\n", sz);
4848
4849 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
4850 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4851
4852 /* LocalPackage value exists */
4853 sz = MAX_PATH;
4854 lstrcpyA(buf, "apple");
4855 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
4856 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4857 ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
4858 ok(sz == 4, "Expected 4, got %d\n", sz);
4859
4860 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
4861 (const BYTE *)&val, sizeof(DWORD));
4862 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4863
4864 /* LocalPackage type is REG_DWORD */
4865 sz = MAX_PATH;
4866 lstrcpyA(buf, "apple");
4867 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
4868 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4869 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4870 ok(sz == 2, "Expected 2, got %d\n", sz);
4871
4872 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4873 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4874
4875 /* UrlInfoAbout value exists */
4876 sz = MAX_PATH;
4877 lstrcpyA(buf, "apple");
4878 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
4879 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4880 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4881 ok(sz == 5, "Expected 5, got %d\n", sz);
4882
4883 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
4884 (const BYTE *)&val, sizeof(DWORD));
4885 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4886
4887 /* UrlInfoAbout type is REG_DWORD */
4888 sz = MAX_PATH;
4889 lstrcpyA(buf, "apple");
4890 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
4891 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4892 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4893 ok(sz == 2, "Expected 2, got %d\n", sz);
4894
4895 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
4896 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4897
4898 /* UrlUpdateInfo value exists */
4899 sz = MAX_PATH;
4900 lstrcpyA(buf, "apple");
4901 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
4902 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4903 ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
4904 ok(sz == 4, "Expected 4, got %d\n", sz);
4905
4906 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
4907 (const BYTE *)&val, sizeof(DWORD));
4908 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4909
4910 /* UrlUpdateInfo type is REG_DWORD */
4911 sz = MAX_PATH;
4912 lstrcpyA(buf, "apple");
4913 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
4914 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4915 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4916 ok(sz == 2, "Expected 2, got %d\n", sz);
4917
4918 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
4919 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4920
4921 /* VersionMinor value exists */
4922 sz = MAX_PATH;
4923 lstrcpyA(buf, "apple");
4924 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
4925 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4926 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4927 ok(sz == 1, "Expected 1, got %d\n", sz);
4928
4929 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
4930 (const BYTE *)&val, sizeof(DWORD));
4931 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4932
4933 /* VersionMinor type is REG_DWORD */
4934 sz = MAX_PATH;
4935 lstrcpyA(buf, "apple");
4936 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
4937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4938 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4939 ok(sz == 2, "Expected 2, got %d\n", sz);
4940
4941 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
4942 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4943
4944 /* VersionMajor value exists */
4945 sz = MAX_PATH;
4946 lstrcpyA(buf, "apple");
4947 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
4948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4949 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4950 ok(sz == 1, "Expected 1, got %d\n", sz);
4951
4952 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
4953 (const BYTE *)&val, sizeof(DWORD));
4954 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4955
4956 /* VersionMajor type is REG_DWORD */
4957 sz = MAX_PATH;
4958 lstrcpyA(buf, "apple");
4959 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
4960 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4961 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4962 ok(sz == 2, "Expected 2, got %d\n", sz);
4963
4964 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4965 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4966
4967 /* ProductID value exists */
4968 sz = MAX_PATH;
4969 lstrcpyA(buf, "apple");
4970 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
4971 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4972 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4973 ok(sz == 2, "Expected 2, got %d\n", sz);
4974
4975 res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
4976 (const BYTE *)&val, sizeof(DWORD));
4977 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4978
4979 /* ProductID type is REG_DWORD */
4980 sz = MAX_PATH;
4981 lstrcpyA(buf, "apple");
4982 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
4983 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4984 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4985 ok(sz == 2, "Expected 2, got %d\n", sz);
4986
4987 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4988 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4989
4990 /* RegCompany value exists */
4991 sz = MAX_PATH;
4992 lstrcpyA(buf, "apple");
4993 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
4994 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4995 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4996 ok(sz == 4, "Expected 4, got %d\n", sz);
4997
4998 res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
4999 (const BYTE *)&val, sizeof(DWORD));
5000 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5001
5002 /* RegCompany type is REG_DWORD */
5003 sz = MAX_PATH;
5004 lstrcpyA(buf, "apple");
5005 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
5006 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5007 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5008 ok(sz == 2, "Expected 2, got %d\n", sz);
5009
5010 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
5011 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5012
5013 /* RegOwner value exists */
5014 sz = MAX_PATH;
5015 lstrcpyA(buf, "apple");
5016 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNERA, buf, &sz);
5017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5018 ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
5019 ok(sz == 3, "Expected 3, got %d\n", sz);
5020
5021 res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
5022 (const BYTE *)&val, sizeof(DWORD));
5023 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5024
5025 /* RegOwner type is REG_DWORD */
5026 sz = MAX_PATH;
5027 lstrcpyA(buf, "apple");
5028 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNERA, buf, &sz);
5029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5030 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5031 ok(sz == 2, "Expected 2, got %d\n", sz);
5032
5033 res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
5034 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5035
5036 /* InstanceType value exists */
5037 sz = MAX_PATH;
5038 lstrcpyA(buf, "apple");
5039 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5041 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5042 ok(sz == 0, "Expected 0, got %d\n", sz);
5043
5044 res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
5045 (const BYTE *)&val, sizeof(DWORD));
5046 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5047
5048 /* InstanceType type is REG_DWORD */
5049 sz = MAX_PATH;
5050 lstrcpyA(buf, "apple");
5051 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5052 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5053 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5054 ok(sz == 0, "Expected 0, got %d\n", sz);
5055
5056 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
5057 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5058
5059 /* InstanceType value exists */
5060 sz = MAX_PATH;
5061 lstrcpyA(buf, "apple");
5062 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5063 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5064 ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
5065 ok(sz == 4, "Expected 4, got %d\n", sz);
5066
5067 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
5068 (const BYTE *)&val, sizeof(DWORD));
5069 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5070
5071 /* InstanceType type is REG_DWORD */
5072 sz = MAX_PATH;
5073 lstrcpyA(buf, "apple");
5074 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5075 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5076 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5077 ok(sz == 2, "Expected 2, got %d\n", sz);
5078
5079 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
5080 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5081
5082 /* Transforms value exists */
5083 sz = MAX_PATH;
5084 lstrcpyA(buf, "apple");
5085 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5086 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5087 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5088 ok(sz == 0, "Expected 0, got %d\n", sz);
5089
5090 res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
5091 (const BYTE *)&val, sizeof(DWORD));
5092 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5093
5094 /* Transforms type is REG_DWORD */
5095 sz = MAX_PATH;
5096 lstrcpyA(buf, "apple");
5097 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5098 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5099 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5100 ok(sz == 0, "Expected 0, got %d\n", sz);
5101
5102 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
5103 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5104
5105 /* Transforms value exists */
5106 sz = MAX_PATH;
5107 lstrcpyA(buf, "apple");
5108 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5110 ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
5111 ok(sz == 6, "Expected 6, got %d\n", sz);
5112
5113 res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
5114 (const BYTE *)&val, sizeof(DWORD));
5115 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5116
5117 /* Transforms type is REG_DWORD */
5118 sz = MAX_PATH;
5119 lstrcpyA(buf, "apple");
5120 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5122 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5123 ok(sz == 2, "Expected 2, got %d\n", sz);
5124
5125 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5126 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5127
5128 /* Language value exists */
5129 sz = MAX_PATH;
5130 lstrcpyA(buf, "apple");
5131 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5133 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5134 ok(sz == 0, "Expected 0, got %d\n", sz);
5135
5136 res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
5137 (const BYTE *)&val, sizeof(DWORD));
5138 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5139
5140 /* Language type is REG_DWORD */
5141 sz = MAX_PATH;
5142 lstrcpyA(buf, "apple");
5143 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5145 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5146 ok(sz == 0, "Expected 0, got %d\n", sz);
5147
5148 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5149 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5150
5151 /* Language value exists */
5152 sz = MAX_PATH;
5153 lstrcpyA(buf, "apple");
5154 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5156 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5157 ok(sz == 4, "Expected 4, got %d\n", sz);
5158
5159 res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
5160 (const BYTE *)&val, sizeof(DWORD));
5161 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5162
5163 /* Language type is REG_DWORD */
5164 sz = MAX_PATH;
5165 lstrcpyA(buf, "apple");
5166 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5167 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5168 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5169 ok(sz == 2, "Expected 2, got %d\n", sz);
5170
5171 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5172 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5173
5174 /* ProductName value exists */
5175 sz = MAX_PATH;
5176 lstrcpyA(buf, "apple");
5177 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5178 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5179 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5180 ok(sz == 0, "Expected 0, got %d\n", sz);
5181
5182 res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
5183 (const BYTE *)&val, sizeof(DWORD));
5184 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5185
5186 /* ProductName type is REG_DWORD */
5187 sz = MAX_PATH;
5188 lstrcpyA(buf, "apple");
5189 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5190 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5191 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5192 ok(sz == 0, "Expected 0, got %d\n", sz);
5193
5194 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5195 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5196
5197 /* ProductName value exists */
5198 sz = MAX_PATH;
5199 lstrcpyA(buf, "apple");
5200 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5201 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5202 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5203 ok(sz == 4, "Expected 4, got %d\n", sz);
5204
5205 res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
5206 (const BYTE *)&val, sizeof(DWORD));
5207 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5208
5209 /* ProductName type is REG_DWORD */
5210 sz = MAX_PATH;
5211 lstrcpyA(buf, "apple");
5212 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5213 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5214 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5215 ok(sz == 2, "Expected 2, got %d\n", sz);
5216
5217 res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5218 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5219
5220 /* Assignment value exists */
5221 sz = MAX_PATH;
5222 lstrcpyA(buf, "apple");
5223 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5224 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5225 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5226 ok(sz == 0, "Expected 0, got %d\n", sz);
5227
5228 res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
5229 (const BYTE *)&val, sizeof(DWORD));
5230 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5231
5232 /* Assignment type is REG_DWORD */
5233 sz = MAX_PATH;
5234 lstrcpyA(buf, "apple");
5235 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5237 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5238 ok(sz == 0, "Expected 0, got %d\n", sz);
5239
5240 res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5241 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5242
5243 /* Assignment value exists */
5244 sz = MAX_PATH;
5245 lstrcpyA(buf, "apple");
5246 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5248 ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
5249 ok(sz == 2, "Expected 2, got %d\n", sz);
5250
5251 res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
5252 (const BYTE *)&val, sizeof(DWORD));
5253 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5254
5255 /* Assignment type is REG_DWORD */
5256 sz = MAX_PATH;
5257 lstrcpyA(buf, "apple");
5258 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5259 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5260 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5261 ok(sz == 2, "Expected 2, got %d\n", sz);
5262
5263 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5264 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5265
5266 /* PackageCode value exists */
5267 sz = MAX_PATH;
5268 lstrcpyA(buf, "apple");
5269 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5270 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5271 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5272 ok(sz == 0, "Expected 0, got %d\n", sz);
5273
5274 res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
5275 (const BYTE *)&val, sizeof(DWORD));
5276 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5277
5278 /* PackageCode type is REG_DWORD */
5279 sz = MAX_PATH;
5280 lstrcpyA(buf, "apple");
5281 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5282 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5283 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5284 ok(sz == 0, "Expected 0, got %d\n", sz);
5285
5286 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5287 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5288
5289 /* PackageCode value exists */
5290 sz = MAX_PATH;
5291 lstrcpyA(buf, "apple");
5292 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5293 ok(r == ERROR_BAD_CONFIGURATION,
5294 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5295 ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
5296 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5297
5298 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
5299 (const BYTE *)&val, sizeof(DWORD));
5300 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5301
5302 /* PackageCode type is REG_DWORD */
5303 sz = MAX_PATH;
5304 lstrcpyA(buf, "apple");
5305 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5306 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5307 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5308 ok(sz == 2, "Expected 2, got %d\n", sz);
5309
5310 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
5311 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5312
5313 /* PackageCode value exists */
5314 sz = MAX_PATH;
5315 lstrcpyA(buf, "apple");
5316 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5317 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5318 ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
5319 ok(sz == 38, "Expected 38, got %d\n", sz);
5320
5321 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5322 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5323
5324 /* Version value exists */
5325 sz = MAX_PATH;
5326 lstrcpyA(buf, "apple");
5327 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5328 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5329 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5330 ok(sz == 0, "Expected 0, got %d\n", sz);
5331
5332 res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
5333 (const BYTE *)&val, sizeof(DWORD));
5334 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5335
5336 /* Version type is REG_DWORD */
5337 sz = MAX_PATH;
5338 lstrcpyA(buf, "apple");
5339 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5341 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5342 ok(sz == 0, "Expected 0, got %d\n", sz);
5343
5344 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5345 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5346
5347 /* Version value exists */
5348 sz = MAX_PATH;
5349 lstrcpyA(buf, "apple");
5350 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5351 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5352 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5353 ok(sz == 3, "Expected 3, got %d\n", sz);
5354
5355 res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
5356 (const BYTE *)&val, sizeof(DWORD));
5357 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5358
5359 /* Version type is REG_DWORD */
5360 sz = MAX_PATH;
5361 lstrcpyA(buf, "apple");
5362 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5364 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5365 ok(sz == 2, "Expected 2, got %d\n", sz);
5366
5367 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5368 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5369
5370 /* ProductIcon value exists */
5371 sz = MAX_PATH;
5372 lstrcpyA(buf, "apple");
5373 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5375 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5376 ok(sz == 0, "Expected 0, got %d\n", sz);
5377
5378 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
5379 (const BYTE *)&val, sizeof(DWORD));
5380 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5381
5382 /* ProductIcon type is REG_DWORD */
5383 sz = MAX_PATH;
5384 lstrcpyA(buf, "apple");
5385 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5386 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5387 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5388 ok(sz == 0, "Expected 0, got %d\n", sz);
5389
5390 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5391 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5392
5393 /* ProductIcon value exists */
5394 sz = MAX_PATH;
5395 lstrcpyA(buf, "apple");
5396 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5398 ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
5399 ok(sz == 3, "Expected 3, got %d\n", sz);
5400
5401 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
5402 (const BYTE *)&val, sizeof(DWORD));
5403 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5404
5405 /* ProductIcon type is REG_DWORD */
5406 sz = MAX_PATH;
5407 lstrcpyA(buf, "apple");
5408 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5409 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5410 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5411 ok(sz == 2, "Expected 2, got %d\n", sz);
5412
5413 /* SourceList key does not exist */
5414 sz = MAX_PATH;
5415 lstrcpyA(buf, "apple");
5416 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5417 ok(r == ERROR_UNKNOWN_PRODUCT,
5418 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5419 ok(!lstrcmpA(buf, "apple"),
5420 "Expected buf to be unchanged, got \"%s\"\n", buf);
5421 ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
5422
5423 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
5424 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5425
5426 /* SourceList key exists, but PackageName val does not exist */
5427 sz = MAX_PATH;
5428 lstrcpyA(buf, "apple");
5429 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5430 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5431 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5432 ok(sz == 0, "Expected 0, got %d\n", sz);
5433
5434 res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
5435 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5436
5437 /* PackageName val exists */
5438 sz = MAX_PATH;
5439 lstrcpyA(buf, "apple");
5440 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5441 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5442 ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
5443 ok(sz == 8, "Expected 8, got %d\n", sz);
5444
5445 res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
5446 (const BYTE *)&val, sizeof(DWORD));
5447 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5448
5449 /* PackageName type is REG_DWORD */
5450 sz = MAX_PATH;
5451 lstrcpyA(buf, "apple");
5452 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5453 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5454 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5455 ok(sz == 2, "Expected 2, got %d\n", sz);
5456
5457 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5458 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5459
5460 /* Authorized value exists */
5461 sz = MAX_PATH;
5462 lstrcpyA(buf, "apple");
5463 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5464 if (r != ERROR_UNKNOWN_PROPERTY)
5465 {
5466 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5467 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5468 ok(sz == 0, "Expected 0, got %d\n", sz);
5469 }
5470
5471 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
5472 (const BYTE *)&val, sizeof(DWORD));
5473 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5474
5475 /* AuthorizedLUAApp type is REG_DWORD */
5476 sz = MAX_PATH;
5477 lstrcpyA(buf, "apple");
5478 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5479 if (r != ERROR_UNKNOWN_PROPERTY)
5480 {
5481 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5482 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5483 ok(sz == 0, "Expected 0, got %d\n", sz);
5484 }
5485
5486 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5487 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5488
5489 /* Authorized value exists */
5490 sz = MAX_PATH;
5491 lstrcpyA(buf, "apple");
5492 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5493 if (r != ERROR_UNKNOWN_PROPERTY)
5494 {
5495 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5496 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5497 ok(sz == 4, "Expected 4, got %d\n", sz);
5498 }
5499
5500 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
5501 (const BYTE *)&val, sizeof(DWORD));
5502 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5503
5504 /* AuthorizedLUAApp type is REG_DWORD */
5505 sz = MAX_PATH;
5506 lstrcpyA(buf, "apple");
5507 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5508 if (r != ERROR_UNKNOWN_PROPERTY)
5509 {
5510 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5511 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5512 ok(sz == 2, "Expected 2, got %d\n", sz);
5513 }
5514
5515 RegDeleteValueA(propkey, "HelpLink");
5516 RegDeleteValueA(propkey, "DisplayName");
5517 RegDeleteValueA(propkey, "DisplayVersion");
5518 RegDeleteValueA(propkey, "HelpTelephone");
5519 RegDeleteValueA(propkey, "InstallLocation");
5520 RegDeleteValueA(propkey, "InstallSource");
5521 RegDeleteValueA(propkey, "InstallDate");
5522 RegDeleteValueA(propkey, "Publisher");
5523 RegDeleteValueA(propkey, "LocalPackage");
5524 RegDeleteValueA(propkey, "UrlInfoAbout");
5525 RegDeleteValueA(propkey, "UrlUpdateInfo");
5526 RegDeleteValueA(propkey, "VersionMinor");
5527 RegDeleteValueA(propkey, "VersionMajor");
5528 RegDeleteValueA(propkey, "ProductID");
5529 RegDeleteValueA(propkey, "RegCompany");
5530 RegDeleteValueA(propkey, "RegOwner");
5531 RegDeleteValueA(propkey, "InstanceType");
5532 RegDeleteValueA(propkey, "Transforms");
5533 RegDeleteValueA(propkey, "Language");
5534 RegDeleteValueA(propkey, "ProductName");
5535 RegDeleteValueA(propkey, "Assignment");
5536 RegDeleteValueA(propkey, "PackageCode");
5537 RegDeleteValueA(propkey, "Version");
5538 RegDeleteValueA(propkey, "ProductIcon");
5539 RegDeleteValueA(propkey, "AuthorizedLUAApp");
5540 delete_key(propkey, "", access & KEY_WOW64_64KEY);
5541 delete_key(localkey, "", access & KEY_WOW64_64KEY);
5542 RegDeleteValueA(prodkey, "InstanceType");
5543 RegDeleteValueA(prodkey, "Transforms");
5544 RegDeleteValueA(prodkey, "Language");
5545 RegDeleteValueA(prodkey, "ProductName");
5546 RegDeleteValueA(prodkey, "Assignment");
5547 RegDeleteValueA(prodkey, "PackageCode");
5548 RegDeleteValueA(prodkey, "Version");
5549 RegDeleteValueA(prodkey, "ProductIcon");
5550 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5551 RegDeleteValueA(source, "PackageName");
5552 delete_key(source, "", access & KEY_WOW64_64KEY);
5553 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5554 RegCloseKey(propkey);
5555 RegCloseKey(localkey);
5556 RegCloseKey(source);
5557 RegCloseKey(prodkey);
5558 LocalFree(usersid);
5559 }
5560
5561 static void test_MsiGetProductInfoEx(void)
5562 {
5563 UINT r;
5564 LONG res;
5565 HKEY propkey, userkey;
5566 HKEY prodkey, localkey;
5567 CHAR prodcode[MAX_PATH];
5568 CHAR prod_squashed[MAX_PATH];
5569 CHAR packcode[MAX_PATH];
5570 CHAR pack_squashed[MAX_PATH];
5571 CHAR buf[MAX_PATH];
5572 CHAR keypath[MAX_PATH];
5573 LPSTR usersid;
5574 DWORD sz;
5575 REGSAM access = KEY_ALL_ACCESS;
5576
5577 if (!pMsiGetProductInfoExA)
5578 {
5579 win_skip("MsiGetProductInfoExA is not available\n");
5580 return;
5581 }
5582
5583 create_test_guid(prodcode, prod_squashed);
5584 create_test_guid(packcode, pack_squashed);
5585 usersid = get_user_sid();
5586
5587 if (is_wow64)
5588 access |= KEY_WOW64_64KEY;
5589
5590 /* NULL szProductCode */
5591 sz = MAX_PATH;
5592 lstrcpyA(buf, "apple");
5593 r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5594 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5595 ok(r == ERROR_INVALID_PARAMETER,
5596 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5597 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5598 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5599
5600 /* empty szProductCode */
5601 sz = MAX_PATH;
5602 lstrcpyA(buf, "apple");
5603 r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5604 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5605 ok(r == ERROR_INVALID_PARAMETER,
5606 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5607 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5608 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5609
5610 /* garbage szProductCode */
5611 sz = MAX_PATH;
5612 lstrcpyA(buf, "apple");
5613 r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5614 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5615 ok(r == ERROR_INVALID_PARAMETER,
5616 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5617 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5618 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5619
5620 /* guid without brackets */
5621 sz = MAX_PATH;
5622 lstrcpyA(buf, "apple");
5623 r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
5624 MSIINSTALLCONTEXT_USERUNMANAGED,
5625 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5626 ok(r == ERROR_INVALID_PARAMETER,
5627 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5628 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5629 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5630
5631 /* guid with brackets */
5632 sz = MAX_PATH;
5633 lstrcpyA(buf, "apple");
5634 r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
5635 MSIINSTALLCONTEXT_USERUNMANAGED,
5636 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5637 ok(r == ERROR_UNKNOWN_PRODUCT,
5638 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5639 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5640 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5641
5642 /* szValue is non-NULL while pcchValue is NULL */
5643 lstrcpyA(buf, "apple");
5644 r = pMsiGetProductInfoExA(prodcode, usersid,
5645 MSIINSTALLCONTEXT_USERUNMANAGED,
5646 INSTALLPROPERTY_PRODUCTSTATEA, buf, NULL);
5647 ok(r == ERROR_INVALID_PARAMETER,
5648 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5649 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5650
5651 /* dwContext is out of range */
5652 sz = MAX_PATH;
5653 lstrcpyA(buf, "apple");
5654 r = pMsiGetProductInfoExA(prodcode, usersid, 42,
5655 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5656 ok(r == ERROR_INVALID_PARAMETER,
5657 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5658 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5659 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5660
5661 /* szProperty is NULL */
5662 sz = MAX_PATH;
5663 lstrcpyA(buf, "apple");
5664 r = pMsiGetProductInfoExA(prodcode, usersid,
5665 MSIINSTALLCONTEXT_USERUNMANAGED,
5666 NULL, buf, &sz);
5667 ok(r == ERROR_INVALID_PARAMETER,
5668 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5669 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5670 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5671
5672 /* szProperty is empty */
5673 sz = MAX_PATH;
5674 lstrcpyA(buf, "apple");
5675 r = pMsiGetProductInfoExA(prodcode, usersid,
5676 MSIINSTALLCONTEXT_USERUNMANAGED,
5677 "", buf, &sz);
5678 ok(r == ERROR_INVALID_PARAMETER,
5679 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5680 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5681 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5682
5683 /* szProperty is not a valid property */
5684 sz = MAX_PATH;
5685 lstrcpyA(buf, "apple");
5686 r = pMsiGetProductInfoExA(prodcode, usersid,
5687 MSIINSTALLCONTEXT_USERUNMANAGED,
5688 "notvalid", buf, &sz);
5689 ok(r == ERROR_UNKNOWN_PRODUCT,
5690 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5691 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5692 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5693
5694 /* same length as guid, but random */
5695 sz = MAX_PATH;
5696 lstrcpyA(buf, "apple");
5697 r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
5698 MSIINSTALLCONTEXT_USERUNMANAGED,
5699 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5700 ok(r == ERROR_INVALID_PARAMETER,
5701 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5702 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5703 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5704
5705 /* MSIINSTALLCONTEXT_USERUNMANAGED */
5706
5707 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5708 lstrcatA(keypath, usersid);
5709 lstrcatA(keypath, "\\Products\\");
5710 lstrcatA(keypath, prod_squashed);
5711
5712 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5713 if (res == ERROR_ACCESS_DENIED)
5714 {
5715 skip("Not enough rights to perform tests\n");
5716 LocalFree(usersid);
5717 return;
5718 }
5719 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5720
5721 /* local user product key exists */
5722 sz = MAX_PATH;
5723 lstrcpyA(buf, "apple");
5724 r = pMsiGetProductInfoExA(prodcode, usersid,
5725 MSIINSTALLCONTEXT_USERUNMANAGED,
5726 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5727 ok(r == ERROR_UNKNOWN_PRODUCT,
5728 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5729 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5730 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5731
5732 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5733 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5734
5735 /* InstallProperties key exists */
5736 sz = MAX_PATH;
5737 lstrcpyA(buf, "apple");
5738 r = pMsiGetProductInfoExA(prodcode, usersid,
5739 MSIINSTALLCONTEXT_USERUNMANAGED,
5740 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5741 ok(r == ERROR_UNKNOWN_PRODUCT,
5742 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5743 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5744 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5745
5746 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5747 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5748
5749 /* LocalPackage value exists */
5750 sz = MAX_PATH;
5751 lstrcpyA(buf, "apple");
5752 r = pMsiGetProductInfoExA(prodcode, usersid,
5753 MSIINSTALLCONTEXT_USERUNMANAGED,
5754 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
5755 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5756 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5757 ok(sz == 1, "Expected 1, got %d\n", sz);
5758
5759 RegDeleteValueA(propkey, "LocalPackage");
5760
5761 /* LocalPackage value must exist */
5762 sz = MAX_PATH;
5763 lstrcpyA(buf, "apple");
5764 r = pMsiGetProductInfoExA(prodcode, usersid,
5765 MSIINSTALLCONTEXT_USERUNMANAGED,
5766 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5767 ok(r == ERROR_UNKNOWN_PRODUCT,
5768 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5769 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5770 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5771
5772 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5773 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5774
5775 /* LocalPackage exists, but HelpLink does not exist */
5776 sz = MAX_PATH;
5777 lstrcpyA(buf, "apple");
5778 r = pMsiGetProductInfoExA(prodcode, usersid,
5779 MSIINSTALLCONTEXT_USERUNMANAGED,
5780 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5782 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5783 ok(sz == 0, "Expected 0, got %d\n", sz);
5784
5785 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5787
5788 /* HelpLink value exists */
5789 sz = MAX_PATH;
5790 lstrcpyA(buf, "apple");
5791 r = pMsiGetProductInfoExA(prodcode, usersid,
5792 MSIINSTALLCONTEXT_USERUNMANAGED,
5793 INSTALLPROPERTY_HELPLINKA, buf, &sz);
5794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5795 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5796 ok(sz == 4, "Expected 4, got %d\n", sz);
5797
5798 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5799 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5800
5801 /* HelpTelephone value exists */
5802 sz = MAX_PATH;
5803 lstrcpyA(buf, "apple");
5804 r = pMsiGetProductInfoExA(prodcode, usersid,
5805 MSIINSTALLCONTEXT_USERUNMANAGED,
5806 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5808 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5809 ok(sz == 5, "Expected 5, got %d\n", sz);
5810
5811 /* szValue and pcchValue are NULL */
5812 r = pMsiGetProductInfoExA(prodcode, usersid,
5813 MSIINSTALLCONTEXT_USERUNMANAGED,
5814 INSTALLPROPERTY_HELPTELEPHONEA, NULL, NULL);
5815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5816
5817 /* pcchValue is exactly 5 */
5818 sz = 5;
5819 lstrcpyA(buf, "apple");
5820 r = pMsiGetProductInfoExA(prodcode, usersid,
5821 MSIINSTALLCONTEXT_USERUNMANAGED,
5822 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5823 ok(r == ERROR_MORE_DATA,
5824 "Expected ERROR_MORE_DATA, got %d\n", r);
5825 ok(sz == 10, "Expected 10, got %d\n", sz);
5826
5827 /* szValue is NULL, pcchValue is exactly 5 */
5828 sz = 5;
5829 r = pMsiGetProductInfoExA(prodcode, usersid,
5830 MSIINSTALLCONTEXT_USERUNMANAGED,
5831 INSTALLPROPERTY_HELPTELEPHONEA, NULL, &sz);
5832 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5833 ok(sz == 10, "Expected 10, got %d\n", sz);
5834
5835 /* szValue is NULL, pcchValue is MAX_PATH */
5836 sz = MAX_PATH;
5837 r = pMsiGetProductInfoExA(prodcode, usersid,
5838 MSIINSTALLCONTEXT_USERUNMANAGED,
5839 INSTALLPROPERTY_HELPTELEPHONEA, NULL, &sz);
5840 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5841 ok(sz == 10, "Expected 10, got %d\n", sz);
5842
5843 /* pcchValue is exactly 0 */
5844 sz = 0;
5845 lstrcpyA(buf, "apple");
5846 r = pMsiGetProductInfoExA(prodcode, usersid,
5847 MSIINSTALLCONTEXT_USERUNMANAGED,
5848 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5849 ok(r == ERROR_MORE_DATA,
5850 "Expected ERROR_MORE_DATA, got %d\n", r);
5851 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5852 ok(sz == 10, "Expected 10, got %d\n", sz);
5853
5854 res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
5855 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5856
5857 /* szProperty is not a valid property */
5858 sz = MAX_PATH;
5859 lstrcpyA(buf, "apple");
5860 r = pMsiGetProductInfoExA(prodcode, usersid,
5861 MSIINSTALLCONTEXT_USERUNMANAGED,
5862 "notvalid", buf, &sz);
5863 ok(r == ERROR_UNKNOWN_PROPERTY,
5864 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5865 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5866 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5867
5868 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5869 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5870
5871 /* InstallDate value exists */
5872 sz = MAX_PATH;
5873 lstrcpyA(buf, "apple");
5874 r = pMsiGetProductInfoExA(prodcode, usersid,
5875 MSIINSTALLCONTEXT_USERUNMANAGED,
5876 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
5877 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5878 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5879 ok(sz == 4, "Expected 4, got %d\n", sz);
5880
5881 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5882 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5883
5884 /* DisplayName value exists */
5885 sz = MAX_PATH;
5886 lstrcpyA(buf, "apple");
5887 r = pMsiGetProductInfoExA(prodcode, usersid,
5888 MSIINSTALLCONTEXT_USERUNMANAGED,
5889 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
5890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5891 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5892 ok(sz == 4, "Expected 4, got %d\n", sz);
5893
5894 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5895 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5896
5897 /* InstallLocation value exists */
5898 sz = MAX_PATH;
5899 lstrcpyA(buf, "apple");
5900 r = pMsiGetProductInfoExA(prodcode, usersid,
5901 MSIINSTALLCONTEXT_USERUNMANAGED,
5902 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
5903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5904 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5905 ok(sz == 3, "Expected 3, got %d\n", sz);
5906
5907 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5908 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5909
5910 /* InstallSource value exists */
5911 sz = MAX_PATH;
5912 lstrcpyA(buf, "apple");
5913 r = pMsiGetProductInfoExA(prodcode, usersid,
5914 MSIINSTALLCONTEXT_USERUNMANAGED,
5915 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
5916 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5917 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5918 ok(sz == 6, "Expected 6, got %d\n", sz);
5919
5920 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5921 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5922
5923 /* LocalPackage value exists */
5924 sz = MAX_PATH;
5925 lstrcpyA(buf, "apple");
5926 r = pMsiGetProductInfoExA(prodcode, usersid,
5927 MSIINSTALLCONTEXT_USERUNMANAGED,
5928 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
5929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5930 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5931 ok(sz == 5, "Expected 5, got %d\n", sz);
5932
5933 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5934 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5935
5936 /* Publisher value exists */
5937 sz = MAX_PATH;
5938 lstrcpyA(buf, "apple");
5939 r = pMsiGetProductInfoExA(prodcode, usersid,
5940 MSIINSTALLCONTEXT_USERUNMANAGED,
5941 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
5942 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5943 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5944 ok(sz == 3, "Expected 3, got %d\n", sz);
5945
5946 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5948
5949 /* URLInfoAbout value exists */
5950 sz = MAX_PATH;
5951 lstrcpyA(buf, "apple");
5952 r = pMsiGetProductInfoExA(prodcode, usersid,
5953 MSIINSTALLCONTEXT_USERUNMANAGED,
5954 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
5955 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5956 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5957 ok(sz == 5, "Expected 5, got %d\n", sz);
5958
5959 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5960 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5961
5962 /* URLUpdateInfo value exists */
5963 sz = MAX_PATH;
5964 lstrcpyA(buf, "apple");
5965 r = pMsiGetProductInfoExA(prodcode, usersid,
5966 MSIINSTALLCONTEXT_USERUNMANAGED,
5967 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
5968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5969 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5970 ok(sz == 6, "Expected 6, got %d\n", sz);
5971
5972 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5973 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5974
5975 /* VersionMinor value exists */
5976 sz = MAX_PATH;
5977 lstrcpyA(buf, "apple");
5978 r = pMsiGetProductInfoExA(prodcode, usersid,
5979 MSIINSTALLCONTEXT_USERUNMANAGED,
5980 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
5981 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5982 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5983 ok(sz == 1, "Expected 1, got %d\n", sz);
5984
5985 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5986 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5987
5988 /* VersionMajor value exists */
5989 sz = MAX_PATH;
5990 lstrcpyA(buf, "apple");
5991 r = pMsiGetProductInfoExA(prodcode, usersid,
5992 MSIINSTALLCONTEXT_USERUNMANAGED,
5993 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
5994 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5995 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5996 ok(sz == 1, "Expected 1, got %d\n", sz);
5997
5998 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5999 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6000
6001 /* DisplayVersion value exists */
6002 sz = MAX_PATH;
6003 lstrcpyA(buf, "apple");
6004 r = pMsiGetProductInfoExA(prodcode, usersid,
6005 MSIINSTALLCONTEXT_USERUNMANAGED,
6006 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6007 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6008 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6009 ok(sz == 5, "Expected 5, got %d\n", sz);
6010
6011 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6012 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6013
6014 /* ProductID value exists */
6015 sz = MAX_PATH;
6016 lstrcpyA(buf, "apple");
6017 r = pMsiGetProductInfoExA(prodcode, usersid,
6018 MSIINSTALLCONTEXT_USERUNMANAGED,
6019 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6021 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6022 ok(sz == 2, "Expected 2, got %d\n", sz);
6023
6024 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6025 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6026
6027 /* RegCompany value exists */
6028 sz = MAX_PATH;
6029 lstrcpyA(buf, "apple");
6030 r = pMsiGetProductInfoExA(prodcode, usersid,
6031 MSIINSTALLCONTEXT_USERUNMANAGED,
6032 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6033 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6034 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6035 ok(sz == 4, "Expected 4, got %d\n", sz);
6036
6037 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6038 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6039
6040 /* RegOwner value exists */
6041 sz = MAX_PATH;
6042 lstrcpyA(buf, "apple");
6043 r = pMsiGetProductInfoExA(prodcode, usersid,
6044 MSIINSTALLCONTEXT_USERUNMANAGED,
6045 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6046 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6047 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6048 ok(sz == 5, "Expected 5, got %d\n", sz);
6049
6050 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6051 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6052
6053 /* Transforms value exists */
6054 sz = MAX_PATH;
6055 lstrcpyA(buf, "apple");
6056 r = pMsiGetProductInfoExA(prodcode, usersid,
6057 MSIINSTALLCONTEXT_USERUNMANAGED,
6058 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6059 ok(r == ERROR_UNKNOWN_PRODUCT,
6060 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6061 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6062 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6063
6064 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6065 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6066
6067 /* Language value exists */
6068 sz = MAX_PATH;
6069 lstrcpyA(buf, "apple");
6070 r = pMsiGetProductInfoExA(prodcode, usersid,
6071 MSIINSTALLCONTEXT_USERUNMANAGED,
6072 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6073 ok(r == ERROR_UNKNOWN_PRODUCT,
6074 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6075 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6076 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6077
6078 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6079 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6080
6081 /* ProductName value exists */
6082 sz = MAX_PATH;
6083 lstrcpyA(buf, "apple");
6084 r = pMsiGetProductInfoExA(prodcode, usersid,
6085 MSIINSTALLCONTEXT_USERUNMANAGED,
6086 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6087 ok(r == ERROR_UNKNOWN_PRODUCT,
6088 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6089 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6090 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6091
6092 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6093 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6094
6095 /* FIXME */
6096
6097 /* AssignmentType value exists */
6098 sz = MAX_PATH;
6099 lstrcpyA(buf, "apple");
6100 r = pMsiGetProductInfoExA(prodcode, usersid,
6101 MSIINSTALLCONTEXT_USERUNMANAGED,
6102 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
6103 ok(r == ERROR_UNKNOWN_PRODUCT,
6104 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6105 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6106 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6107
6108 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6109 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6110
6111 /* PackageCode value exists */
6112 sz = MAX_PATH;
6113 lstrcpyA(buf, "apple");
6114 r = pMsiGetProductInfoExA(prodcode, usersid,
6115 MSIINSTALLCONTEXT_USERUNMANAGED,
6116 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
6117 ok(r == ERROR_UNKNOWN_PRODUCT,
6118 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6119 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6120 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6121
6122 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6123 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6124
6125 /* Version value exists */
6126 sz = MAX_PATH;
6127 lstrcpyA(buf, "apple");
6128 r = pMsiGetProductInfoExA(prodcode, usersid,
6129 MSIINSTALLCONTEXT_USERUNMANAGED,
6130 INSTALLPROPERTY_VERSIONA, buf, &sz);
6131 ok(r == ERROR_UNKNOWN_PRODUCT,
6132 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6133 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6134 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6135
6136 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6137 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6138
6139 /* ProductIcon value exists */
6140 sz = MAX_PATH;
6141 lstrcpyA(buf, "apple");
6142 r = pMsiGetProductInfoExA(prodcode, usersid,
6143 MSIINSTALLCONTEXT_USERUNMANAGED,
6144 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6145 ok(r == ERROR_UNKNOWN_PRODUCT,
6146 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6147 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6148 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6149
6150 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6151 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6152
6153 /* PackageName value exists */
6154 sz = MAX_PATH;
6155 lstrcpyA(buf, "apple");
6156 r = pMsiGetProductInfoExA(prodcode, usersid,
6157 MSIINSTALLCONTEXT_USERUNMANAGED,
6158 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
6159 ok(r == ERROR_UNKNOWN_PRODUCT,
6160 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6161 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6162 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6163
6164 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6165 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6166
6167 /* AuthorizedLUAApp value exists */
6168 sz = MAX_PATH;
6169 lstrcpyA(buf, "apple");
6170 r = pMsiGetProductInfoExA(prodcode, usersid,
6171 MSIINSTALLCONTEXT_USERUNMANAGED,
6172 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
6173 ok(r == ERROR_UNKNOWN_PRODUCT,
6174 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6175 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6176 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6177
6178 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6179 RegDeleteValueA(propkey, "PackageName");
6180 RegDeleteValueA(propkey, "ProductIcon");
6181 RegDeleteValueA(propkey, "Version");
6182 RegDeleteValueA(propkey, "PackageCode");
6183 RegDeleteValueA(propkey, "AssignmentType");
6184 RegDeleteValueA(propkey, "ProductName");
6185 RegDeleteValueA(propkey, "Language");
6186 RegDeleteValueA(propkey, "Transforms");
6187 RegDeleteValueA(propkey, "RegOwner");
6188 RegDeleteValueA(propkey, "RegCompany");
6189 RegDeleteValueA(propkey, "ProductID");
6190 RegDeleteValueA(propkey, "DisplayVersion");
6191 RegDeleteValueA(propkey, "VersionMajor");
6192 RegDeleteValueA(propkey, "VersionMinor");
6193 RegDeleteValueA(propkey, "URLUpdateInfo");
6194 RegDeleteValueA(propkey, "URLInfoAbout");
6195 RegDeleteValueA(propkey, "Publisher");
6196 RegDeleteValueA(propkey, "LocalPackage");
6197 RegDeleteValueA(propkey, "InstallSource");
6198 RegDeleteValueA(propkey, "InstallLocation");
6199 RegDeleteValueA(propkey, "DisplayName");
6200 RegDeleteValueA(propkey, "InstallDate");
6201 RegDeleteValueA(propkey, "HelpTelephone");
6202 RegDeleteValueA(propkey, "HelpLink");
6203 RegDeleteValueA(propkey, "LocalPackage");
6204 RegDeleteKeyA(propkey, "");
6205 RegCloseKey(propkey);
6206 RegDeleteKeyA(localkey, "");
6207 RegCloseKey(localkey);
6208
6209 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6210 lstrcatA(keypath, usersid);
6211 lstrcatA(keypath, "\\Installer\\Products\\");
6212 lstrcatA(keypath, prod_squashed);
6213
6214 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6215 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6216
6217 /* user product key exists */
6218 sz = MAX_PATH;
6219 lstrcpyA(buf, "apple");
6220 r = pMsiGetProductInfoExA(prodcode, usersid,
6221 MSIINSTALLCONTEXT_USERUNMANAGED,
6222 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6223 ok(r == ERROR_UNKNOWN_PRODUCT,
6224 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6225 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6226 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6227
6228 RegDeleteKeyA(userkey, "");
6229 RegCloseKey(userkey);
6230
6231 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6232 lstrcatA(keypath, prod_squashed);
6233
6234 res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6235 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6236
6237 sz = MAX_PATH;
6238 lstrcpyA(buf, "apple");
6239 r = pMsiGetProductInfoExA(prodcode, usersid,
6240 MSIINSTALLCONTEXT_USERUNMANAGED,
6241 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6242 ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
6243 if (r == ERROR_UNKNOWN_PRODUCT)
6244 {
6245 win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
6246 delete_key(prodkey, "", access);
6247 RegCloseKey(prodkey);
6248 return;
6249 }
6250 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6251 ok(sz == 1, "Expected 1, got %d\n", sz);
6252
6253 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6254 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6255
6256 /* HelpLink value exists */
6257 sz = MAX_PATH;
6258 lstrcpyA(buf, "apple");
6259 r = pMsiGetProductInfoExA(prodcode, usersid,
6260 MSIINSTALLCONTEXT_USERUNMANAGED,
6261 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6262 ok(r == ERROR_UNKNOWN_PROPERTY,
6263 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6264 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6265 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6266
6267 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6268 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6269
6270 /* HelpTelephone value exists */
6271 sz = MAX_PATH;
6272 lstrcpyA(buf, "apple");
6273 r = pMsiGetProductInfoExA(prodcode, usersid,
6274 MSIINSTALLCONTEXT_USERUNMANAGED,
6275 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6276 ok(r == ERROR_UNKNOWN_PROPERTY,
6277 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6278 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6279 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6280
6281 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6282 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6283
6284 /* InstallDate value exists */
6285 sz = MAX_PATH;
6286 lstrcpyA(buf, "apple");
6287 r = pMsiGetProductInfoExA(prodcode, usersid,
6288 MSIINSTALLCONTEXT_USERUNMANAGED,
6289 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6290 ok(r == ERROR_UNKNOWN_PROPERTY,
6291 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6292 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6293 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6294
6295 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6297
6298 /* DisplayName value exists */
6299 sz = MAX_PATH;
6300 lstrcpyA(buf, "apple");
6301 r = pMsiGetProductInfoExA(prodcode, usersid,
6302 MSIINSTALLCONTEXT_USERUNMANAGED,
6303 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6304 ok(r == ERROR_UNKNOWN_PROPERTY,
6305 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6306 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6307 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6308
6309 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6310 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6311
6312 /* InstallLocation value exists */
6313 sz = MAX_PATH;
6314 lstrcpyA(buf, "apple");
6315 r = pMsiGetProductInfoExA(prodcode, usersid,
6316 MSIINSTALLCONTEXT_USERUNMANAGED,
6317 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6318 ok(r == ERROR_UNKNOWN_PROPERTY,
6319 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6320 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6321 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6322
6323 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6324 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6325
6326 /* InstallSource value exists */
6327 sz = MAX_PATH;
6328 lstrcpyA(buf, "apple");
6329 r = pMsiGetProductInfoExA(prodcode, usersid,
6330 MSIINSTALLCONTEXT_USERUNMANAGED,
6331 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6332 ok(r == ERROR_UNKNOWN_PROPERTY,
6333 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6334 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6335 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6336
6337 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6338 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6339
6340 /* LocalPackage value exists */
6341 sz = MAX_PATH;
6342 lstrcpyA(buf, "apple");
6343 r = pMsiGetProductInfoExA(prodcode, usersid,
6344 MSIINSTALLCONTEXT_USERUNMANAGED,
6345 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6346 ok(r == ERROR_UNKNOWN_PROPERTY,
6347 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6348 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6349 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6350
6351 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6352 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6353
6354 /* Publisher value exists */
6355 sz = MAX_PATH;
6356 lstrcpyA(buf, "apple");
6357 r = pMsiGetProductInfoExA(prodcode, usersid,
6358 MSIINSTALLCONTEXT_USERUNMANAGED,
6359 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6360 ok(r == ERROR_UNKNOWN_PROPERTY,
6361 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6362 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6363 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6364
6365 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6366 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6367
6368 /* URLInfoAbout value exists */
6369 sz = MAX_PATH;
6370 lstrcpyA(buf, "apple");
6371 r = pMsiGetProductInfoExA(prodcode, usersid,
6372 MSIINSTALLCONTEXT_USERUNMANAGED,
6373 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6374 ok(r == ERROR_UNKNOWN_PROPERTY,
6375 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6376 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6377 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6378
6379 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6380 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6381
6382 /* URLUpdateInfo value exists */
6383 sz = MAX_PATH;
6384 lstrcpyA(buf, "apple");
6385 r = pMsiGetProductInfoExA(prodcode, usersid,
6386 MSIINSTALLCONTEXT_USERUNMANAGED,
6387 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6388 ok(r == ERROR_UNKNOWN_PROPERTY,
6389 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6390 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6391 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6392
6393 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6394 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6395
6396 /* VersionMinor value exists */
6397 sz = MAX_PATH;
6398 lstrcpyA(buf, "apple");
6399 r = pMsiGetProductInfoExA(prodcode, usersid,
6400 MSIINSTALLCONTEXT_USERUNMANAGED,
6401 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6402 ok(r == ERROR_UNKNOWN_PROPERTY,
6403 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6404 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6405 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6406
6407 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6408 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6409
6410 /* VersionMajor value exists */
6411 sz = MAX_PATH;
6412 lstrcpyA(buf, "apple");
6413 r = pMsiGetProductInfoExA(prodcode, usersid,
6414 MSIINSTALLCONTEXT_USERUNMANAGED,
6415 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6416 ok(r == ERROR_UNKNOWN_PROPERTY,
6417 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6418 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6419 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6420
6421 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6422 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6423
6424 /* DisplayVersion value exists */
6425 sz = MAX_PATH;
6426 lstrcpyA(buf, "apple");
6427 r = pMsiGetProductInfoExA(prodcode, usersid,
6428 MSIINSTALLCONTEXT_USERUNMANAGED,
6429 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6430 ok(r == ERROR_UNKNOWN_PROPERTY,
6431 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6432 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6433 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6434
6435 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6436 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6437
6438 /* ProductID value exists */
6439 sz = MAX_PATH;
6440 lstrcpyA(buf, "apple");
6441 r = pMsiGetProductInfoExA(prodcode, usersid,
6442 MSIINSTALLCONTEXT_USERUNMANAGED,
6443 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6444 ok(r == ERROR_UNKNOWN_PROPERTY,
6445 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6446 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6447 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6448
6449 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6450 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6451
6452 /* RegCompany value exists */
6453 sz = MAX_PATH;
6454 lstrcpyA(buf, "apple");
6455 r = pMsiGetProductInfoExA(prodcode, usersid,
6456 MSIINSTALLCONTEXT_USERUNMANAGED,
6457 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6458 ok(r == ERROR_UNKNOWN_PROPERTY,
6459 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6460 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6461 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6462
6463 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6464 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6465
6466 /* RegOwner value exists */
6467 sz = MAX_PATH;
6468 lstrcpyA(buf, "apple");
6469 r = pMsiGetProductInfoExA(prodcode, usersid,
6470 MSIINSTALLCONTEXT_USERUNMANAGED,
6471 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6472 ok(r == ERROR_UNKNOWN_PROPERTY,
6473 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6474 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6475 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6476
6477 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6478 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6479
6480 /* Transforms value exists */
6481 sz = MAX_PATH;
6482 lstrcpyA(buf, "apple");
6483 r = pMsiGetProductInfoExA(prodcode, usersid,
6484 MSIINSTALLCONTEXT_USERUNMANAGED,
6485 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6487 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6488 ok(sz == 5, "Expected 5, got %d\n", sz);
6489
6490 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6491 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6492
6493 /* Language value exists */
6494 sz = MAX_PATH;
6495 lstrcpyA(buf, "apple");
6496 r = pMsiGetProductInfoExA(prodcode, usersid,
6497 MSIINSTALLCONTEXT_USERUNMANAGED,
6498 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6500 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6501 ok(sz == 4, "Expected 4, got %d\n", sz);
6502
6503 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6504 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6505
6506 /* ProductName value exists */
6507 sz = MAX_PATH;
6508 lstrcpyA(buf, "apple");
6509 r = pMsiGetProductInfoExA(prodcode, usersid,
6510 MSIINSTALLCONTEXT_USERUNMANAGED,
6511 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6513 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6514 ok(sz == 4, "Expected 4, got %d\n", sz);
6515
6516 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6517 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6518
6519 /* FIXME */
6520
6521 /* AssignmentType value exists */
6522 sz = MAX_PATH;
6523 lstrcpyA(buf, "apple");
6524 r = pMsiGetProductInfoExA(prodcode, usersid,
6525 MSIINSTALLCONTEXT_USERUNMANAGED,
6526 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
6527 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6528 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6529 ok(sz == 0, "Expected 0, got %d\n", sz);
6530
6531 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6532 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6533
6534 /* FIXME */
6535
6536 /* PackageCode value exists */
6537 sz = MAX_PATH;
6538 lstrcpyA(buf, "apple");
6539 r = pMsiGetProductInfoExA(prodcode, usersid,
6540 MSIINSTALLCONTEXT_USERUNMANAGED,
6541 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
6542 todo_wine
6543 {
6544 ok(r == ERROR_BAD_CONFIGURATION,
6545 "Expected ERROR_BAD_CONFIGURATION, 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
6550 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6551 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6552
6553 /* Version value exists */
6554 sz = MAX_PATH;
6555 lstrcpyA(buf, "apple");
6556 r = pMsiGetProductInfoExA(prodcode, usersid,
6557 MSIINSTALLCONTEXT_USERUNMANAGED,
6558 INSTALLPROPERTY_VERSIONA, buf, &sz);
6559 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6560 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6561 ok(sz == 3, "Expected 3, got %d\n", sz);
6562
6563 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6564 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6565
6566 /* ProductIcon value exists */
6567 sz = MAX_PATH;
6568 lstrcpyA(buf, "apple");
6569 r = pMsiGetProductInfoExA(prodcode, usersid,
6570 MSIINSTALLCONTEXT_USERUNMANAGED,
6571 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6572 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6573 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6574 ok(sz == 4, "Expected 4, got %d\n", sz);
6575
6576 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6577 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6578
6579 /* PackageName value exists */
6580 sz = MAX_PATH;
6581 lstrcpyA(buf, "apple");
6582 r = pMsiGetProductInfoExA(prodcode, usersid,
6583 MSIINSTALLCONTEXT_USERUNMANAGED,
6584 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
6585 todo_wine
6586 {
6587 ok(r == ERROR_UNKNOWN_PRODUCT,
6588 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6589 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6590 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6591 }
6592
6593 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6594 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6595
6596 /* AuthorizedLUAApp value exists */
6597 sz = MAX_PATH;
6598 lstrcpyA(buf, "apple");
6599 r = pMsiGetProductInfoExA(prodcode, usersid,
6600 MSIINSTALLCONTEXT_USERUNMANAGED,
6601 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
6602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6603 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6604 ok(sz == 4, "Expected 4, got %d\n", sz);
6605
6606 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6607 RegDeleteValueA(prodkey, "PackageName");
6608 RegDeleteValueA(prodkey, "ProductIcon");
6609 RegDeleteValueA(prodkey, "Version");
6610 RegDeleteValueA(prodkey, "PackageCode");
6611 RegDeleteValueA(prodkey, "AssignmentType");
6612 RegDeleteValueA(prodkey, "ProductName");
6613 RegDeleteValueA(prodkey, "Language");
6614 RegDeleteValueA(prodkey, "Transforms");
6615 RegDeleteValueA(prodkey, "RegOwner");
6616 RegDeleteValueA(prodkey, "RegCompany");
6617 RegDeleteValueA(prodkey, "ProductID");
6618 RegDeleteValueA(prodkey, "DisplayVersion");
6619 RegDeleteValueA(prodkey, "VersionMajor");
6620 RegDeleteValueA(prodkey, "VersionMinor");
6621 RegDeleteValueA(prodkey, "URLUpdateInfo");
6622 RegDeleteValueA(prodkey, "URLInfoAbout");
6623 RegDeleteValueA(prodkey, "Publisher");
6624 RegDeleteValueA(prodkey, "LocalPackage");
6625 RegDeleteValueA(prodkey, "InstallSource");
6626 RegDeleteValueA(prodkey, "InstallLocation");
6627 RegDeleteValueA(prodkey, "DisplayName");
6628 RegDeleteValueA(prodkey, "InstallDate");
6629 RegDeleteValueA(prodkey, "HelpTelephone");
6630 RegDeleteValueA(prodkey, "HelpLink");
6631 RegDeleteValueA(prodkey, "LocalPackage");
6632 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6633 RegCloseKey(prodkey);
6634
6635 /* MSIINSTALLCONTEXT_USERMANAGED */
6636
6637 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
6638 lstrcatA(keypath, usersid);
6639 lstrcatA(keypath, "\\Products\\");
6640 lstrcatA(keypath, prod_squashed);
6641
6642 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6643 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6644
6645 /* local user product key exists */
6646 sz = MAX_PATH;
6647 lstrcpyA(buf, "apple");
6648 r = pMsiGetProductInfoExA(prodcode, usersid,
6649 MSIINSTALLCONTEXT_USERMANAGED,
6650 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6651 ok(r == ERROR_UNKNOWN_PRODUCT,
6652 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6653 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6654 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6655
6656 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6657 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6658
6659 /* InstallProperties key exists */
6660 sz = MAX_PATH;
6661 lstrcpyA(buf, "apple");
6662 r = pMsiGetProductInfoExA(prodcode, usersid,
6663 MSIINSTALLCONTEXT_USERMANAGED,
6664 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6665 ok(r == ERROR_UNKNOWN_PRODUCT,
6666 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6667 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6668 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6669
6670 res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6671 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6672
6673 /* ManagedLocalPackage value exists */
6674 sz = MAX_PATH;
6675 lstrcpyA(buf, "apple");
6676 r = pMsiGetProductInfoExA(prodcode, usersid,
6677 MSIINSTALLCONTEXT_USERMANAGED,
6678 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6679 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6680 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6681 ok(sz == 1, "Expected 1, got %d\n", sz);
6682
6683 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6685
6686 /* HelpLink value exists */
6687 sz = MAX_PATH;
6688 lstrcpyA(buf, "apple");
6689 r = pMsiGetProductInfoExA(prodcode, usersid,
6690 MSIINSTALLCONTEXT_USERMANAGED,
6691 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6693 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6694 ok(sz == 4, "Expected 4, got %d\n", sz);
6695
6696 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6698
6699 /* HelpTelephone value exists */
6700 sz = MAX_PATH;
6701 lstrcpyA(buf, "apple");
6702 r = pMsiGetProductInfoExA(prodcode, usersid,
6703 MSIINSTALLCONTEXT_USERMANAGED,
6704 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6705 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6706 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6707 ok(sz == 5, "Expected 5, got %d\n", sz);
6708
6709 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6710 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6711
6712 /* InstallDate value exists */
6713 sz = MAX_PATH;
6714 lstrcpyA(buf, "apple");
6715 r = pMsiGetProductInfoExA(prodcode, usersid,
6716 MSIINSTALLCONTEXT_USERMANAGED,
6717 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6719 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6720 ok(sz == 4, "Expected 4, got %d\n", sz);
6721
6722 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6723 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6724
6725 /* DisplayName value exists */
6726 sz = MAX_PATH;
6727 lstrcpyA(buf, "apple");
6728 r = pMsiGetProductInfoExA(prodcode, usersid,
6729 MSIINSTALLCONTEXT_USERMANAGED,
6730 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6732 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6733 ok(sz == 4, "Expected 4, got %d\n", sz);
6734
6735 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6736 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6737
6738 /* InstallLocation value exists */
6739 sz = MAX_PATH;
6740 lstrcpyA(buf, "apple");
6741 r = pMsiGetProductInfoExA(prodcode, usersid,
6742 MSIINSTALLCONTEXT_USERMANAGED,
6743 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6744 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6745 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6746 ok(sz == 3, "Expected 3, got %d\n", sz);
6747
6748 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6749 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6750
6751 /* InstallSource value exists */
6752 sz = MAX_PATH;
6753 lstrcpyA(buf, "apple");
6754 r = pMsiGetProductInfoExA(prodcode, usersid,
6755 MSIINSTALLCONTEXT_USERMANAGED,
6756 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6758 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6759 ok(sz == 6, "Expected 6, got %d\n", sz);
6760
6761 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6762 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6763
6764 /* LocalPackage value exists */
6765 sz = MAX_PATH;
6766 lstrcpyA(buf, "apple");
6767 r = pMsiGetProductInfoExA(prodcode, usersid,
6768 MSIINSTALLCONTEXT_USERMANAGED,
6769 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6770 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6771 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6772 ok(sz == 5, "Expected 5, got %d\n", sz);
6773
6774 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6775 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6776
6777 /* Publisher value exists */
6778 sz = MAX_PATH;
6779 lstrcpyA(buf, "apple");
6780 r = pMsiGetProductInfoExA(prodcode, usersid,
6781 MSIINSTALLCONTEXT_USERMANAGED,
6782 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6783 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6784 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6785 ok(sz == 3, "Expected 3, got %d\n", sz);
6786
6787 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6788 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6789
6790 /* URLInfoAbout value exists */
6791 sz = MAX_PATH;
6792 lstrcpyA(buf, "apple");
6793 r = pMsiGetProductInfoExA(prodcode, usersid,
6794 MSIINSTALLCONTEXT_USERMANAGED,
6795 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6796 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6797 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6798 ok(sz == 5, "Expected 5, got %d\n", sz);
6799
6800 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6802
6803 /* URLUpdateInfo value exists */
6804 sz = MAX_PATH;
6805 lstrcpyA(buf, "apple");
6806 r = pMsiGetProductInfoExA(prodcode, usersid,
6807 MSIINSTALLCONTEXT_USERMANAGED,
6808 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6809 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6810 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6811 ok(sz == 6, "Expected 6, got %d\n", sz);
6812
6813 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6814 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6815
6816 /* VersionMinor value exists */
6817 sz = MAX_PATH;
6818 lstrcpyA(buf, "apple");
6819 r = pMsiGetProductInfoExA(prodcode, usersid,
6820 MSIINSTALLCONTEXT_USERMANAGED,
6821 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6823 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6824 ok(sz == 1, "Expected 1, got %d\n", sz);
6825
6826 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6827 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6828
6829 /* VersionMajor value exists */
6830 sz = MAX_PATH;
6831 lstrcpyA(buf, "apple");
6832 r = pMsiGetProductInfoExA(prodcode, usersid,
6833 MSIINSTALLCONTEXT_USERMANAGED,
6834 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6836 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6837 ok(sz == 1, "Expected 1, got %d\n", sz);
6838
6839 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6841
6842 /* DisplayVersion value exists */
6843 sz = MAX_PATH;
6844 lstrcpyA(buf, "apple");
6845 r = pMsiGetProductInfoExA(prodcode, usersid,
6846 MSIINSTALLCONTEXT_USERMANAGED,
6847 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6849 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6850 ok(sz == 5, "Expected 5, got %d\n", sz);
6851
6852 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6853 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6854
6855 /* ProductID value exists */
6856 sz = MAX_PATH;
6857 lstrcpyA(buf, "apple");
6858 r = pMsiGetProductInfoExA(prodcode, usersid,
6859 MSIINSTALLCONTEXT_USERMANAGED,
6860 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6861 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6862 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6863 ok(sz == 2, "Expected 2, got %d\n", sz);
6864
6865 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6866 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6867
6868 /* RegCompany value exists */
6869 sz = MAX_PATH;
6870 lstrcpyA(buf, "apple");
6871 r = pMsiGetProductInfoExA(prodcode, usersid,
6872 MSIINSTALLCONTEXT_USERMANAGED,
6873 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6874 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6875 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6876 ok(sz == 4, "Expected 4, got %d\n", sz);
6877
6878 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6879 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6880
6881 /* RegOwner value exists */
6882 sz = MAX_PATH;
6883 lstrcpyA(buf, "apple");
6884 r = pMsiGetProductInfoExA(prodcode, usersid,
6885 MSIINSTALLCONTEXT_USERMANAGED,
6886 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6887 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6888 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6889 ok(sz == 5, "Expected 5, got %d\n", sz);
6890
6891 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6892 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6893
6894 /* Transforms value exists */
6895 sz = MAX_PATH;
6896 lstrcpyA(buf, "apple");
6897 r = pMsiGetProductInfoExA(prodcode, usersid,
6898 MSIINSTALLCONTEXT_USERMANAGED,
6899 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6900 ok(r == ERROR_UNKNOWN_PRODUCT,
6901 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6902 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6903 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6904
6905 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6906 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6907
6908 /* Language value exists */
6909 sz = MAX_PATH;
6910 lstrcpyA(buf, "apple");
6911 r = pMsiGetProductInfoExA(prodcode, usersid,
6912 MSIINSTALLCONTEXT_USERMANAGED,
6913 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6914 ok(r == ERROR_UNKNOWN_PRODUCT,
6915 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6916 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6917 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6918
6919 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6920 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6921
6922 /* ProductName value exists */
6923 sz = MAX_PATH;
6924 lstrcpyA(buf, "apple");
6925 r = pMsiGetProductInfoExA(prodcode, usersid,
6926 MSIINSTALLCONTEXT_USERMANAGED,
6927 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6928 ok(r == ERROR_UNKNOWN_PRODUCT,
6929 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6930 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6931 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6932
6933 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6934 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6935
6936 /* FIXME */
6937
6938 /* AssignmentType value exists */
6939 sz = MAX_PATH;
6940 lstrcpyA(buf, "apple");
6941 r = pMsiGetProductInfoExA(prodcode, usersid,
6942 MSIINSTALLCONTEXT_USERMANAGED,
6943 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
6944 ok(r == ERROR_UNKNOWN_PRODUCT,
6945 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6946 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6947 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6948
6949 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6950 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6951
6952 /* PackageCode value exists */
6953 sz = MAX_PATH;
6954 lstrcpyA(buf, "apple");
6955 r = pMsiGetProductInfoExA(prodcode, usersid,
6956 MSIINSTALLCONTEXT_USERMANAGED,
6957 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
6958 ok(r == ERROR_UNKNOWN_PRODUCT,
6959 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6960 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6961 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6962
6963 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6964 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6965
6966 /* Version value exists */
6967 sz = MAX_PATH;
6968 lstrcpyA(buf, "apple");
6969 r = pMsiGetProductInfoExA(prodcode, usersid,
6970 MSIINSTALLCONTEXT_USERMANAGED,
6971 INSTALLPROPERTY_VERSIONA, buf, &sz);
6972 ok(r == ERROR_UNKNOWN_PRODUCT,
6973 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6974 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6975 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6976
6977 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6978 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6979
6980 /* ProductIcon value exists */
6981 sz = MAX_PATH;
6982 lstrcpyA(buf, "apple");
6983 r = pMsiGetProductInfoExA(prodcode, usersid,
6984 MSIINSTALLCONTEXT_USERMANAGED,
6985 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6986 ok(r == ERROR_UNKNOWN_PRODUCT,
6987 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6988 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6989 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6990
6991 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6992 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6993
6994 /* PackageName value exists */
6995 sz = MAX_PATH;
6996 lstrcpyA(buf, "apple");
6997 r = pMsiGetProductInfoExA(prodcode, usersid,
6998 MSIINSTALLCONTEXT_USERMANAGED,
6999 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7000 ok(r == ERROR_UNKNOWN_PRODUCT,
7001 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7002 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7003 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7004
7005 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7006 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7007
7008 /* AuthorizedLUAApp value exists */
7009 sz = MAX_PATH;
7010 lstrcpyA(buf, "apple");
7011 r = pMsiGetProductInfoExA(prodcode, usersid,
7012 MSIINSTALLCONTEXT_USERMANAGED,
7013 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7014 ok(r == ERROR_UNKNOWN_PRODUCT,
7015 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7016 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7017 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7018
7019 RegDeleteValueA(propkey, "AuthorizedLUAApp");
7020 RegDeleteValueA(propkey, "PackageName");
7021 RegDeleteValueA(propkey, "ProductIcon");
7022 RegDeleteValueA(propkey, "Version");
7023 RegDeleteValueA(propkey, "PackageCode");
7024 RegDeleteValueA(propkey, "AssignmentType");
7025 RegDeleteValueA(propkey, "ProductName");
7026 RegDeleteValueA(propkey, "Language");
7027 RegDeleteValueA(propkey, "Transforms");
7028 RegDeleteValueA(propkey, "RegOwner");
7029 RegDeleteValueA(propkey, "RegCompany");
7030 RegDeleteValueA(propkey, "ProductID");
7031 RegDeleteValueA(propkey, "DisplayVersion");
7032 RegDeleteValueA(propkey, "VersionMajor");
7033 RegDeleteValueA(propkey, "VersionMinor");
7034 RegDeleteValueA(propkey, "URLUpdateInfo");
7035 RegDeleteValueA(propkey, "URLInfoAbout");
7036 RegDeleteValueA(propkey, "Publisher");
7037 RegDeleteValueA(propkey, "LocalPackage");
7038 RegDeleteValueA(propkey, "InstallSource");
7039 RegDeleteValueA(propkey, "InstallLocation");
7040 RegDeleteValueA(propkey, "DisplayName");
7041 RegDeleteValueA(propkey, "InstallDate");
7042 RegDeleteValueA(propkey, "HelpTelephone");
7043 RegDeleteValueA(propkey, "HelpLink");
7044 RegDeleteValueA(propkey, "ManagedLocalPackage");
7045 delete_key(propkey, "", access & KEY_WOW64_64KEY);
7046 RegCloseKey(propkey);
7047 delete_key(localkey, "", access & KEY_WOW64_64KEY);
7048 RegCloseKey(localkey);
7049
7050 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7051 lstrcatA(keypath, usersid);
7052 lstrcatA(keypath, "\\Installer\\Products\\");
7053 lstrcatA(keypath, prod_squashed);
7054
7055 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7056 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7057
7058 /* user product key exists */
7059 sz = MAX_PATH;
7060 lstrcpyA(buf, "apple");
7061 r = pMsiGetProductInfoExA(prodcode, usersid,
7062 MSIINSTALLCONTEXT_USERMANAGED,
7063 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7065 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
7066 ok(sz == 1, "Expected 1, got %d\n", sz);
7067
7068 delete_key(userkey, "", access & KEY_WOW64_64KEY);
7069 RegCloseKey(userkey);
7070
7071 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7072 lstrcatA(keypath, prod_squashed);
7073
7074 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7075 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7076
7077 /* current user product key exists */
7078 sz = MAX_PATH;
7079 lstrcpyA(buf, "apple");
7080 r = pMsiGetProductInfoExA(prodcode, usersid,
7081 MSIINSTALLCONTEXT_USERMANAGED,
7082 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7083 ok(r == ERROR_UNKNOWN_PRODUCT,
7084 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7085 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7086 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7087
7088 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7089 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7090
7091 /* HelpLink value exists, user product key does not exist */
7092 sz = MAX_PATH;
7093 lstrcpyA(buf, "apple");
7094 r = pMsiGetProductInfoExA(prodcode, usersid,
7095 MSIINSTALLCONTEXT_USERMANAGED,
7096 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7097 ok(r == ERROR_UNKNOWN_PRODUCT,
7098 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7099 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7100 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7101
7102 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7103 lstrcatA(keypath, usersid);
7104 lstrcatA(keypath, "\\Installer\\Products\\");
7105 lstrcatA(keypath, prod_squashed);
7106
7107 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7108 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7109
7110 res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7111 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7112
7113 /* HelpLink value exists, user product key does exist */
7114 sz = MAX_PATH;
7115 lstrcpyA(buf, "apple");
7116 r = pMsiGetProductInfoExA(prodcode, usersid,
7117 MSIINSTALLCONTEXT_USERMANAGED,
7118 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7119 ok(r == ERROR_UNKNOWN_PROPERTY,
7120 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7121 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7122 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7123
7124 res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7125 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7126
7127 /* HelpTelephone value exists */
7128 sz = MAX_PATH;
7129 lstrcpyA(buf, "apple");
7130 r = pMsiGetProductInfoExA(prodcode, usersid,
7131 MSIINSTALLCONTEXT_USERMANAGED,
7132 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7133 ok(r == ERROR_UNKNOWN_PROPERTY,
7134 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7135 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7136 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7137
7138 res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7139 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7140
7141 /* InstallDate value exists */
7142 sz = MAX_PATH;
7143 lstrcpyA(buf, "apple");
7144 r = pMsiGetProductInfoExA(prodcode, usersid,
7145 MSIINSTALLCONTEXT_USERMANAGED,
7146 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7147 ok(r == ERROR_UNKNOWN_PROPERTY,
7148 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7149 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7150 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7151
7152 res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7153 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7154
7155 /* DisplayName value exists */
7156 sz = MAX_PATH;
7157 lstrcpyA(buf, "apple");
7158 r = pMsiGetProductInfoExA(prodcode, usersid,
7159 MSIINSTALLCONTEXT_USERMANAGED,
7160 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7161 ok(r == ERROR_UNKNOWN_PROPERTY,
7162 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7163 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7164 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7165
7166 res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7167 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7168
7169 /* InstallLocation value exists */
7170 sz = MAX_PATH;
7171 lstrcpyA(buf, "apple");
7172 r = pMsiGetProductInfoExA(prodcode, usersid,
7173 MSIINSTALLCONTEXT_USERMANAGED,
7174 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7175 ok(r == ERROR_UNKNOWN_PROPERTY,
7176 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7177 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7178 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7179
7180 res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7181 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7182
7183 /* InstallSource value exists */
7184 sz = MAX_PATH;
7185 lstrcpyA(buf, "apple");
7186 r = pMsiGetProductInfoExA(prodcode, usersid,
7187 MSIINSTALLCONTEXT_USERMANAGED,
7188 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7189 ok(r == ERROR_UNKNOWN_PROPERTY,
7190 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7191 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7192 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7193
7194 res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7195 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7196
7197 /* LocalPackage value exists */
7198 sz = MAX_PATH;
7199 lstrcpyA(buf, "apple");
7200 r = pMsiGetProductInfoExA(prodcode, usersid,
7201 MSIINSTALLCONTEXT_USERMANAGED,
7202 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7203 ok(r == ERROR_UNKNOWN_PROPERTY,
7204 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7205 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7206 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7207
7208 res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7209 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7210
7211 /* Publisher value exists */
7212 sz = MAX_PATH;
7213 lstrcpyA(buf, "apple");
7214 r = pMsiGetProductInfoExA(prodcode, usersid,
7215 MSIINSTALLCONTEXT_USERMANAGED,
7216 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7217 ok(r == ERROR_UNKNOWN_PROPERTY,
7218 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7219 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7220 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7221
7222 res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7223 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7224
7225 /* URLInfoAbout value exists */
7226 sz = MAX_PATH;
7227 lstrcpyA(buf, "apple");
7228 r = pMsiGetProductInfoExA(prodcode, usersid,
7229 MSIINSTALLCONTEXT_USERMANAGED,
7230 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7231 ok(r == ERROR_UNKNOWN_PROPERTY,
7232 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7233 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7234 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7235
7236 res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7238
7239 /* URLUpdateInfo value exists */
7240 sz = MAX_PATH;
7241 lstrcpyA(buf, "apple");
7242 r = pMsiGetProductInfoExA(prodcode, usersid,
7243 MSIINSTALLCONTEXT_USERMANAGED,
7244 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7245 ok(r == ERROR_UNKNOWN_PROPERTY,
7246 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7247 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7248 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7249
7250 res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7251 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7252
7253 /* VersionMinor value exists */
7254 sz = MAX_PATH;
7255 lstrcpyA(buf, "apple");
7256 r = pMsiGetProductInfoExA(prodcode, usersid,
7257 MSIINSTALLCONTEXT_USERMANAGED,
7258 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7259 ok(r == ERROR_UNKNOWN_PROPERTY,
7260 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7261 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7262 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7263
7264 res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7265 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7266
7267 /* VersionMajor value exists */
7268 sz = MAX_PATH;
7269 lstrcpyA(buf, "apple");
7270 r = pMsiGetProductInfoExA(prodcode, usersid,
7271 MSIINSTALLCONTEXT_USERMANAGED,
7272 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7273 ok(r == ERROR_UNKNOWN_PROPERTY,
7274 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7275 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7276 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7277
7278 res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7279 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7280
7281 /* DisplayVersion value exists */
7282 sz = MAX_PATH;
7283 lstrcpyA(buf, "apple");
7284 r = pMsiGetProductInfoExA(prodcode, usersid,
7285 MSIINSTALLCONTEXT_USERMANAGED,
7286 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7287 ok(r == ERROR_UNKNOWN_PROPERTY,
7288 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7289 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7290 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7291
7292 res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7293 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7294
7295 /* ProductID value exists */
7296 sz = MAX_PATH;
7297 lstrcpyA(buf, "apple");
7298 r = pMsiGetProductInfoExA(prodcode, usersid,
7299 MSIINSTALLCONTEXT_USERMANAGED,
7300 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7301 ok(r == ERROR_UNKNOWN_PROPERTY,
7302 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7303 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7304 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7305
7306 res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7307 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7308
7309 /* RegCompany value exists */
7310 sz = MAX_PATH;
7311 lstrcpyA(buf, "apple");
7312 r = pMsiGetProductInfoExA(prodcode, usersid,
7313 MSIINSTALLCONTEXT_USERMANAGED,
7314 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7315 ok(r == ERROR_UNKNOWN_PROPERTY,
7316 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7317 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7318 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7319
7320 res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7321 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7322
7323 /* RegOwner value exists */
7324 sz = MAX_PATH;
7325 lstrcpyA(buf, "apple");
7326 r = pMsiGetProductInfoExA(prodcode, usersid,
7327 MSIINSTALLCONTEXT_USERMANAGED,
7328 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7329 ok(r == ERROR_UNKNOWN_PROPERTY,
7330 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7331 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7332 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7333
7334 res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7335 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7336
7337 /* Transforms value exists */
7338 sz = MAX_PATH;
7339 lstrcpyA(buf, "apple");
7340 r = pMsiGetProductInfoExA(prodcode, usersid,
7341 MSIINSTALLCONTEXT_USERMANAGED,
7342 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7343 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7344 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
7345 ok(sz == 5, "Expected 5, got %d\n", sz);
7346
7347 res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7348 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7349
7350 /* Language value exists */
7351 sz = MAX_PATH;
7352 lstrcpyA(buf, "apple");
7353 r = pMsiGetProductInfoExA(prodcode, usersid,
7354 MSIINSTALLCONTEXT_USERMANAGED,
7355 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7357 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
7358 ok(sz == 4, "Expected 4, got %d\n", sz);
7359
7360 res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7361 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7362
7363 /* ProductName value exists */
7364 sz = MAX_PATH;
7365 lstrcpyA(buf, "apple");
7366 r = pMsiGetProductInfoExA(prodcode, usersid,
7367 MSIINSTALLCONTEXT_USERMANAGED,
7368 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7369 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7370 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7371 ok(sz == 4, "Expected 4, got %d\n", sz);
7372
7373 res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7375
7376 /* FIXME */
7377
7378 /* AssignmentType value exists */
7379 sz = MAX_PATH;
7380 lstrcpyA(buf, "apple");
7381 r = pMsiGetProductInfoExA(prodcode, usersid,
7382 MSIINSTALLCONTEXT_USERMANAGED,
7383 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7384 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7385 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7386 ok(sz == 0, "Expected 0, got %d\n", sz);
7387
7388 res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7390
7391 /* FIXME */
7392
7393 /* PackageCode value exists */
7394 sz = MAX_PATH;
7395 lstrcpyA(buf, "apple");
7396 r = pMsiGetProductInfoExA(prodcode, usersid,
7397 MSIINSTALLCONTEXT_USERMANAGED,
7398 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7399 todo_wine
7400 {
7401 ok(r == ERROR_BAD_CONFIGURATION,
7402 "Expected ERROR_BAD_CONFIGURATION, 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
7407 res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7408 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7409
7410 /* Version value exists */
7411 sz = MAX_PATH;
7412 lstrcpyA(buf, "apple");
7413 r = pMsiGetProductInfoExA(prodcode, usersid,
7414 MSIINSTALLCONTEXT_USERMANAGED,
7415 INSTALLPROPERTY_VERSIONA, buf, &sz);
7416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7417 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7418 ok(sz == 3, "Expected 3, got %d\n", sz);
7419
7420 res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7421 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7422
7423 /* ProductIcon value exists */
7424 sz = MAX_PATH;
7425 lstrcpyA(buf, "apple");
7426 r = pMsiGetProductInfoExA(prodcode, usersid,
7427 MSIINSTALLCONTEXT_USERMANAGED,
7428 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7429 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7430 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7431 ok(sz == 4, "Expected 4, got %d\n", sz);
7432
7433 res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7435
7436 /* PackageName value exists */
7437 sz = MAX_PATH;
7438 lstrcpyA(buf, "apple");
7439 r = pMsiGetProductInfoExA(prodcode, usersid,
7440 MSIINSTALLCONTEXT_USERMANAGED,
7441 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7442 todo_wine
7443 {
7444 ok(r == ERROR_UNKNOWN_PRODUCT,
7445 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7446 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7447 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7448 }
7449
7450 res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7451 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7452
7453 /* AuthorizedLUAApp value exists */
7454 sz = MAX_PATH;
7455 lstrcpyA(buf, "apple");
7456 r = pMsiGetProductInfoExA(prodcode, usersid,
7457 MSIINSTALLCONTEXT_USERMANAGED,
7458 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7459 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7460 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7461 ok(sz == 4, "Expected 4, got %d\n", sz);
7462
7463 RegDeleteValueA(userkey, "AuthorizedLUAApp");
7464 RegDeleteValueA(userkey, "PackageName");
7465 RegDeleteValueA(userkey, "ProductIcon");
7466 RegDeleteValueA(userkey, "Version");
7467 RegDeleteValueA(userkey, "PackageCode");
7468 RegDeleteValueA(userkey, "AssignmentType");
7469 RegDeleteValueA(userkey, "ProductName");
7470 RegDeleteValueA(userkey, "Language");
7471 RegDeleteValueA(userkey, "Transforms");
7472 RegDeleteValueA(userkey, "RegOwner");
7473 RegDeleteValueA(userkey, "RegCompany");
7474 RegDeleteValueA(userkey, "ProductID");
7475 RegDeleteValueA(userkey, "DisplayVersion");
7476 RegDeleteValueA(userkey, "VersionMajor");
7477 RegDeleteValueA(userkey, "VersionMinor");
7478 RegDeleteValueA(userkey, "URLUpdateInfo");
7479 RegDeleteValueA(userkey, "URLInfoAbout");
7480 RegDeleteValueA(userkey, "Publisher");
7481 RegDeleteValueA(userkey, "LocalPackage");
7482 RegDeleteValueA(userkey, "InstallSource");
7483 RegDeleteValueA(userkey, "InstallLocation");
7484 RegDeleteValueA(userkey, "DisplayName");
7485 RegDeleteValueA(userkey, "InstallDate");
7486 RegDeleteValueA(userkey, "HelpTelephone");
7487 RegDeleteValueA(userkey, "HelpLink");
7488 delete_key(userkey, "", access & KEY_WOW64_64KEY);
7489 RegCloseKey(userkey);
7490 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7491 RegCloseKey(prodkey);
7492
7493 /* MSIINSTALLCONTEXT_MACHINE */
7494
7495 /* szUserSid is non-NULL */
7496 sz = MAX_PATH;
7497 lstrcpyA(buf, "apple");
7498 r = pMsiGetProductInfoExA(prodcode, usersid,
7499 MSIINSTALLCONTEXT_MACHINE,
7500 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7501 ok(r == ERROR_INVALID_PARAMETER,
7502 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7503 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7504 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7505
7506 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
7507 lstrcatA(keypath, prod_squashed);
7508
7509 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
7510 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7511
7512 /* local system product key exists */
7513 sz = MAX_PATH;
7514 lstrcpyA(buf, "apple");
7515 r = pMsiGetProductInfoExA(prodcode, NULL,
7516 MSIINSTALLCONTEXT_MACHINE,
7517 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7518 ok(r == ERROR_UNKNOWN_PRODUCT,
7519 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7520 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7521 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7522
7523 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
7524 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7525
7526 /* InstallProperties key exists */
7527 sz = MAX_PATH;
7528 lstrcpyA(buf, "apple");
7529 r = pMsiGetProductInfoExA(prodcode, NULL,
7530 MSIINSTALLCONTEXT_MACHINE,
7531 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7532 ok(r == ERROR_UNKNOWN_PRODUCT,
7533 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7534 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7535 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7536
7537 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7538 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7539
7540 /* LocalPackage value exists */
7541 sz = MAX_PATH;
7542 lstrcpyA(buf, "apple");
7543 r = pMsiGetProductInfoExA(prodcode, NULL,
7544 MSIINSTALLCONTEXT_MACHINE,
7545 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7547 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
7548 ok(sz == 1, "Expected 1, got %d\n", sz);
7549
7550 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7551 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7552
7553 /* HelpLink value exists */
7554 sz = MAX_PATH;
7555 lstrcpyA(buf, "apple");
7556 r = pMsiGetProductInfoExA(prodcode, NULL,
7557 MSIINSTALLCONTEXT_MACHINE,
7558 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7559 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7560 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
7561 ok(sz == 4, "Expected 4, got %d\n", sz);
7562
7563 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7564 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7565
7566 /* HelpTelephone value exists */
7567 sz = MAX_PATH;
7568 lstrcpyA(buf, "apple");
7569 r = pMsiGetProductInfoExA(prodcode, NULL,
7570 MSIINSTALLCONTEXT_MACHINE,
7571 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7572 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7573 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
7574 ok(sz == 5, "Expected 5, got %d\n", sz);
7575
7576 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7577 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7578
7579 /* InstallDate value exists */
7580 sz = MAX_PATH;
7581 lstrcpyA(buf, "apple");
7582 r = pMsiGetProductInfoExA(prodcode, NULL,
7583 MSIINSTALLCONTEXT_MACHINE,
7584 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7585 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7586 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
7587 ok(sz == 4, "Expected 4, got %d\n", sz);
7588
7589 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7590 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7591
7592 /* DisplayName value exists */
7593 sz = MAX_PATH;
7594 lstrcpyA(buf, "apple");
7595 r = pMsiGetProductInfoExA(prodcode, NULL,
7596 MSIINSTALLCONTEXT_MACHINE,
7597 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7598 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7599 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7600 ok(sz == 4, "Expected 4, got %d\n", sz);
7601
7602 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7603 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7604
7605 /* InstallLocation value exists */
7606 sz = MAX_PATH;
7607 lstrcpyA(buf, "apple");
7608 r = pMsiGetProductInfoExA(prodcode, NULL,
7609 MSIINSTALLCONTEXT_MACHINE,
7610 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7612 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
7613 ok(sz == 3, "Expected 3, got %d\n", sz);
7614
7615 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7616 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7617
7618 /* InstallSource value exists */
7619 sz = MAX_PATH;
7620 lstrcpyA(buf, "apple");
7621 r = pMsiGetProductInfoExA(prodcode, NULL,
7622 MSIINSTALLCONTEXT_MACHINE,
7623 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7624 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7625 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
7626 ok(sz == 6, "Expected 6, got %d\n", sz);
7627
7628 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7629 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7630
7631 /* LocalPackage value exists */
7632 sz = MAX_PATH;
7633 lstrcpyA(buf, "apple");
7634 r = pMsiGetProductInfoExA(prodcode, NULL,
7635 MSIINSTALLCONTEXT_MACHINE,
7636 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7638 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
7639 ok(sz == 5, "Expected 5, got %d\n", sz);
7640
7641 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7642 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7643
7644 /* Publisher value exists */
7645 sz = MAX_PATH;
7646 lstrcpyA(buf, "apple");
7647 r = pMsiGetProductInfoExA(prodcode, NULL,
7648 MSIINSTALLCONTEXT_MACHINE,
7649 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7650 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7651 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
7652 ok(sz == 3, "Expected 3, got %d\n", sz);
7653
7654 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7655 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7656
7657 /* URLInfoAbout value exists */
7658 sz = MAX_PATH;
7659 lstrcpyA(buf, "apple");
7660 r = pMsiGetProductInfoExA(prodcode, NULL,
7661 MSIINSTALLCONTEXT_MACHINE,
7662 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7664 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
7665 ok(sz == 5, "Expected 5, got %d\n", sz);
7666
7667 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7668 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7669
7670 /* URLUpdateInfo value exists */
7671 sz = MAX_PATH;
7672 lstrcpyA(buf, "apple");
7673 r = pMsiGetProductInfoExA(prodcode, NULL,
7674 MSIINSTALLCONTEXT_MACHINE,
7675 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7676 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7677 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
7678 ok(sz == 6, "Expected 6, got %d\n", sz);
7679
7680 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7681 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7682
7683 /* VersionMinor value exists */
7684 sz = MAX_PATH;
7685 lstrcpyA(buf, "apple");
7686 r = pMsiGetProductInfoExA(prodcode, NULL,
7687 MSIINSTALLCONTEXT_MACHINE,
7688 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7689 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7690 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
7691 ok(sz == 1, "Expected 1, got %d\n", sz);
7692
7693 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7695
7696 /* VersionMajor value exists */
7697 sz = MAX_PATH;
7698 lstrcpyA(buf, "apple");
7699 r = pMsiGetProductInfoExA(prodcode, NULL,
7700 MSIINSTALLCONTEXT_MACHINE,
7701 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7703 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
7704 ok(sz == 1, "Expected 1, got %d\n", sz);
7705
7706 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7707 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7708
7709 /* DisplayVersion value exists */
7710 sz = MAX_PATH;
7711 lstrcpyA(buf, "apple");
7712 r = pMsiGetProductInfoExA(prodcode, NULL,
7713 MSIINSTALLCONTEXT_MACHINE,
7714 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7716 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
7717 ok(sz == 5, "Expected 5, got %d\n", sz);
7718
7719 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7720 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7721
7722 /* ProductID value exists */
7723 sz = MAX_PATH;
7724 lstrcpyA(buf, "apple");
7725 r = pMsiGetProductInfoExA(prodcode, NULL,
7726 MSIINSTALLCONTEXT_MACHINE,
7727 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7729 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
7730 ok(sz == 2, "Expected 2, got %d\n", sz);
7731
7732 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7733 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7734
7735 /* RegCompany value exists */
7736 sz = MAX_PATH;
7737 lstrcpyA(buf, "apple");
7738 r = pMsiGetProductInfoExA(prodcode, NULL,
7739 MSIINSTALLCONTEXT_MACHINE,
7740 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7742 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
7743 ok(sz == 4, "Expected 4, got %d\n", sz);
7744
7745 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7746 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7747
7748 /* RegOwner value exists */
7749 sz = MAX_PATH;
7750 lstrcpyA(buf, "apple");
7751 r = pMsiGetProductInfoExA(prodcode, NULL,
7752 MSIINSTALLCONTEXT_MACHINE,
7753 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7755 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
7756 ok(sz == 5, "Expected 5, got %d\n", sz);
7757
7758 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7759 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7760
7761 /* Transforms value exists */
7762 sz = MAX_PATH;
7763 lstrcpyA(buf, "apple");
7764 r = pMsiGetProductInfoExA(prodcode, NULL,
7765 MSIINSTALLCONTEXT_MACHINE,
7766 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7767 ok(r == ERROR_UNKNOWN_PRODUCT,
7768 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7769 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7770 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7771
7772 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7773 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7774
7775 /* Language value exists */
7776 sz = MAX_PATH;
7777 lstrcpyA(buf, "apple");
7778 r = pMsiGetProductInfoExA(prodcode, NULL,
7779 MSIINSTALLCONTEXT_MACHINE,
7780 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7781 ok(r == ERROR_UNKNOWN_PRODUCT,
7782 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7783 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7784 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7785
7786 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7787 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7788
7789 /* ProductName value exists */
7790 sz = MAX_PATH;
7791 lstrcpyA(buf, "apple");
7792 r = pMsiGetProductInfoExA(prodcode, NULL,
7793 MSIINSTALLCONTEXT_MACHINE,
7794 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7795 ok(r == ERROR_UNKNOWN_PRODUCT,
7796 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7797 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7798 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7799
7800 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7802
7803 /* FIXME */
7804
7805 /* AssignmentType value exists */
7806 sz = MAX_PATH;
7807 lstrcpyA(buf, "apple");
7808 r = pMsiGetProductInfoExA(prodcode, NULL,
7809 MSIINSTALLCONTEXT_MACHINE,
7810 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7811 ok(r == ERROR_UNKNOWN_PRODUCT,
7812 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7813 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7814 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7815
7816 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7817 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7818
7819 /* PackageCode value exists */
7820 sz = MAX_PATH;
7821 lstrcpyA(buf, "apple");
7822 r = pMsiGetProductInfoExA(prodcode, NULL,
7823 MSIINSTALLCONTEXT_MACHINE,
7824 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7825 ok(r == ERROR_UNKNOWN_PRODUCT,
7826 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7827 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7828 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7829
7830 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7832
7833 /* Version value exists */
7834 sz = MAX_PATH;
7835 lstrcpyA(buf, "apple");
7836 r = pMsiGetProductInfoExA(prodcode, NULL,
7837 MSIINSTALLCONTEXT_MACHINE,
7838 INSTALLPROPERTY_VERSIONA, buf, &sz);
7839 ok(r == ERROR_UNKNOWN_PRODUCT,
7840 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7841 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7842 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7843
7844 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7845 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7846
7847 /* ProductIcon value exists */
7848 sz = MAX_PATH;
7849 lstrcpyA(buf, "apple");
7850 r = pMsiGetProductInfoExA(prodcode, NULL,
7851 MSIINSTALLCONTEXT_MACHINE,
7852 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7853 ok(r == ERROR_UNKNOWN_PRODUCT,
7854 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7855 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7856 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7857
7858 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7859 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7860
7861 /* PackageName value exists */
7862 sz = MAX_PATH;
7863 lstrcpyA(buf, "apple");
7864 r = pMsiGetProductInfoExA(prodcode, NULL,
7865 MSIINSTALLCONTEXT_MACHINE,
7866 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7867 ok(r == ERROR_UNKNOWN_PRODUCT,
7868 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7869 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7870 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7871
7872 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7873 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7874
7875 /* AuthorizedLUAApp value exists */
7876 sz = MAX_PATH;
7877 lstrcpyA(buf, "apple");
7878 r = pMsiGetProductInfoExA(prodcode, NULL,
7879 MSIINSTALLCONTEXT_MACHINE,
7880 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7881 ok(r == ERROR_UNKNOWN_PRODUCT,
7882 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7883 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7884 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7885
7886 RegDeleteValueA(propkey, "AuthorizedLUAApp");
7887 RegDeleteValueA(propkey, "PackageName");
7888 RegDeleteValueA(propkey, "ProductIcon");
7889 RegDeleteValueA(propkey, "Version");
7890 RegDeleteValueA(propkey, "PackageCode");
7891 RegDeleteValueA(propkey, "AssignmentType");
7892 RegDeleteValueA(propkey, "ProductName");
7893 RegDeleteValueA(propkey, "Language");
7894 RegDeleteValueA(propkey, "Transforms");
7895 RegDeleteValueA(propkey, "RegOwner");
7896 RegDeleteValueA(propkey, "RegCompany");
7897 RegDeleteValueA(propkey, "ProductID");
7898 RegDeleteValueA(propkey, "DisplayVersion");
7899 RegDeleteValueA(propkey, "VersionMajor");
7900 RegDeleteValueA(propkey, "VersionMinor");
7901 RegDeleteValueA(propkey, "URLUpdateInfo");
7902 RegDeleteValueA(propkey, "URLInfoAbout");
7903 RegDeleteValueA(propkey, "Publisher");
7904 RegDeleteValueA(propkey, "LocalPackage");
7905 RegDeleteValueA(propkey, "InstallSource");
7906 RegDeleteValueA(propkey, "InstallLocation");
7907 RegDeleteValueA(propkey, "DisplayName");
7908 RegDeleteValueA(propkey, "InstallDate");
7909 RegDeleteValueA(propkey, "HelpTelephone");
7910 RegDeleteValueA(propkey, "HelpLink");
7911 RegDeleteValueA(propkey, "LocalPackage");
7912 delete_key(propkey, "", access & KEY_WOW64_64KEY);
7913 RegCloseKey(propkey);
7914 delete_key(localkey, "", access & KEY_WOW64_64KEY);
7915 RegCloseKey(localkey);
7916
7917 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7918 lstrcatA(keypath, prod_squashed);
7919
7920 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7921 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7922
7923 /* local classes product key exists */
7924 sz = MAX_PATH;
7925 lstrcpyA(buf, "apple");
7926 r = pMsiGetProductInfoExA(prodcode, NULL,
7927 MSIINSTALLCONTEXT_MACHINE,
7928 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7929 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7930 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
7931 ok(sz == 1, "Expected 1, got %d\n", sz);
7932
7933 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7934 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7935
7936 /* HelpLink value exists */
7937 sz = MAX_PATH;
7938 lstrcpyA(buf, "apple");
7939 r = pMsiGetProductInfoExA(prodcode, NULL,
7940 MSIINSTALLCONTEXT_MACHINE,
7941 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7942 ok(r == ERROR_UNKNOWN_PROPERTY,
7943 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7944 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7945 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7946
7947 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7948 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7949
7950 /* HelpTelephone value exists */
7951 sz = MAX_PATH;
7952 lstrcpyA(buf, "apple");
7953 r = pMsiGetProductInfoExA(prodcode, NULL,
7954 MSIINSTALLCONTEXT_MACHINE,
7955 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7956 ok(r == ERROR_UNKNOWN_PROPERTY,
7957 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7958 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7959 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7960
7961 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7962 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7963
7964 /* InstallDate value exists */
7965 sz = MAX_PATH;
7966 lstrcpyA(buf, "apple");
7967 r = pMsiGetProductInfoExA(prodcode, NULL,
7968 MSIINSTALLCONTEXT_MACHINE,
7969 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7970 ok(r == ERROR_UNKNOWN_PROPERTY,
7971 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7972 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7973 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7974
7975 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7977
7978 /* DisplayName value exists */
7979 sz = MAX_PATH;
7980 lstrcpyA(buf, "apple");
7981 r = pMsiGetProductInfoExA(prodcode, NULL,
7982 MSIINSTALLCONTEXT_MACHINE,
7983 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7984 ok(r == ERROR_UNKNOWN_PROPERTY,
7985 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7986 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7987 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7988
7989 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7990 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7991
7992 /* InstallLocation value exists */
7993 sz = MAX_PATH;
7994 lstrcpyA(buf, "apple");
7995 r = pMsiGetProductInfoExA(prodcode, NULL,
7996 MSIINSTALLCONTEXT_MACHINE,
7997 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7998 ok(r == ERROR_UNKNOWN_PROPERTY,
7999 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8000 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8001 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8002
8003 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
8004 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8005
8006 /* InstallSource value exists */
8007 sz = MAX_PATH;
8008 lstrcpyA(buf, "apple");
8009 r = pMsiGetProductInfoExA(prodcode, NULL,
8010 MSIINSTALLCONTEXT_MACHINE,
8011 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
8012 ok(r == ERROR_UNKNOWN_PROPERTY,
8013 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8014 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8015 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8016
8017 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
8018 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8019
8020 /* LocalPackage value exists */
8021 sz = MAX_PATH;
8022 lstrcpyA(buf, "apple");
8023 r = pMsiGetProductInfoExA(prodcode, NULL,
8024 MSIINSTALLCONTEXT_MACHINE,
8025 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
8026 ok(r == ERROR_UNKNOWN_PROPERTY,
8027 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8028 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8029 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8030
8031 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
8032 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8033
8034 /* Publisher value exists */
8035 sz = MAX_PATH;
8036 lstrcpyA(buf, "apple");
8037 r = pMsiGetProductInfoExA(prodcode, NULL,
8038 MSIINSTALLCONTEXT_MACHINE,
8039 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
8040 ok(r == ERROR_UNKNOWN_PROPERTY,
8041 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8042 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8043 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8044
8045 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
8046 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8047
8048 /* URLInfoAbout value exists */
8049 sz = MAX_PATH;
8050 lstrcpyA(buf, "apple");
8051 r = pMsiGetProductInfoExA(prodcode, NULL,
8052 MSIINSTALLCONTEXT_MACHINE,
8053 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
8054 ok(r == ERROR_UNKNOWN_PROPERTY,
8055 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8056 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8057 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8058
8059 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
8060 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8061
8062 /* URLUpdateInfo value exists */
8063 sz = MAX_PATH;
8064 lstrcpyA(buf, "apple");
8065 r = pMsiGetProductInfoExA(prodcode, NULL,
8066 MSIINSTALLCONTEXT_MACHINE,
8067 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
8068 ok(r == ERROR_UNKNOWN_PROPERTY,
8069 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8070 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8071 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8072
8073 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
8074 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8075
8076 /* VersionMinor value exists */
8077 sz = MAX_PATH;
8078 lstrcpyA(buf, "apple");
8079 r = pMsiGetProductInfoExA(prodcode, NULL,
8080 MSIINSTALLCONTEXT_MACHINE,
8081 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
8082 ok(r == ERROR_UNKNOWN_PROPERTY,
8083 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8084 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8085 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8086
8087 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
8088 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8089
8090 /* VersionMajor value exists */
8091 sz = MAX_PATH;
8092 lstrcpyA(buf, "apple");
8093 r = pMsiGetProductInfoExA(prodcode, NULL,
8094 MSIINSTALLCONTEXT_MACHINE,
8095 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
8096 ok(r == ERROR_UNKNOWN_PROPERTY,
8097 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8098 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8099 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8100
8101 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
8102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8103
8104 /* DisplayVersion value exists */
8105 sz = MAX_PATH;
8106 lstrcpyA(buf, "apple");
8107 r = pMsiGetProductInfoExA(prodcode, NULL,
8108 MSIINSTALLCONTEXT_MACHINE,
8109 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
8110 ok(r == ERROR_UNKNOWN_PROPERTY,
8111 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8112 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8113 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8114
8115 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
8116 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8117
8118 /* ProductID value exists */
8119 sz = MAX_PATH;
8120 lstrcpyA(buf, "apple");
8121 r = pMsiGetProductInfoExA(prodcode, NULL,
8122 MSIINSTALLCONTEXT_MACHINE,
8123 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
8124 ok(r == ERROR_UNKNOWN_PROPERTY,
8125 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8126 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8127 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8128
8129 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
8130 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8131
8132 /* RegCompany value exists */
8133 sz = MAX_PATH;
8134 lstrcpyA(buf, "apple");
8135 r = pMsiGetProductInfoExA(prodcode, NULL,
8136 MSIINSTALLCONTEXT_MACHINE,
8137 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
8138 ok(r == ERROR_UNKNOWN_PROPERTY,
8139 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8140 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8141 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8142
8143 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8144 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8145
8146 /* RegOwner value exists */
8147 sz = MAX_PATH;
8148 lstrcpyA(buf, "apple");
8149 r = pMsiGetProductInfoExA(prodcode, NULL,
8150 MSIINSTALLCONTEXT_MACHINE,
8151 INSTALLPROPERTY_REGOWNERA, buf, &sz);
8152 ok(r == ERROR_UNKNOWN_PROPERTY,
8153 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8154 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8155 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8156
8157 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
8158 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8159
8160 /* Transforms value exists */
8161 sz = MAX_PATH;
8162 lstrcpyA(buf, "apple");
8163 r = pMsiGetProductInfoExA(prodcode, NULL,
8164 MSIINSTALLCONTEXT_MACHINE,
8165 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
8166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8167 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
8168 ok(sz == 5, "Expected 5, got %d\n", sz);
8169
8170 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
8171 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8172
8173 /* Language value exists */
8174 sz = MAX_PATH;
8175 lstrcpyA(buf, "apple");
8176 r = pMsiGetProductInfoExA(prodcode, NULL,
8177 MSIINSTALLCONTEXT_MACHINE,
8178 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
8179 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8180 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
8181 ok(sz == 4, "Expected 4, got %d\n", sz);
8182
8183 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
8184 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8185
8186 /* ProductName value exists */
8187 sz = MAX_PATH;
8188 lstrcpyA(buf, "apple");
8189 r = pMsiGetProductInfoExA(prodcode, NULL,
8190 MSIINSTALLCONTEXT_MACHINE,
8191 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
8192 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8193 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
8194 ok(sz == 4, "Expected 4, got %d\n", sz);
8195
8196 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
8197 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8198
8199 /* FIXME */
8200
8201 /* AssignmentType value exists */
8202 sz = MAX_PATH;
8203 lstrcpyA(buf, "apple");
8204 r = pMsiGetProductInfoExA(prodcode, NULL,
8205 MSIINSTALLCONTEXT_MACHINE,
8206 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
8207 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8208 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8209 ok(sz == 0, "Expected 0, got %d\n", sz);
8210
8211 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
8212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8213
8214 /* FIXME */
8215
8216 /* PackageCode value exists */
8217 sz = MAX_PATH;
8218 lstrcpyA(buf, "apple");
8219 r = pMsiGetProductInfoExA(prodcode, NULL,
8220 MSIINSTALLCONTEXT_MACHINE,
8221 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
8222 todo_wine
8223 {
8224 ok(r == ERROR_BAD_CONFIGURATION,
8225 "Expected ERROR_BAD_CONFIGURATION, 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
8230 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
8231 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8232
8233 /* Version value exists */
8234 sz = MAX_PATH;
8235 lstrcpyA(buf, "apple");
8236 r = pMsiGetProductInfoExA(prodcode, NULL,
8237 MSIINSTALLCONTEXT_MACHINE,
8238 INSTALLPROPERTY_VERSIONA, buf, &sz);
8239 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8240 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
8241 ok(sz == 3, "Expected 3, got %d\n", sz);
8242
8243 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
8244 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8245
8246 /* ProductIcon value exists */
8247 sz = MAX_PATH;
8248 lstrcpyA(buf, "apple");
8249 r = pMsiGetProductInfoExA(prodcode, NULL,
8250 MSIINSTALLCONTEXT_MACHINE,
8251 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
8252 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8253 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
8254 ok(sz == 4, "Expected 4, got %d\n", sz);
8255
8256 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
8257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8258
8259 /* PackageName value exists */
8260 sz = MAX_PATH;
8261 lstrcpyA(buf, "apple");
8262 r = pMsiGetProductInfoExA(prodcode, NULL,
8263 MSIINSTALLCONTEXT_MACHINE,
8264 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
8265 todo_wine
8266 {
8267 ok(r == ERROR_UNKNOWN_PRODUCT,
8268 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8269 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8270 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8271 }
8272
8273 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
8274 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8275
8276 /* AuthorizedLUAApp value exists */
8277 sz = MAX_PATH;
8278 lstrcpyA(buf, "apple");
8279 r = pMsiGetProductInfoExA(prodcode, NULL,
8280 MSIINSTALLCONTEXT_MACHINE,
8281 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
8282 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8283 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
8284 ok(sz == 4, "Expected 4, got %d\n", sz);
8285
8286 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
8287 RegDeleteValueA(prodkey, "PackageName");
8288 RegDeleteValueA(prodkey, "ProductIcon");
8289 RegDeleteValueA(prodkey, "Version");
8290 RegDeleteValueA(prodkey, "PackageCode");
8291 RegDeleteValueA(prodkey, "AssignmentType");
8292 RegDeleteValueA(prodkey, "ProductName");
8293 RegDeleteValueA(prodkey, "Language");
8294 RegDeleteValueA(prodkey, "Transforms");
8295 RegDeleteValueA(prodkey, "RegOwner");
8296 RegDeleteValueA(prodkey, "RegCompany");
8297 RegDeleteValueA(prodkey, "ProductID");
8298 RegDeleteValueA(prodkey, "DisplayVersion");
8299 RegDeleteValueA(prodkey, "VersionMajor");
8300 RegDeleteValueA(prodkey, "VersionMinor");
8301 RegDeleteValueA(prodkey, "URLUpdateInfo");
8302 RegDeleteValueA(prodkey, "URLInfoAbout");
8303 RegDeleteValueA(prodkey, "Publisher");
8304 RegDeleteValueA(prodkey, "LocalPackage");
8305 RegDeleteValueA(prodkey, "InstallSource");
8306 RegDeleteValueA(prodkey, "InstallLocation");
8307 RegDeleteValueA(prodkey, "DisplayName");
8308 RegDeleteValueA(prodkey, "InstallDate");
8309 RegDeleteValueA(prodkey, "HelpTelephone");
8310 RegDeleteValueA(prodkey, "HelpLink");
8311 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8312 RegCloseKey(prodkey);
8313 LocalFree(usersid);
8314 }
8315
8316 #define INIT_USERINFO() \
8317 lstrcpyA(user, "apple"); \
8318 lstrcpyA(org, "orange"); \
8319 lstrcpyA(serial, "banana"); \
8320 usersz = orgsz = serialsz = MAX_PATH;
8321
8322 static void test_MsiGetUserInfo(void)
8323 {
8324 USERINFOSTATE state;
8325 CHAR user[MAX_PATH];
8326 CHAR org[MAX_PATH];
8327 CHAR serial[MAX_PATH];
8328 DWORD usersz, orgsz, serialsz;
8329 CHAR keypath[MAX_PATH * 2];
8330 CHAR prodcode[MAX_PATH];
8331 CHAR prod_squashed[MAX_PATH];
8332 HKEY prodkey, userprod, props;
8333 LPSTR usersid;
8334 LONG res;
8335 REGSAM access = KEY_ALL_ACCESS;
8336
8337 create_test_guid(prodcode, prod_squashed);
8338 usersid = get_user_sid();
8339
8340 if (is_wow64)
8341 access |= KEY_WOW64_64KEY;
8342
8343 /* NULL szProduct */
8344 INIT_USERINFO();
8345 state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
8346 ok(state == USERINFOSTATE_INVALIDARG,
8347 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8348 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8349 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8350 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8351 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8352 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8353 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8354
8355 /* empty szProductCode */
8356 INIT_USERINFO();
8357 state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
8358 ok(state == USERINFOSTATE_INVALIDARG,
8359 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8360 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8361 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8362 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8363 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8364 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8365 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8366
8367 /* garbage szProductCode */
8368 INIT_USERINFO();
8369 state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
8370 ok(state == USERINFOSTATE_INVALIDARG,
8371 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8372 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8373 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8374 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8375 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8376 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8377 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8378
8379 /* guid without brackets */
8380 INIT_USERINFO();
8381 state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
8382 user, &usersz, org, &orgsz, serial, &serialsz);
8383 ok(state == USERINFOSTATE_INVALIDARG,
8384 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8385 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8386 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8387 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8388 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8389 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8390 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8391
8392 /* guid with brackets */
8393 INIT_USERINFO();
8394 state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
8395 user, &usersz, org, &orgsz, serial, &serialsz);
8396 ok(state == USERINFOSTATE_UNKNOWN,
8397 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8398 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8399 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8400 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8401 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8402 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8403 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8404
8405 /* NULL lpUserNameBuf */
8406 INIT_USERINFO();
8407 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8408 ok(state == USERINFOSTATE_UNKNOWN,
8409 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8410 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8411 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8412 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8413 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8414 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8415
8416 /* NULL pcchUserNameBuf */
8417 INIT_USERINFO();
8418 state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
8419 ok(state == USERINFOSTATE_INVALIDARG,
8420 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8421 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8422 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8423 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8424 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8425 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8426
8427 /* both lpUserNameBuf and pcchUserNameBuf NULL */
8428 INIT_USERINFO();
8429 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8430 ok(state == USERINFOSTATE_UNKNOWN,
8431 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8432 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8433 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8434 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8435 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8436
8437 /* NULL lpOrgNameBuf */
8438 INIT_USERINFO();
8439 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
8440 ok(state == USERINFOSTATE_UNKNOWN,
8441 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8442 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8443 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8444 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8445 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8446 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8447
8448 /* NULL pcchOrgNameBuf */
8449 INIT_USERINFO();
8450 state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
8451 ok(state == USERINFOSTATE_INVALIDARG,
8452 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8453 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8454 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8455 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8456 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8457 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8458
8459 /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
8460 INIT_USERINFO();
8461 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
8462 ok(state == USERINFOSTATE_UNKNOWN,
8463 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8464 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8465 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8466 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8467 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8468
8469 /* NULL lpSerialBuf */
8470 INIT_USERINFO();
8471 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
8472 ok(state == USERINFOSTATE_UNKNOWN,
8473 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8474 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8475 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8476 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8477 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8478 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8479
8480 /* NULL pcchSerialBuf */
8481 INIT_USERINFO();
8482 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
8483 ok(state == USERINFOSTATE_INVALIDARG,
8484 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8485 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8486 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8487 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8488 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8489 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8490
8491 /* both lpSerialBuf and pcchSerialBuf NULL */
8492 INIT_USERINFO();
8493 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
8494 ok(state == USERINFOSTATE_UNKNOWN,
8495 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8496 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8497 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8498 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8499 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8500
8501 /* MSIINSTALLCONTEXT_USERMANAGED */
8502
8503 /* create local system product key */
8504 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8505 lstrcatA(keypath, usersid);
8506 lstrcatA(keypath, "\\Installer\\Products\\");
8507 lstrcatA(keypath, prod_squashed);
8508
8509 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8510 if (res == ERROR_ACCESS_DENIED)
8511 {
8512 skip("Not enough rights to perform tests\n");
8513 LocalFree(usersid);
8514 return;
8515 }
8516 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8517
8518 /* managed product key exists */
8519 INIT_USERINFO();
8520 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8521 ok(state == USERINFOSTATE_ABSENT,
8522 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8523 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8524 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8525 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8526 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8527 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8528 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8529
8530 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8531 lstrcatA(keypath, "Installer\\UserData\\");
8532 lstrcatA(keypath, usersid);
8533 lstrcatA(keypath, "\\Products\\");
8534 lstrcatA(keypath, prod_squashed);
8535
8536 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8537 if (res == ERROR_ACCESS_DENIED)
8538 {
8539 skip("Not enough rights to perform tests\n");
8540 LocalFree(usersid);
8541 return;
8542 }
8543 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8544
8545 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8546 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8547
8548 /* InstallProperties key exists */
8549 INIT_USERINFO();
8550 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8551 ok(state == USERINFOSTATE_ABSENT,
8552 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8553 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8554 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8555 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8556 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8557 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8558 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8559
8560 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8561 INIT_USERINFO();
8562 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8563 ok(state == USERINFOSTATE_ABSENT,
8564 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8565 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8566 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8567 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8568 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8569
8570 /* RegOwner, RegCompany don't exist, out params are NULL */
8571 INIT_USERINFO();
8572 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8573 ok(state == USERINFOSTATE_ABSENT,
8574 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8575 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8576 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8577
8578 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8579 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8580
8581 /* RegOwner value exists */
8582 INIT_USERINFO();
8583 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8584 ok(state == USERINFOSTATE_ABSENT,
8585 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8586 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8587 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8588 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8589 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8590 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8591 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8592
8593 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8594 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8595
8596 /* RegCompany value exists */
8597 INIT_USERINFO();
8598 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8599 ok(state == USERINFOSTATE_ABSENT,
8600 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8601 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8602 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8603 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8604 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8605 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8606 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8607
8608 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8609 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8610
8611 /* ProductID value exists */
8612 INIT_USERINFO();
8613 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8614 ok(state == USERINFOSTATE_PRESENT,
8615 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8616 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8617 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8618 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8619 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8620 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8621 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8622
8623 /* pcchUserNameBuf is too small */
8624 INIT_USERINFO();
8625 usersz = 0;
8626 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8627 ok(state == USERINFOSTATE_MOREDATA,
8628 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8629 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8630 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8631 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8632 ok(usersz == 5, "Expected 5, 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 /* pcchUserNameBuf has no room for NULL terminator */
8637 INIT_USERINFO();
8638 usersz = 5;
8639 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8640 ok(state == USERINFOSTATE_MOREDATA,
8641 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8642 todo_wine
8643 {
8644 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8645 }
8646 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8647 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8648 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8649 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8650 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8651
8652 /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
8653 INIT_USERINFO();
8654 usersz = 0;
8655 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8656 ok(state == USERINFOSTATE_PRESENT,
8657 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8658 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8659 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8660 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8661 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8662 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8663 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8664
8665 RegDeleteValueA(props, "ProductID");
8666 RegDeleteValueA(props, "RegCompany");
8667 RegDeleteValueA(props, "RegOwner");
8668 delete_key(props, "", access & KEY_WOW64_64KEY);
8669 RegCloseKey(props);
8670 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8671 RegCloseKey(userprod);
8672 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8673 RegCloseKey(prodkey);
8674
8675 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8676
8677 /* create local system product key */
8678 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8679 lstrcatA(keypath, prod_squashed);
8680
8681 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8682 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8683
8684 /* product key exists */
8685 INIT_USERINFO();
8686 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8687 ok(state == USERINFOSTATE_ABSENT,
8688 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8689 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8690 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8691 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8692 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8693 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8694 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8695
8696 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8697 lstrcatA(keypath, "Installer\\UserData\\");
8698 lstrcatA(keypath, usersid);
8699 lstrcatA(keypath, "\\Products\\");
8700 lstrcatA(keypath, prod_squashed);
8701
8702 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8703 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8704
8705 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8706 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8707
8708 /* InstallProperties key exists */
8709 INIT_USERINFO();
8710 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8711 ok(state == USERINFOSTATE_ABSENT,
8712 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8713 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8714 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8715 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8716 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8717 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8718 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8719
8720 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8721 INIT_USERINFO();
8722 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8723 ok(state == USERINFOSTATE_ABSENT,
8724 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8725 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8726 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8727 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8728 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8729
8730 /* RegOwner, RegCompany don't exist, out params are NULL */
8731 INIT_USERINFO();
8732 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8733 ok(state == USERINFOSTATE_ABSENT,
8734 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8735 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8736 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8737
8738 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8739 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8740
8741 /* RegOwner value exists */
8742 INIT_USERINFO();
8743 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8744 ok(state == USERINFOSTATE_ABSENT,
8745 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8746 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8747 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8748 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8749 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8750 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8751 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8752
8753 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8754 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8755
8756 /* RegCompany value exists */
8757 INIT_USERINFO();
8758 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8759 ok(state == USERINFOSTATE_ABSENT,
8760 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8761 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8762 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8763 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8764 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8765 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8766 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8767
8768 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8769 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8770
8771 /* ProductID value exists */
8772 INIT_USERINFO();
8773 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8774 ok(state == USERINFOSTATE_PRESENT,
8775 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8776 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8777 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8778 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8779 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8780 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8781 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8782
8783 RegDeleteValueA(props, "ProductID");
8784 RegDeleteValueA(props, "RegCompany");
8785 RegDeleteValueA(props, "RegOwner");
8786 delete_key(props, "", access & KEY_WOW64_64KEY);
8787 RegCloseKey(props);
8788 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8789 RegCloseKey(userprod);
8790 RegDeleteKeyA(prodkey, "");
8791 RegCloseKey(prodkey);
8792
8793 /* MSIINSTALLCONTEXT_MACHINE */
8794
8795 /* create local system product key */
8796 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8797 lstrcatA(keypath, prod_squashed);
8798
8799 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8800 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8801
8802 /* product key exists */
8803 INIT_USERINFO();
8804 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8805 ok(state == USERINFOSTATE_ABSENT,
8806 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8807 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8808 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8809 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8810 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8811 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8812 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8813
8814 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8815 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
8816 lstrcatA(keypath, "\\Products\\");
8817 lstrcatA(keypath, prod_squashed);
8818
8819 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8820 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8821
8822 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8823 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8824
8825 /* InstallProperties key exists */
8826 INIT_USERINFO();
8827 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8828 ok(state == USERINFOSTATE_ABSENT,
8829 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8830 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8831 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8832 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8833 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8834 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8835 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8836
8837 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8838 INIT_USERINFO();
8839 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8840 ok(state == USERINFOSTATE_ABSENT,
8841 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8842 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8843 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8844 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8845 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8846
8847 /* RegOwner, RegCompany don't exist, out params are NULL */
8848 INIT_USERINFO();
8849 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8850 ok(state == USERINFOSTATE_ABSENT,
8851 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8852 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8853 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8854
8855 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8857
8858 /* RegOwner value exists */
8859 INIT_USERINFO();
8860 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8861 ok(state == USERINFOSTATE_ABSENT,
8862 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8863 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8864 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8865 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8866 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8867 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8868 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8869
8870 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8871 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8872
8873 /* RegCompany value exists */
8874 INIT_USERINFO();
8875 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8876 ok(state == USERINFOSTATE_ABSENT,
8877 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8878 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8879 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8880 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8881 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8882 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8883 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8884
8885 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8886 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8887
8888 /* ProductID value exists */
8889 INIT_USERINFO();
8890 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8891 ok(state == USERINFOSTATE_PRESENT,
8892 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8893 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8894 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8895 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8896 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8897 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8898 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8899
8900 RegDeleteValueA(props, "ProductID");
8901 RegDeleteValueA(props, "RegCompany");
8902 RegDeleteValueA(props, "RegOwner");
8903 delete_key(props, "", access & KEY_WOW64_64KEY);
8904 RegCloseKey(props);
8905 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8906 RegCloseKey(userprod);
8907 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8908 RegCloseKey(prodkey);
8909 LocalFree(usersid);
8910 }
8911
8912 static void test_MsiOpenProduct(void)
8913 {
8914 MSIHANDLE hprod, hdb;
8915 CHAR val[MAX_PATH];
8916 CHAR path[MAX_PATH];
8917 CHAR keypath[MAX_PATH*2];
8918 CHAR prodcode[MAX_PATH];
8919 CHAR prod_squashed[MAX_PATH];
8920 HKEY prodkey, userkey, props;
8921 LPSTR usersid;
8922 DWORD size;
8923 LONG res;
8924 UINT r;
8925 REGSAM access = KEY_ALL_ACCESS;
8926
8927 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8928
8929 GetCurrentDirectoryA(MAX_PATH, path);
8930 lstrcatA(path, "\\");
8931
8932 create_test_guid(prodcode, prod_squashed);
8933 usersid = get_user_sid();
8934
8935 if (is_wow64)
8936 access |= KEY_WOW64_64KEY;
8937
8938 hdb = create_package_db(prodcode);
8939 MsiCloseHandle(hdb);
8940
8941 /* NULL szProduct */
8942 hprod = 0xdeadbeef;
8943 r = MsiOpenProductA(NULL, &hprod);
8944 ok(r == ERROR_INVALID_PARAMETER,
8945 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8946 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8947
8948 /* empty szProduct */
8949 hprod = 0xdeadbeef;
8950 r = MsiOpenProductA("", &hprod);
8951 ok(r == ERROR_INVALID_PARAMETER,
8952 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8953 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8954
8955 /* garbage szProduct */
8956 hprod = 0xdeadbeef;
8957 r = MsiOpenProductA("garbage", &hprod);
8958 ok(r == ERROR_INVALID_PARAMETER,
8959 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8960 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8961
8962 /* guid without brackets */
8963 hprod = 0xdeadbeef;
8964 r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
8965 ok(r == ERROR_INVALID_PARAMETER,
8966 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8967 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8968
8969 /* guid with brackets */
8970 hprod = 0xdeadbeef;
8971 r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
8972 ok(r == ERROR_UNKNOWN_PRODUCT,
8973 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8974 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8975
8976 /* same length as guid, but random */
8977 hprod = 0xdeadbeef;
8978 r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
8979 ok(r == ERROR_INVALID_PARAMETER,
8980 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8981 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8982
8983 /* hProduct is NULL */
8984 hprod = 0xdeadbeef;
8985 r = MsiOpenProductA(prodcode, NULL);
8986 ok(r == ERROR_INVALID_PARAMETER,
8987 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8988 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8989
8990 /* MSIINSTALLCONTEXT_USERMANAGED */
8991
8992 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8993 lstrcatA(keypath, "Installer\\Managed\\");
8994 lstrcatA(keypath, usersid);
8995 lstrcatA(keypath, "\\Installer\\Products\\");
8996 lstrcatA(keypath, prod_squashed);
8997
8998 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8999 if (res == ERROR_ACCESS_DENIED)
9000 {
9001 skip("Not enough rights to perform tests\n");
9002 LocalFree(usersid);
9003 return;
9004 }
9005 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9006
9007 /* managed product key exists */
9008 hprod = 0xdeadbeef;
9009 r = MsiOpenProductA(prodcode, &hprod);
9010 ok(r == ERROR_UNKNOWN_PRODUCT,
9011 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9012 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9013
9014 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9015 lstrcatA(keypath, "Installer\\UserData\\");
9016 lstrcatA(keypath, usersid);
9017 lstrcatA(keypath, "\\Products\\");
9018 lstrcatA(keypath, prod_squashed);
9019
9020 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9021 if (res == ERROR_ACCESS_DENIED)
9022 {
9023 skip("Not enough rights to perform tests\n");
9024 LocalFree(usersid);
9025 return;
9026 }
9027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9028
9029 /* user product key exists */
9030 hprod = 0xdeadbeef;
9031 r = MsiOpenProductA(prodcode, &hprod);
9032 ok(r == ERROR_UNKNOWN_PRODUCT,
9033 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9034 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9035
9036 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9037 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9038
9039 /* InstallProperties key exists */
9040 hprod = 0xdeadbeef;
9041 r = MsiOpenProductA(prodcode, &hprod);
9042 ok(r == ERROR_UNKNOWN_PRODUCT,
9043 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9044 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9045
9046 lstrcpyA(val, path);
9047 lstrcatA(val, "\\winetest.msi");
9048 res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
9049 (const BYTE *)val, lstrlenA(val) + 1);
9050 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9051
9052 /* ManagedLocalPackage value exists */
9053 hprod = 0xdeadbeef;
9054 r = MsiOpenProductA(prodcode, &hprod);
9055 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9056 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9057
9058 size = MAX_PATH;
9059 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9061 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9062 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9063
9064 MsiCloseHandle(hprod);
9065
9066 RegDeleteValueA(props, "ManagedLocalPackage");
9067 delete_key(props, "", access & KEY_WOW64_64KEY);
9068 RegCloseKey(props);
9069 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9070 RegCloseKey(userkey);
9071 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9072 RegCloseKey(prodkey);
9073
9074 /* MSIINSTALLCONTEXT_USERUNMANAGED */
9075
9076 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9077 lstrcatA(keypath, prod_squashed);
9078
9079 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9080 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9081
9082 /* unmanaged product key exists */
9083 hprod = 0xdeadbeef;
9084 r = MsiOpenProductA(prodcode, &hprod);
9085 ok(r == ERROR_UNKNOWN_PRODUCT,
9086 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9087 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9088
9089 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9090 lstrcatA(keypath, "Installer\\UserData\\");
9091 lstrcatA(keypath, usersid);
9092 lstrcatA(keypath, "\\Products\\");
9093 lstrcatA(keypath, prod_squashed);
9094
9095 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9096 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9097
9098 /* user product key exists */
9099 hprod = 0xdeadbeef;
9100 r = MsiOpenProductA(prodcode, &hprod);
9101 ok(r == ERROR_UNKNOWN_PRODUCT,
9102 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9103 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9104
9105 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9106 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9107
9108 /* InstallProperties key exists */
9109 hprod = 0xdeadbeef;
9110 r = MsiOpenProductA(prodcode, &hprod);
9111 ok(r == ERROR_UNKNOWN_PRODUCT,
9112 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9113 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9114
9115 lstrcpyA(val, path);
9116 lstrcatA(val, "\\winetest.msi");
9117 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9118 (const BYTE *)val, lstrlenA(val) + 1);
9119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9120
9121 /* LocalPackage value exists */
9122 hprod = 0xdeadbeef;
9123 r = MsiOpenProductA(prodcode, &hprod);
9124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9125 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9126
9127 size = MAX_PATH;
9128 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9130 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9131 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9132
9133 MsiCloseHandle(hprod);
9134
9135 RegDeleteValueA(props, "LocalPackage");
9136 delete_key(props, "", access & KEY_WOW64_64KEY);
9137 RegCloseKey(props);
9138 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9139 RegCloseKey(userkey);
9140 RegDeleteKeyA(prodkey, "");
9141 RegCloseKey(prodkey);
9142
9143 /* MSIINSTALLCONTEXT_MACHINE */
9144
9145 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9146 lstrcatA(keypath, prod_squashed);
9147
9148 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9149 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9150
9151 /* managed product key exists */
9152 hprod = 0xdeadbeef;
9153 r = MsiOpenProductA(prodcode, &hprod);
9154 ok(r == ERROR_UNKNOWN_PRODUCT,
9155 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9156 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9157
9158 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9159 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9160 lstrcatA(keypath, prod_squashed);
9161
9162 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9163 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9164
9165 /* user product key exists */
9166 hprod = 0xdeadbeef;
9167 r = MsiOpenProductA(prodcode, &hprod);
9168 ok(r == ERROR_UNKNOWN_PRODUCT,
9169 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9170 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9171
9172 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9173 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9174
9175 /* InstallProperties key exists */
9176 hprod = 0xdeadbeef;
9177 r = MsiOpenProductA(prodcode, &hprod);
9178 ok(r == ERROR_UNKNOWN_PRODUCT,
9179 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9180 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9181
9182 lstrcpyA(val, path);
9183 lstrcatA(val, "\\winetest.msi");
9184 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9185 (const BYTE *)val, lstrlenA(val) + 1);
9186 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9187
9188 /* LocalPackage value exists */
9189 hprod = 0xdeadbeef;
9190 r = MsiOpenProductA(prodcode, &hprod);
9191 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9192 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9193
9194 size = MAX_PATH;
9195 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9196 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9197 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9198 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9199
9200 MsiCloseHandle(hprod);
9201
9202 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9203 (const BYTE *)"winetest.msi", 13);
9204 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9205
9206 lstrcpyA(val, path);
9207 lstrcatA(val, "\\winetest.msi");
9208 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9209 (const BYTE *)val, lstrlenA(val) + 1);
9210 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9211
9212 DeleteFileA(msifile);
9213
9214 /* local package does not exist */
9215 hprod = 0xdeadbeef;
9216 r = MsiOpenProductA(prodcode, &hprod);
9217 ok(r == ERROR_UNKNOWN_PRODUCT,
9218 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9219 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9220
9221 RegDeleteValueA(props, "LocalPackage");
9222 delete_key(props, "", access & KEY_WOW64_64KEY);
9223 RegCloseKey(props);
9224 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9225 RegCloseKey(userkey);
9226 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9227 RegCloseKey(prodkey);
9228
9229 DeleteFileA(msifile);
9230 LocalFree(usersid);
9231 }
9232
9233 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
9234 {
9235 MSIINSTALLCONTEXT context;
9236 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9237 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9238 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9239 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9240 HKEY prodkey, patches, udprod, udpatch, hpatch;
9241 DWORD size, data;
9242 LONG res;
9243 UINT r;
9244 REGSAM access = KEY_ALL_ACCESS;
9245
9246 create_test_guid(prodcode, prod_squashed);
9247 create_test_guid(patch, patch_squashed);
9248
9249 if (is_wow64)
9250 access |= KEY_WOW64_64KEY;
9251
9252 /* MSIPATCHSTATE_APPLIED */
9253
9254 lstrcpyA(patchcode, "apple");
9255 lstrcpyA(targetprod, "banana");
9256 context = 0xdeadbeef;
9257 lstrcpyA(targetsid, "kiwi");
9258 size = MAX_PATH;
9259 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9260 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9261 &context, targetsid, &size);
9262 if (r == ERROR_ACCESS_DENIED)
9263 {
9264 skip("Not enough rights to perform tests\n");
9265 return;
9266 }
9267 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9268 ok(!lstrcmpA(patchcode, "apple"),
9269 "Expected patchcode to be unchanged, got %s\n", patchcode);
9270 ok(!lstrcmpA(targetprod, "banana"),
9271 "Expected targetprod to be unchanged, got %s\n", targetprod);
9272 ok(context == 0xdeadbeef,
9273 "Expected context to be unchanged, got %d\n", context);
9274 ok(!lstrcmpA(targetsid, "kiwi"),
9275 "Expected targetsid to be unchanged, got %s\n", targetsid);
9276 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9277
9278 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9279 lstrcatA(keypath, expectedsid);
9280 lstrcatA(keypath, "\\Installer\\Products\\");
9281 lstrcatA(keypath, prod_squashed);
9282
9283 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9284 if (res == ERROR_ACCESS_DENIED)
9285 {
9286 skip("Not enough rights to perform tests\n");
9287 return;
9288 }
9289 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9290
9291 /* managed product key exists */
9292 lstrcpyA(patchcode, "apple");
9293 lstrcpyA(targetprod, "banana");
9294 context = 0xdeadbeef;
9295 lstrcpyA(targetsid, "kiwi");
9296 size = MAX_PATH;
9297 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9298 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9299 &context, targetsid, &size);
9300 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9301 ok(!lstrcmpA(patchcode, "apple"),
9302 "Expected patchcode to be unchanged, got %s\n", patchcode);
9303 ok(!lstrcmpA(targetprod, "banana"),
9304 "Expected targetprod to be unchanged, got %s\n", targetprod);
9305 ok(context == 0xdeadbeef,
9306 "Expected context to be unchanged, got %d\n", context);
9307 ok(!lstrcmpA(targetsid, "kiwi"),
9308 "Expected targetsid to be unchanged, got %s\n", targetsid);
9309 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9310
9311 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9312 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9313
9314 /* patches key exists */
9315 lstrcpyA(patchcode, "apple");
9316 lstrcpyA(targetprod, "banana");
9317 context = 0xdeadbeef;
9318 lstrcpyA(targetsid, "kiwi");
9319 size = MAX_PATH;
9320 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9321 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9322 &context, targetsid, &size);
9323 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9324 ok(!lstrcmpA(patchcode, "apple"),
9325 "Expected patchcode to be unchanged, got %s\n", patchcode);
9326 ok(!lstrcmpA(targetprod, "banana"),
9327 "Expected targetprod to be unchanged, got %s\n", targetprod);
9328 ok(context == 0xdeadbeef,
9329 "Expected context to be unchanged, got %d\n", context);
9330 ok(!lstrcmpA(targetsid, "kiwi"),
9331 "Expected targetsid to be unchanged, got %s\n", targetsid);
9332 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9333
9334 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9335 (const BYTE *)patch_squashed,
9336 lstrlenA(patch_squashed) + 1);
9337 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9338
9339 /* Patches value exists, is not REG_MULTI_SZ */
9340 lstrcpyA(patchcode, "apple");
9341 lstrcpyA(targetprod, "banana");
9342 context = 0xdeadbeef;
9343 lstrcpyA(targetsid, "kiwi");
9344 size = MAX_PATH;
9345 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9346 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9347 &context, targetsid, &size);
9348 ok(r == ERROR_BAD_CONFIGURATION,
9349 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9350 ok(!lstrcmpA(patchcode, "apple"),
9351 "Expected patchcode to be unchanged, got %s\n", patchcode);
9352 ok(!lstrcmpA(targetprod, "banana"),
9353 "Expected targetprod to be unchanged, got %s\n", targetprod);
9354 ok(context == 0xdeadbeef,
9355 "Expected context to be unchanged, got %d\n", context);
9356 ok(!lstrcmpA(targetsid, "kiwi"),
9357 "Expected targetsid to be unchanged, got %s\n", targetsid);
9358 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9359
9360 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9361 (const BYTE *)"a\0b\0c\0\0", 7);
9362 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9363
9364 /* Patches value exists, is not a squashed guid */
9365 lstrcpyA(patchcode, "apple");
9366 lstrcpyA(targetprod, "banana");
9367 context = 0xdeadbeef;
9368 lstrcpyA(targetsid, "kiwi");
9369 size = MAX_PATH;
9370 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9371 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9372 &context, targetsid, &size);
9373 ok(r == ERROR_BAD_CONFIGURATION,
9374 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9375 ok(!lstrcmpA(patchcode, "apple"),
9376 "Expected patchcode to be unchanged, got %s\n", patchcode);
9377 ok(!lstrcmpA(targetprod, "banana"),
9378 "Expected targetprod to be unchanged, got %s\n", targetprod);
9379 ok(context == 0xdeadbeef,
9380 "Expected context to be unchanged, got %d\n", context);
9381 ok(!lstrcmpA(targetsid, "kiwi"),
9382 "Expected targetsid to be unchanged, got %s\n", targetsid);
9383 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9384
9385 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9386 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9387 (const BYTE *)patch_squashed,
9388 lstrlenA(patch_squashed) + 2);
9389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9390
9391 /* Patches value exists */
9392 lstrcpyA(patchcode, "apple");
9393 lstrcpyA(targetprod, "banana");
9394 context = 0xdeadbeef;
9395 lstrcpyA(targetsid, "kiwi");
9396 size = MAX_PATH;
9397 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9398 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9399 &context, targetsid, &size);
9400 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9401 ok(!lstrcmpA(patchcode, "apple"),
9402 "Expected patchcode to be unchanged, got %s\n", patchcode);
9403 ok(!lstrcmpA(targetprod, "banana"),
9404 "Expected targetprod to be unchanged, got %s\n", targetprod);
9405 ok(context == 0xdeadbeef,
9406 "Expected context to be unchanged, got %d\n", context);
9407 ok(!lstrcmpA(targetsid, "kiwi"),
9408 "Expected targetsid to be unchanged, got %s\n", targetsid);
9409 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9410
9411 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9412 (const BYTE *)"whatever", 9);
9413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9414
9415 /* patch squashed value exists */
9416 lstrcpyA(patchcode, "apple");
9417 lstrcpyA(targetprod, "banana");
9418 context = 0xdeadbeef;
9419 lstrcpyA(targetsid, "kiwi");
9420 size = MAX_PATH;
9421 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9422 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9423 &context, targetsid, &size);
9424 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9425 ok(!lstrcmpA(patchcode, patch),
9426 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9427 ok(!lstrcmpA(targetprod, prodcode),
9428 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9429 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9430 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9431 ok(!lstrcmpA(targetsid, expectedsid),
9432 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9433 ok(size == lstrlenA(expectedsid),
9434 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9435
9436 /* increase the index */
9437 lstrcpyA(patchcode, "apple");
9438 lstrcpyA(targetprod, "banana");
9439 context = 0xdeadbeef;
9440 lstrcpyA(targetsid, "kiwi");
9441 size = MAX_PATH;
9442 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9443 MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
9444 &context, targetsid, &size);
9445 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9446 ok(!lstrcmpA(patchcode, "apple"),
9447 "Expected patchcode to be unchanged, got %s\n", patchcode);
9448 ok(!lstrcmpA(targetprod, "banana"),
9449 "Expected targetprod to be unchanged, got %s\n", targetprod);
9450 ok(context == 0xdeadbeef,
9451 "Expected context to be unchanged, got %d\n", context);
9452 ok(!lstrcmpA(targetsid, "kiwi"),
9453 "Expected targetsid to be unchanged, got %s\n", targetsid);
9454 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9455
9456 /* increase again */
9457 lstrcpyA(patchcode, "apple");
9458 lstrcpyA(targetprod, "banana");
9459 context = 0xdeadbeef;
9460 lstrcpyA(targetsid, "kiwi");
9461 size = MAX_PATH;
9462 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9463 MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
9464 &context, targetsid, &size);
9465 ok(r == ERROR_INVALID_PARAMETER,
9466 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9467 ok(!lstrcmpA(patchcode, "apple"),
9468 "Expected patchcode to be unchanged, got %s\n", patchcode);
9469 ok(!lstrcmpA(targetprod, "banana"),
9470 "Expected targetprod to be unchanged, got %s\n", targetprod);
9471 ok(context == 0xdeadbeef,
9472 "Expected context to be unchanged, got %d\n", context);
9473 ok(!lstrcmpA(targetsid, "kiwi"),
9474 "Expected targetsid to be unchanged, got %s\n", targetsid);
9475 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9476
9477 /* szPatchCode is NULL */
9478 lstrcpyA(targetprod, "banana");
9479 context = 0xdeadbeef;
9480 lstrcpyA(targetsid, "kiwi");
9481 size = MAX_PATH;
9482 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9483 MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
9484 &context, targetsid, &size);
9485 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9486 ok(!lstrcmpA(targetprod, prodcode),
9487 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9488 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9489 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9490 ok(!lstrcmpA(targetsid, expectedsid),
9491 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9492 ok(size == lstrlenA(expectedsid),
9493 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9494
9495 /* szTargetProductCode is NULL */
9496 lstrcpyA(patchcode, "apple");
9497 context = 0xdeadbeef;
9498 lstrcpyA(targetsid, "kiwi");
9499 size = MAX_PATH;
9500 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9501 MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
9502 &context, targetsid, &size);
9503 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9504 ok(!lstrcmpA(patchcode, patch),
9505 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9506 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9507 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9508 ok(!lstrcmpA(targetsid, expectedsid),
9509 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9510 ok(size == lstrlenA(expectedsid),
9511 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9512
9513 /* pdwTargetProductContext is NULL */
9514 lstrcpyA(patchcode, "apple");
9515 lstrcpyA(targetprod, "banana");
9516 lstrcpyA(targetsid, "kiwi");
9517 size = MAX_PATH;
9518 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9519 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9520 NULL, targetsid, &size);
9521 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9522 ok(!lstrcmpA(patchcode, patch),
9523 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9524 ok(!lstrcmpA(targetprod, prodcode),
9525 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9526 ok(!lstrcmpA(targetsid, expectedsid),
9527 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9528 ok(size == lstrlenA(expectedsid),
9529 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9530
9531 /* szTargetUserSid is NULL */
9532 lstrcpyA(patchcode, "apple");
9533 lstrcpyA(targetprod, "banana");
9534 context = 0xdeadbeef;
9535 size = MAX_PATH;
9536 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9537 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9538 &context, NULL, &size);
9539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9540 ok(!lstrcmpA(patchcode, patch),
9541 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9542 ok(!lstrcmpA(targetprod, prodcode),
9543 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9544 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9545 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9546 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
9547 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
9548
9549 /* pcchTargetUserSid is exactly the length of szTargetUserSid */
9550 lstrcpyA(patchcode, "apple");
9551 lstrcpyA(targetprod, "banana");
9552 context = 0xdeadbeef;
9553 lstrcpyA(targetsid, "kiwi");
9554 size = lstrlenA(expectedsid);
9555 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9556 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9557 &context, targetsid, &size);
9558 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9559 ok(!lstrcmpA(patchcode, patch),
9560 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9561 ok(!lstrcmpA(targetprod, prodcode),
9562 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9563 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9564 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9565 ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
9566 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9567 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
9568 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
9569
9570 /* pcchTargetUserSid has enough room for NULL terminator */
9571 lstrcpyA(patchcode, "apple");
9572 lstrcpyA(targetprod, "banana");
9573 context = 0xdeadbeef;
9574 lstrcpyA(targetsid, "kiwi");
9575 size = lstrlenA(expectedsid) + 1;
9576 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9577 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9578 &context, targetsid, &size);
9579 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9580 ok(!lstrcmpA(patchcode, patch),
9581 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9582 ok(!lstrcmpA(targetprod, prodcode),
9583 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9584 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9585 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9586 ok(!lstrcmpA(targetsid, expectedsid),
9587 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9588 ok(size == lstrlenA(expectedsid),
9589 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9590
9591 /* both szTargetuserSid and pcchTargetUserSid are NULL */
9592 lstrcpyA(patchcode, "apple");
9593 lstrcpyA(targetprod, "banana");
9594 context = 0xdeadbeef;
9595 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9596 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9597 &context, NULL, NULL);
9598 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9599 ok(!lstrcmpA(patchcode, patch),
9600 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9601 ok(!lstrcmpA(targetprod, prodcode),
9602 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9603 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9604 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9605
9606 /* MSIPATCHSTATE_SUPERSEDED */
9607
9608 lstrcpyA(patchcode, "apple");
9609 lstrcpyA(targetprod, "banana");
9610 context = 0xdeadbeef;
9611 lstrcpyA(targetsid, "kiwi");
9612 size = MAX_PATH;
9613 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9614 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9615 &context, targetsid, &size);
9616 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9617 ok(!lstrcmpA(patchcode, "apple"),
9618 "Expected patchcode to be unchanged, got %s\n", patchcode);
9619 ok(!lstrcmpA(targetprod, "banana"),
9620 "Expected targetprod to be unchanged, got %s\n", targetprod);
9621 ok(context == 0xdeadbeef,
9622 "Expected context to be unchanged, got %d\n", context);
9623 ok(!lstrcmpA(targetsid, "kiwi"),
9624 "Expected targetsid to be unchanged, got %s\n", targetsid);
9625 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9626
9627 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9628 lstrcatA(keypath, expectedsid);
9629 lstrcatA(keypath, "\\Products\\");
9630 lstrcatA(keypath, prod_squashed);
9631
9632 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9633 if (res == ERROR_ACCESS_DENIED)
9634 {
9635 skip("Not enough rights to perform tests\n");
9636 return;
9637 }
9638 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9639
9640 /* UserData product key exists */
9641 lstrcpyA(patchcode, "apple");
9642 lstrcpyA(targetprod, "banana");
9643 context = 0xdeadbeef;
9644 lstrcpyA(targetsid, "kiwi");
9645 size = MAX_PATH;
9646 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9647 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9648 &context, targetsid, &size);
9649 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9650 ok(!lstrcmpA(patchcode, "apple"),
9651 "Expected patchcode to be unchanged, got %s\n", patchcode);
9652 ok(!lstrcmpA(targetprod, "banana"),
9653 "Expected targetprod to be unchanged, got %s\n", targetprod);
9654 ok(context == 0xdeadbeef,
9655 "Expected context to be unchanged, got %d\n", context);
9656 ok(!lstrcmpA(targetsid, "kiwi"),
9657 "Expected targetsid to be unchanged, got %s\n", targetsid);
9658 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9659
9660 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9661 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9662
9663 /* UserData patches key exists */
9664 lstrcpyA(patchcode, "apple");
9665 lstrcpyA(targetprod, "banana");
9666 context = 0xdeadbeef;
9667 lstrcpyA(targetsid, "kiwi");
9668 size = MAX_PATH;
9669 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9670 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9671 &context, targetsid, &size);
9672 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9673 ok(!lstrcmpA(patchcode, "apple"),
9674 "Expected patchcode to be unchanged, got %s\n", patchcode);
9675 ok(!lstrcmpA(targetprod, "banana"),
9676 "Expected targetprod to be unchanged, got %s\n", targetprod);
9677 ok(context == 0xdeadbeef,
9678 "Expected context to be unchanged, got %d\n", context);
9679 ok(!lstrcmpA(targetsid, "kiwi"),
9680 "Expected targetsid to be unchanged, got %s\n", targetsid);
9681 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9682
9683 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9685
9686 /* specific UserData patch key exists */
9687 lstrcpyA(patchcode, "apple");
9688 lstrcpyA(targetprod, "banana");
9689 context = 0xdeadbeef;
9690 lstrcpyA(targetsid, "kiwi");
9691 size = MAX_PATH;
9692 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9693 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9694 &context, targetsid, &size);
9695 ok(r == ERROR_BAD_CONFIGURATION,
9696 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9697 ok(!lstrcmpA(patchcode, "apple"),
9698 "Expected patchcode to be unchanged, got %s\n", patchcode);
9699 ok(!lstrcmpA(targetprod, "banana"),
9700 "Expected targetprod to be unchanged, got %s\n", targetprod);
9701 ok(context == 0xdeadbeef,
9702 "Expected context to be unchanged, got %d\n", context);
9703 ok(!lstrcmpA(targetsid, "kiwi"),
9704 "Expected targetsid to be unchanged, got %s\n", targetsid);
9705 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9706
9707 data = MSIPATCHSTATE_SUPERSEDED;
9708 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9709 (const BYTE *)&data, sizeof(DWORD));
9710 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9711
9712 /* State value exists */
9713 lstrcpyA(patchcode, "apple");
9714 lstrcpyA(targetprod, "banana");
9715 context = 0xdeadbeef;
9716 lstrcpyA(targetsid, "kiwi");
9717 size = MAX_PATH;
9718 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9719 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9720 &context, targetsid, &size);
9721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9722 ok(!lstrcmpA(patchcode, patch),
9723 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9724 ok(!lstrcmpA(targetprod, prodcode),
9725 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9726 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9727 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9728 ok(!lstrcmpA(targetsid, expectedsid),
9729 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9730 ok(size == lstrlenA(expectedsid),
9731 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9732
9733 /* MSIPATCHSTATE_OBSOLETED */
9734
9735 lstrcpyA(patchcode, "apple");
9736 lstrcpyA(targetprod, "banana");
9737 context = 0xdeadbeef;
9738 lstrcpyA(targetsid, "kiwi");
9739 size = MAX_PATH;
9740 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9741 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9742 &context, targetsid, &size);
9743 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9744 ok(!lstrcmpA(patchcode, "apple"),
9745 "Expected patchcode to be unchanged, got %s\n", patchcode);
9746 ok(!lstrcmpA(targetprod, "banana"),
9747 "Expected targetprod to be unchanged, got %s\n", targetprod);
9748 ok(context == 0xdeadbeef,
9749 "Expected context to be unchanged, got %d\n", context);
9750 ok(!lstrcmpA(targetsid, "kiwi"),
9751 "Expected targetsid to be unchanged, got %s\n", targetsid);
9752 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9753
9754 data = MSIPATCHSTATE_OBSOLETED;
9755 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9756 (const BYTE *)&data, sizeof(DWORD));
9757 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9758
9759 /* State value is obsoleted */
9760 lstrcpyA(patchcode, "apple");
9761 lstrcpyA(targetprod, "banana");
9762 context = 0xdeadbeef;
9763 lstrcpyA(targetsid, "kiwi");
9764 size = MAX_PATH;
9765 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9766 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9767 &context, targetsid, &size);
9768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9769 ok(!lstrcmpA(patchcode, patch),
9770 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9771 ok(!lstrcmpA(targetprod, prodcode),
9772 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9773 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9774 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9775 ok(!lstrcmpA(targetsid, expectedsid),
9776 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9777 ok(size == lstrlenA(expectedsid),
9778 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9779
9780 /* MSIPATCHSTATE_REGISTERED */
9781 /* FIXME */
9782
9783 /* MSIPATCHSTATE_ALL */
9784
9785 /* 1st */
9786 lstrcpyA(patchcode, "apple");
9787 lstrcpyA(targetprod, "banana");
9788 context = 0xdeadbeef;
9789 lstrcpyA(targetsid, "kiwi");
9790 size = MAX_PATH;
9791 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9792 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9793 &context, targetsid, &size);
9794 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9795 ok(!lstrcmpA(patchcode, patch),
9796 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9797 ok(!lstrcmpA(targetprod, prodcode),
9798 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9799 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9800 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9801 ok(!lstrcmpA(targetsid, expectedsid),
9802 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9803 ok(size == lstrlenA(expectedsid),
9804 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9805
9806 /* same patch in multiple places, only one is enumerated */
9807 lstrcpyA(patchcode, "apple");
9808 lstrcpyA(targetprod, "banana");
9809 context = 0xdeadbeef;
9810 lstrcpyA(targetsid, "kiwi");
9811 size = MAX_PATH;
9812 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9813 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9814 &context, targetsid, &size);
9815 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9816 ok(!lstrcmpA(patchcode, "apple"),
9817 "Expected patchcode to be unchanged, got %s\n", patchcode);
9818 ok(!lstrcmpA(targetprod, "banana"),
9819 "Expected targetprod to be unchanged, got %s\n", targetprod);
9820 ok(context == 0xdeadbeef,
9821 "Expected context to be unchanged, got %d\n", context);
9822 ok(!lstrcmpA(targetsid, "kiwi"),
9823 "Expected targetsid to be unchanged, got %s\n", targetsid);
9824 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9825
9826 RegDeleteValueA(hpatch, "State");
9827 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9828 RegCloseKey(hpatch);
9829 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9830 RegCloseKey(udpatch);
9831 delete_key(udprod, "", access & KEY_WOW64_64KEY);
9832 RegCloseKey(udprod);
9833 RegDeleteValueA(patches, "Patches");
9834 delete_key(patches, "", access & KEY_WOW64_64KEY);
9835 RegCloseKey(patches);
9836 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9837 RegCloseKey(prodkey);
9838 }
9839
9840 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
9841 {
9842 MSIINSTALLCONTEXT context;
9843 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9844 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9845 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9846 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9847 HKEY prodkey, patches, udprod, udpatch;
9848 HKEY userkey, hpatch;
9849 DWORD size, data;
9850 LONG res;
9851 UINT r;
9852 REGSAM access = KEY_ALL_ACCESS;
9853
9854 create_test_guid(prodcode, prod_squashed);
9855 create_test_guid(patch, patch_squashed);
9856
9857 if (is_wow64)
9858 access |= KEY_WOW64_64KEY;
9859
9860 /* MSIPATCHSTATE_APPLIED */
9861
9862 lstrcpyA(patchcode, "apple");
9863 lstrcpyA(targetprod, "banana");
9864 context = 0xdeadbeef;
9865 lstrcpyA(targetsid, "kiwi");
9866 size = MAX_PATH;
9867 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9868 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9869 &context, targetsid, &size);
9870 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9871 ok(!lstrcmpA(patchcode, "apple"),
9872 "Expected patchcode to be unchanged, got %s\n", patchcode);
9873 ok(!lstrcmpA(targetprod, "banana"),
9874 "Expected targetprod to be unchanged, got %s\n", targetprod);
9875 ok(context == 0xdeadbeef,
9876 "Expected context to be unchanged, got %d\n", context);
9877 ok(!lstrcmpA(targetsid, "kiwi"),
9878 "Expected targetsid to be unchanged, got %s\n", targetsid);
9879 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9880
9881 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9882 lstrcatA(keypath, prod_squashed);
9883
9884 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9885 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9886
9887 /* current user product key exists */
9888 lstrcpyA(patchcode, "apple");
9889 lstrcpyA(targetprod, "banana");
9890 context = 0xdeadbeef;
9891 lstrcpyA(targetsid, "kiwi");
9892 size = MAX_PATH;
9893 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9894 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9895 &context, targetsid, &size);
9896 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9897 ok(!lstrcmpA(patchcode, "apple"),
9898 "Expected patchcode to be unchanged, got %s\n", patchcode);
9899 ok(!lstrcmpA(targetprod, "banana"),
9900 "Expected targetprod to be unchanged, got %s\n", targetprod);
9901 ok(context == 0xdeadbeef,
9902 "Expected context to be unchanged, got %d\n", context);
9903 ok(!lstrcmpA(targetsid, "kiwi"),
9904 "Expected targetsid to be unchanged, got %s\n", targetsid);
9905 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9906
9907 res = RegCreateKeyA(prodkey, "Patches", &patches);
9908 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9909
9910 /* Patches key exists */
9911 lstrcpyA(patchcode, "apple");
9912 lstrcpyA(targetprod, "banana");
9913 context = 0xdeadbeef;
9914 lstrcpyA(targetsid, "kiwi");
9915 size = MAX_PATH;
9916 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9917 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9918 &context, targetsid, &size);
9919 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9920 ok(!lstrcmpA(patchcode, "apple"),
9921 "Expected patchcode to be unchanged, got %s\n", patchcode);
9922 ok(!lstrcmpA(targetprod, "banana"),
9923 "Expected targetprod to be unchanged, got %s\n", targetprod);
9924 ok(context == 0xdeadbeef,
9925 "Expected context to be unchanged, got %d\n", context);
9926 ok(!lstrcmpA(targetsid, "kiwi"),
9927 "Expected targetsid to be unchanged, got %s\n", targetsid);
9928 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9929
9930 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9931 (const BYTE *)patch_squashed,
9932 lstrlenA(patch_squashed) + 1);
9933 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9934
9935 /* Patches value exists, is not REG_MULTI_SZ */
9936 lstrcpyA(patchcode, "apple");
9937 lstrcpyA(targetprod, "banana");
9938 context = 0xdeadbeef;
9939 lstrcpyA(targetsid, "kiwi");
9940 size = MAX_PATH;
9941 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9942 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9943 &context, targetsid, &size);
9944 ok(r == ERROR_BAD_CONFIGURATION,
9945 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9946 ok(!lstrcmpA(patchcode, "apple"),
9947 "Expected patchcode to be unchanged, got %s\n", patchcode);
9948 ok(!lstrcmpA(targetprod, "banana"),
9949 "Expected targetprod to be unchanged, got %s\n", targetprod);
9950 ok(context == 0xdeadbeef,
9951 "Expected context to be unchanged, got %d\n", context);
9952 ok(!lstrcmpA(targetsid, "kiwi"),
9953 "Expected targetsid to be unchanged, got %s\n", targetsid);
9954 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9955
9956 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9957 (const BYTE *)"a\0b\0c\0\0", 7);
9958 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9959
9960 /* Patches value exists, is not a squashed guid */
9961 lstrcpyA(patchcode, "apple");
9962 lstrcpyA(targetprod, "banana");
9963 context = 0xdeadbeef;
9964 lstrcpyA(targetsid, "kiwi");
9965 size = MAX_PATH;
9966 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9967 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9968 &context, targetsid, &size);
9969 ok(r == ERROR_BAD_CONFIGURATION,
9970 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9971 ok(!lstrcmpA(patchcode, "apple"),
9972 "Expected patchcode to be unchanged, got %s\n", patchcode);
9973 ok(!lstrcmpA(targetprod, "banana"),
9974 "Expected targetprod to be unchanged, got %s\n", targetprod);
9975 ok(context == 0xdeadbeef,
9976 "Expected context to be unchanged, got %d\n", context);
9977 ok(!lstrcmpA(targetsid, "kiwi"),
9978 "Expected targetsid to be unchanged, got %s\n", targetsid);
9979 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9980
9981 patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
9982 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9983 (const BYTE *)patch_squashed,
9984 lstrlenA(patch_squashed) + 2);
9985 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9986
9987 /* Patches value exists */
9988 lstrcpyA(patchcode, "apple");
9989 lstrcpyA(targetprod, "banana");
9990 context = 0xdeadbeef;
9991 lstrcpyA(targetsid, "kiwi");
9992 size = MAX_PATH;
9993 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9994 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9995 &context, targetsid, &size);
9996 ok(r == ERROR_NO_MORE_ITEMS ||
9997 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
9998 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9999 ok(!lstrcmpA(patchcode, "apple"),
10000 "Expected patchcode to be unchanged, got %s\n", patchcode);
10001 ok(!lstrcmpA(targetprod, "banana"),
10002 "Expected targetprod to be unchanged, got %s\n", targetprod);
10003 ok(context == 0xdeadbeef,
10004 "Expected context to be unchanged, got %d\n", context);
10005 ok(!lstrcmpA(targetsid, "kiwi"),
10006 "Expected targetsid to be unchanged, got %s\n", targetsid);
10007 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10008
10009 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10010 (const BYTE *)"whatever", 9);
10011 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10012
10013 /* patch code value exists */
10014 lstrcpyA(patchcode, "apple");
10015 lstrcpyA(targetprod, "banana");
10016 context = 0xdeadbeef;
10017 lstrcpyA(targetsid, "kiwi");
10018 size = MAX_PATH;
10019 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10020 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10021 &context, targetsid, &size);
10022 ok(r == ERROR_NO_MORE_ITEMS ||
10023 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
10024 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10025 ok(!lstrcmpA(patchcode, "apple"),
10026 "Expected patchcode to be unchanged, got %s\n", patchcode);
10027 ok(!lstrcmpA(targetprod, "banana"),
10028 "Expected targetprod to be unchanged, got %s\n", targetprod);
10029 ok(context == 0xdeadbeef,
10030 "Expected context to be unchanged, got %d\n", context);
10031 ok(!lstrcmpA(targetsid, "kiwi"),
10032 "Expected targetsid to be unchanged, got %s\n", targetsid);
10033 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10034
10035 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10036 lstrcatA(keypath, expectedsid);
10037 lstrcatA(keypath, "\\Patches\\");
10038 lstrcatA(keypath, patch_squashed);
10039
10040 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10041 if (res == ERROR_ACCESS_DENIED)
10042 {
10043 skip("Not enough rights to perform tests\n");
10044 goto error;
10045 }
10046 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10047
10048 /* userdata patch key exists */
10049 lstrcpyA(patchcode, "apple");
10050 lstrcpyA(targetprod, "banana");
10051 context = 0xdeadbeef;
10052 lstrcpyA(targetsid, "kiwi");
10053 size = MAX_PATH;
10054 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10055 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10056 &context, targetsid, &size);
10057 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10058 ok(!lstrcmpA(patchcode, patch),
10059 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10060 ok(!lstrcmpA(targetprod, prodcode),
10061 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10062 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10063 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10064 ok(!lstrcmpA(targetsid, expectedsid),
10065 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10066 ok(size == lstrlenA(expectedsid),
10067 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10068
10069 /* MSIPATCHSTATE_SUPERSEDED */
10070
10071 lstrcpyA(patchcode, "apple");
10072 lstrcpyA(targetprod, "banana");
10073 context = 0xdeadbeef;
10074 lstrcpyA(targetsid, "kiwi");
10075 size = MAX_PATH;
10076 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10077 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10078 &context, targetsid, &size);
10079 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10080 ok(!lstrcmpA(patchcode, "apple"),
10081 "Expected patchcode to be unchanged, got %s\n", patchcode);
10082 ok(!lstrcmpA(targetprod, "banana"),
10083 "Expected targetprod to be unchanged, got %s\n", targetprod);
10084 ok(context == 0xdeadbeef,
10085 "Expected context to be unchanged, got %d\n", context);
10086 ok(!lstrcmpA(targetsid, "kiwi"),
10087 "Expected targetsid to be unchanged, got %s\n", targetsid);
10088 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10089
10090 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10091 lstrcatA(keypath, expectedsid);
10092 lstrcatA(keypath, "\\Products\\");
10093 lstrcatA(keypath, prod_squashed);
10094
10095 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10096 if (res == ERROR_ACCESS_DENIED)
10097 {
10098 skip("Not enough rights to perform tests\n");
10099 goto error;
10100 }
10101 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10102
10103 /* UserData product key exists */
10104 lstrcpyA(patchcode, "apple");
10105 lstrcpyA(targetprod, "banana");
10106 context = 0xdeadbeef;
10107 lstrcpyA(targetsid, "kiwi");
10108 size = MAX_PATH;
10109 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10110 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10111 &context, targetsid, &size);
10112 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10113 ok(!lstrcmpA(patchcode, "apple"),
10114 "Expected patchcode to be unchanged, got %s\n", patchcode);
10115 ok(!lstrcmpA(targetprod, "banana"),
10116 "Expected targetprod to be unchanged, got %s\n", targetprod);
10117 ok(context == 0xdeadbeef,
10118 "Expected context to be unchanged, got %d\n", context);
10119 ok(!lstrcmpA(targetsid, "kiwi"),
10120 "Expected targetsid to be unchanged, got %s\n", targetsid);
10121 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10122
10123 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10124 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10125
10126 /* UserData patches key exists */
10127 lstrcpyA(patchcode, "apple");
10128 lstrcpyA(targetprod, "banana");
10129 context = 0xdeadbeef;
10130 lstrcpyA(targetsid, "kiwi");
10131 size = MAX_PATH;
10132 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10133 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10134 &context, targetsid, &size);
10135 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10136 ok(!lstrcmpA(patchcode, "apple"),
10137 "Expected patchcode to be unchanged, got %s\n", patchcode);
10138 ok(!lstrcmpA(targetprod, "banana"),
10139 "Expected targetprod to be unchanged, got %s\n", targetprod);
10140 ok(context == 0xdeadbeef,
10141 "Expected context to be unchanged, got %d\n", context);
10142 ok(!lstrcmpA(targetsid, "kiwi"),
10143 "Expected targetsid to be unchanged, got %s\n", targetsid);
10144 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10145
10146 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10147 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10148
10149 /* specific UserData patch key exists */
10150 lstrcpyA(patchcode, "apple");
10151 lstrcpyA(targetprod, "banana");
10152 context = 0xdeadbeef;
10153 lstrcpyA(targetsid, "kiwi");
10154 size = MAX_PATH;
10155 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10156 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10157 &context, targetsid, &size);
10158 ok(r == ERROR_BAD_CONFIGURATION,
10159 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10160 ok(!lstrcmpA(patchcode, "apple"),
10161 "Expected patchcode to be unchanged, got %s\n", patchcode);
10162 ok(!lstrcmpA(targetprod, "banana"),
10163 "Expected targetprod to be unchanged, got %s\n", targetprod);
10164 ok(context == 0xdeadbeef,
10165 "Expected context to be unchanged, got %d\n", context);
10166 ok(!lstrcmpA(targetsid, "kiwi"),
10167 "Expected targetsid to be unchanged, got %s\n", targetsid);
10168 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10169
10170 data = MSIPATCHSTATE_SUPERSEDED;
10171 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10172 (const BYTE *)&data, sizeof(DWORD));
10173 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10174
10175 /* State value exists */
10176 lstrcpyA(patchcode, "apple");
10177 lstrcpyA(targetprod, "banana");
10178 context = 0xdeadbeef;
10179 lstrcpyA(targetsid, "kiwi");
10180 size = MAX_PATH;
10181 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10182 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10183 &context, targetsid, &size);
10184 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10185 ok(!lstrcmpA(patchcode, patch),
10186 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10187 ok(!lstrcmpA(targetprod, prodcode),
10188 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10189 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10190 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10191 ok(!lstrcmpA(targetsid, expectedsid),
10192 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10193 ok(size == lstrlenA(expectedsid),
10194 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10195
10196 /* MSIPATCHSTATE_OBSOLETED */
10197
10198 lstrcpyA(patchcode, "apple");
10199 lstrcpyA(targetprod, "banana");
10200 context = 0xdeadbeef;
10201 lstrcpyA(targetsid, "kiwi");
10202 size = MAX_PATH;
10203 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10204 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10205 &context, targetsid, &size);
10206 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10207 ok(!lstrcmpA(patchcode, "apple"),
10208 "Expected patchcode to be unchanged, got %s\n", patchcode);
10209 ok(!lstrcmpA(targetprod, "banana"),
10210 "Expected targetprod to be unchanged, got %s\n", targetprod);
10211 ok(context == 0xdeadbeef,
10212 "Expected context to be unchanged, got %d\n", context);
10213 ok(!lstrcmpA(targetsid, "kiwi"),
10214 "Expected targetsid to be unchanged, got %s\n", targetsid);
10215 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10216
10217 data = MSIPATCHSTATE_OBSOLETED;
10218 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10219 (const BYTE *)&data, sizeof(DWORD));
10220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10221
10222 /* State value is obsoleted */
10223 lstrcpyA(patchcode, "apple");
10224 lstrcpyA(targetprod, "banana");
10225 context = 0xdeadbeef;
10226 lstrcpyA(targetsid, "kiwi");
10227 size = MAX_PATH;
10228 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10229 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10230 &context, targetsid, &size);
10231 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10232 ok(!lstrcmpA(patchcode, patch),
10233 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10234 ok(!lstrcmpA(targetprod, prodcode),
10235 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10236 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10237 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10238 ok(!lstrcmpA(targetsid, expectedsid),
10239 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10240 ok(size == lstrlenA(expectedsid),
10241 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10242
10243 /* MSIPATCHSTATE_REGISTERED */
10244 /* FIXME */
10245
10246 /* MSIPATCHSTATE_ALL */
10247
10248 /* 1st */
10249 lstrcpyA(patchcode, "apple");
10250 lstrcpyA(targetprod, "banana");
10251 context = 0xdeadbeef;
10252 lstrcpyA(targetsid, "kiwi");
10253 size = MAX_PATH;
10254 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10255 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10256 &context, targetsid, &size);
10257 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10258 ok(!lstrcmpA(patchcode, patch),
10259 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10260 ok(!lstrcmpA(targetprod, prodcode),
10261 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10262 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10263 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10264 ok(!lstrcmpA(targetsid, expectedsid),
10265 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10266 ok(size == lstrlenA(expectedsid),
10267 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10268
10269 /* same patch in multiple places, only one is enumerated */
10270 lstrcpyA(patchcode, "apple");
10271 lstrcpyA(targetprod, "banana");
10272 context = 0xdeadbeef;
10273 lstrcpyA(targetsid, "kiwi");
10274 size = MAX_PATH;
10275 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10276 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10277 &context, targetsid, &size);
10278 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10279 ok(!lstrcmpA(patchcode, "apple"),
10280 "Expected patchcode to be unchanged, got %s\n", patchcode);
10281 ok(!lstrcmpA(targetprod, "banana"),
10282 "Expected targetprod to be unchanged, got %s\n", targetprod);
10283 ok(context == 0xdeadbeef,
10284 "Expected context to be unchanged, got %d\n", context);
10285 ok(!lstrcmpA(targetsid, "kiwi"),
10286 "Expected targetsid to be unchanged, got %s\n", targetsid);
10287 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10288
10289 RegDeleteValueA(hpatch, "State");
10290 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10291 RegCloseKey(hpatch);
10292 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10293 RegCloseKey(udpatch);
10294 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10295 RegCloseKey(udprod);
10296 delete_key(userkey, "", access & KEY_WOW64_64KEY);
10297 RegCloseKey(userkey);
10298 RegDeleteValueA(patches, patch_squashed);
10299 RegDeleteValueA(patches, "Patches");
10300
10301 error:
10302 RegDeleteKeyA(patches, "");
10303 RegCloseKey(patches);
10304 RegDeleteKeyA(prodkey, "");
10305 RegCloseKey(prodkey);
10306 }
10307
10308 static void test_MsiEnumPatchesEx_machine(void)
10309 {
10310 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10311 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
10312 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10313 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10314 HKEY prodkey, patches, udprod, udpatch;
10315 HKEY hpatch;
10316 MSIINSTALLCONTEXT context;
10317 DWORD size, data;
10318 LONG res;
10319 UINT r;
10320 REGSAM access = KEY_ALL_ACCESS;
10321
10322 create_test_guid(prodcode, prod_squashed);
10323 create_test_guid(patch, patch_squashed);
10324
10325 if (is_wow64)
10326 access |= KEY_WOW64_64KEY;
10327
10328 /* MSIPATCHSTATE_APPLIED */
10329
10330 lstrcpyA(patchcode, "apple");
10331 lstrcpyA(targetprod, "banana");
10332 context = 0xdeadbeef;
10333 lstrcpyA(targetsid, "kiwi");
10334 size = MAX_PATH;
10335 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10336 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10337 &context, targetsid, &size);
10338 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10339 ok(!lstrcmpA(patchcode, "apple"),
10340 "Expected patchcode to be unchanged, got %s\n", patchcode);
10341 ok(!lstrcmpA(targetprod, "banana"),
10342 "Expected targetprod to be unchanged, got %s\n", targetprod);
10343 ok(context == 0xdeadbeef,
10344 "Expected context to be unchanged, got %d\n", context);
10345 ok(!lstrcmpA(targetsid, "kiwi"),
10346 "Expected targetsid to be unchanged, got %s\n", targetsid);
10347 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10348
10349 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10350 lstrcatA(keypath, prod_squashed);
10351
10352 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10353 if (res == ERROR_ACCESS_DENIED)
10354 {
10355 skip("Not enough rights to perform tests\n");
10356 return;
10357 }
10358 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10359
10360 /* local product key exists */
10361 lstrcpyA(patchcode, "apple");
10362 lstrcpyA(targetprod, "banana");
10363 context = 0xdeadbeef;
10364 lstrcpyA(targetsid, "kiwi");
10365 size = MAX_PATH;
10366 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10367 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10368 &context, targetsid, &size);
10369 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10370 ok(!lstrcmpA(patchcode, "apple"),
10371 "Expected patchcode to be unchanged, got %s\n", patchcode);
10372 ok(!lstrcmpA(targetprod, "banana"),
10373 "Expected targetprod to be unchanged, got %s\n", targetprod);
10374 ok(context == 0xdeadbeef,
10375 "Expected context to be unchanged, got %d\n", context);
10376 ok(!lstrcmpA(targetsid, "kiwi"),
10377 "Expected targetsid to be unchanged, got %s\n", targetsid);
10378 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10379
10380 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10381 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10382
10383 /* Patches key exists */
10384 lstrcpyA(patchcode, "apple");
10385 lstrcpyA(targetprod, "banana");
10386 context = 0xdeadbeef;
10387 lstrcpyA(targetsid, "kiwi");
10388 size = MAX_PATH;
10389 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10390 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10391 &context, targetsid, &size);
10392 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10393 ok(!lstrcmpA(patchcode, "apple"),
10394 "Expected patchcode to be unchanged, got %s\n", patchcode);
10395 ok(!lstrcmpA(targetprod, "banana"),
10396 "Expected targetprod to be unchanged, got %s\n", targetprod);
10397 ok(context == 0xdeadbeef,
10398 "Expected context to be unchanged, got %d\n", context);
10399 ok(!lstrcmpA(targetsid, "kiwi"),
10400 "Expected targetsid to be unchanged, got %s\n", targetsid);
10401 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10402
10403 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10404 (const BYTE *)patch_squashed,
10405 lstrlenA(patch_squashed) + 1);
10406 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10407
10408 /* Patches value exists, is not REG_MULTI_SZ */
10409 lstrcpyA(patchcode, "apple");
10410 lstrcpyA(targetprod, "banana");
10411 context = 0xdeadbeef;
10412 lstrcpyA(targetsid, "kiwi");
10413 size = MAX_PATH;
10414 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10415 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10416 &context, targetsid, &size);
10417 ok(r == ERROR_BAD_CONFIGURATION,
10418 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10419 ok(!lstrcmpA(patchcode, "apple"),
10420 "Expected patchcode to be unchanged, got %s\n", patchcode);
10421 ok(!lstrcmpA(targetprod, "banana"),
10422 "Expected targetprod to be unchanged, got %s\n", targetprod);
10423 ok(context == 0xdeadbeef,
10424 "Expected context to be unchanged, got %d\n", context);
10425 ok(!lstrcmpA(targetsid, "kiwi"),
10426 "Expected targetsid to be unchanged, got %s\n", targetsid);
10427 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10428
10429 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10430 (const BYTE *)"a\0b\0c\0\0", 7);
10431 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10432
10433 /* Patches value exists, is not a squashed guid */
10434 lstrcpyA(patchcode, "apple");
10435 lstrcpyA(targetprod, "banana");
10436 context = 0xdeadbeef;
10437 lstrcpyA(targetsid, "kiwi");
10438 size = MAX_PATH;
10439 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10440 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10441 &context, targetsid, &size);
10442 ok(r == ERROR_BAD_CONFIGURATION,
10443 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10444 ok(!lstrcmpA(patchcode, "apple"),
10445 "Expected patchcode to be unchanged, got %s\n", patchcode);
10446 ok(!lstrcmpA(targetprod, "banana"),
10447 "Expected targetprod to be unchanged, got %s\n", targetprod);
10448 ok(context == 0xdeadbeef,
10449 "Expected context to be unchanged, got %d\n", context);
10450 ok(!lstrcmpA(targetsid, "kiwi"),
10451 "Expected targetsid to be unchanged, got %s\n", targetsid);
10452 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10453
10454 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10455 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10456 (const BYTE *)patch_squashed,
10457 lstrlenA(patch_squashed) + 2);
10458 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10459
10460 /* Patches value exists */
10461 lstrcpyA(patchcode, "apple");
10462 lstrcpyA(targetprod, "banana");
10463 context = 0xdeadbeef;
10464 lstrcpyA(targetsid, "kiwi");
10465 size = MAX_PATH;
10466 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10467 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10468 &context, targetsid, &size);
10469 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10470 ok(!lstrcmpA(patchcode, "apple"),
10471 "Expected patchcode to be unchanged, got %s\n", patchcode);
10472 ok(!lstrcmpA(targetprod, "banana"),
10473 "Expected targetprod to be unchanged, got %s\n", targetprod);
10474 ok(context == 0xdeadbeef,
10475 "Expected context to be unchanged, got %d\n", context);
10476 ok(!lstrcmpA(targetsid, "kiwi"),
10477 "Expected targetsid to be unchanged, got %s\n", targetsid);
10478 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10479
10480 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10481 (const BYTE *)"whatever", 9);
10482 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10483
10484 /* patch code value exists */
10485 lstrcpyA(patchcode, "apple");
10486 lstrcpyA(targetprod, "banana");
10487 context = 0xdeadbeef;
10488 lstrcpyA(targetsid, "kiwi");
10489 size = MAX_PATH;
10490 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10491 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10492 &context, targetsid, &size);
10493 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10494 ok(!lstrcmpA(patchcode, patch),
10495 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10496 ok(!lstrcmpA(targetprod, prodcode),
10497 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10498 ok(context == MSIINSTALLCONTEXT_MACHINE,
10499 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10500 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10501 ok(size == 0, "Expected 0, got %d\n", size);
10502
10503 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10504 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10505 lstrcatA(keypath, prod_squashed);
10506
10507 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10508 if (res == ERROR_ACCESS_DENIED)
10509 {
10510 skip("Not enough rights to perform tests\n");
10511 goto done;
10512 }
10513 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10514
10515 /* local UserData product key exists */
10516 lstrcpyA(patchcode, "apple");
10517 lstrcpyA(targetprod, "banana");
10518 context = 0xdeadbeef;
10519 lstrcpyA(targetsid, "kiwi");
10520 size = MAX_PATH;
10521 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10522 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10523 &context, targetsid, &size);
10524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10525 ok(!lstrcmpA(patchcode, patch),
10526 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10527 ok(!lstrcmpA(targetprod, prodcode),
10528 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10529 ok(context == MSIINSTALLCONTEXT_MACHINE,
10530 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10531 ok(!lstrcmpA(targetsid, ""),
10532 "Expected \"\", got \"%s\"\n", targetsid);
10533 ok(size == 0, "Expected 0, got %d\n", size);
10534
10535 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10536 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10537
10538 /* local UserData Patches key exists */
10539 lstrcpyA(patchcode, "apple");
10540 lstrcpyA(targetprod, "banana");
10541 context = 0xdeadbeef;
10542 lstrcpyA(targetsid, "kiwi");
10543 size = MAX_PATH;
10544 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10545 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10546 &context, targetsid, &size);
10547 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10548 ok(!lstrcmpA(patchcode, patch),
10549 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10550 ok(!lstrcmpA(targetprod, prodcode),
10551 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10552 ok(context == MSIINSTALLCONTEXT_MACHINE,
10553 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10554 ok(!lstrcmpA(targetsid, ""),
10555 "Expected \"\", got \"%s\"\n", targetsid);
10556 ok(size == 0, "Expected 0, got %d\n", size);
10557
10558 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10560
10561 /* local UserData Product patch key exists */
10562 lstrcpyA(patchcode, "apple");
10563 lstrcpyA(targetprod, "banana");
10564 context = 0xdeadbeef;
10565 lstrcpyA(targetsid, "kiwi");
10566 size = MAX_PATH;
10567 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10568 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10569 &context, targetsid, &size);
10570 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10571 ok(!lstrcmpA(patchcode, "apple"),
10572 "Expected patchcode to be unchanged, got %s\n", patchcode);
10573 ok(!lstrcmpA(targetprod, "banana"),
10574 "Expected targetprod to be unchanged, got %s\n", targetprod);
10575 ok(context == 0xdeadbeef,
10576 "Expected context to be unchanged, got %d\n", context);
10577 ok(!lstrcmpA(targetsid, "kiwi"),
10578 "Expected targetsid to be unchanged, got %s\n", targetsid);
10579 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10580
10581 data = MSIPATCHSTATE_APPLIED;
10582 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10583 (const BYTE *)&data, sizeof(DWORD));
10584 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10585
10586 /* State value exists */
10587 lstrcpyA(patchcode, "apple");
10588 lstrcpyA(targetprod, "banana");
10589 context = 0xdeadbeef;
10590 lstrcpyA(targetsid, "kiwi");
10591 size = MAX_PATH;
10592 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10593 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10594 &context, targetsid, &size);
10595 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10596 ok(!lstrcmpA(patchcode, patch),
10597 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10598 ok(!lstrcmpA(targetprod, prodcode),
10599 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10600 ok(context == MSIINSTALLCONTEXT_MACHINE,
10601 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10602 ok(!lstrcmpA(targetsid, ""),
10603 "Expected \"\", got \"%s\"\n", targetsid);
10604 ok(size == 0, "Expected 0, got %d\n", size);
10605
10606 /* MSIPATCHSTATE_SUPERSEDED */
10607
10608 lstrcpyA(patchcode, "apple");
10609 lstrcpyA(targetprod, "banana");
10610 context = 0xdeadbeef;
10611 lstrcpyA(targetsid, "kiwi");
10612 size = MAX_PATH;
10613 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10614 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10615 &context, targetsid, &size);
10616 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10617 ok(!lstrcmpA(patchcode, "apple"),
10618 "Expected patchcode to be unchanged, got %s\n", patchcode);
10619 ok(!lstrcmpA(targetprod, "banana"),
10620 "Expected targetprod to be unchanged, got %s\n", targetprod);
10621 ok(context == 0xdeadbeef,
10622 "Expected context to be unchanged, got %d\n", context);
10623 ok(!lstrcmpA(targetsid, "kiwi"),
10624 "Expected targetsid to be unchanged, got %s\n", targetsid);
10625 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10626
10627 data = MSIPATCHSTATE_SUPERSEDED;
10628 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10629 (const BYTE *)&data, sizeof(DWORD));
10630 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10631
10632 /* State value is MSIPATCHSTATE_SUPERSEDED */
10633 lstrcpyA(patchcode, "apple");
10634 lstrcpyA(targetprod, "banana");
10635 context = 0xdeadbeef;
10636 lstrcpyA(targetsid, "kiwi");
10637 size = MAX_PATH;
10638 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10639 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10640 &context, targetsid, &size);
10641 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10642 ok(!lstrcmpA(patchcode, patch),
10643 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10644 ok(!lstrcmpA(targetprod, prodcode),
10645 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10646 ok(context == MSIINSTALLCONTEXT_MACHINE,
10647 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10648 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10649 ok(size == 0, "Expected 0, got %d\n", size);
10650
10651 /* MSIPATCHSTATE_OBSOLETED */
10652
10653 lstrcpyA(patchcode, "apple");
10654 lstrcpyA(targetprod, "banana");
10655 context = 0xdeadbeef;
10656 lstrcpyA(targetsid, "kiwi");
10657 size = MAX_PATH;
10658 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10659 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10660 &context, targetsid, &size);
10661 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10662 ok(!lstrcmpA(patchcode, "apple"),
10663 "Expected patchcode to be unchanged, got %s\n", patchcode);
10664 ok(!lstrcmpA(targetprod, "banana"),
10665 "Expected targetprod to be unchanged, got %s\n", targetprod);
10666 ok(context == 0xdeadbeef,
10667 "Expected context to be unchanged, got %d\n", context);
10668 ok(!lstrcmpA(targetsid, "kiwi"),
10669 "Expected targetsid to be unchanged, got %s\n", targetsid);
10670 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10671
10672 data = MSIPATCHSTATE_OBSOLETED;
10673 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10674 (const BYTE *)&data, sizeof(DWORD));
10675 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10676
10677 /* State value is obsoleted */
10678 lstrcpyA(patchcode, "apple");
10679 lstrcpyA(targetprod, "banana");
10680 context = 0xdeadbeef;
10681 lstrcpyA(targetsid, "kiwi");
10682 size = MAX_PATH;
10683 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10684 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10685 &context, targetsid, &size);
10686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10687 ok(!lstrcmpA(patchcode, patch),
10688 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10689 ok(!lstrcmpA(targetprod, prodcode),
10690 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10691 ok(context == MSIINSTALLCONTEXT_MACHINE,
10692 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10693 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10694 ok(size == 0, "Expected 0, got %d\n", size);
10695
10696 /* MSIPATCHSTATE_REGISTERED */
10697 /* FIXME */
10698
10699 /* MSIPATCHSTATE_ALL */
10700
10701 /* 1st */
10702 lstrcpyA(patchcode, "apple");
10703 lstrcpyA(targetprod, "banana");
10704 context = 0xdeadbeef;
10705 lstrcpyA(targetsid, "kiwi");
10706 size = MAX_PATH;
10707 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10708 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10709 &context, targetsid, &size);
10710 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10711 ok(!lstrcmpA(patchcode, patch),
10712 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10713 ok(!lstrcmpA(targetprod, prodcode),
10714 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10715 ok(context == MSIINSTALLCONTEXT_MACHINE,
10716 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10717 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10718 ok(size == 0, "Expected 0, got %d\n", size);
10719
10720 /* same patch in multiple places, only one is enumerated */
10721 lstrcpyA(patchcode, "apple");
10722 lstrcpyA(targetprod, "banana");
10723 context = 0xdeadbeef;
10724 lstrcpyA(targetsid, "kiwi");
10725 size = MAX_PATH;
10726 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10727 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10728 &context, targetsid, &size);
10729 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10730 ok(!lstrcmpA(patchcode, "apple"),
10731 "Expected patchcode to be unchanged, got %s\n", patchcode);
10732 ok(!lstrcmpA(targetprod, "banana"),
10733 "Expected targetprod to be unchanged, got %s\n", targetprod);
10734 ok(context == 0xdeadbeef,
10735 "Expected context to be unchanged, got %d\n", context);
10736 ok(!lstrcmpA(targetsid, "kiwi"),
10737 "Expected targetsid to be unchanged, got %s\n", targetsid);
10738 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10739
10740 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10741 RegCloseKey(hpatch);
10742 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10743 RegCloseKey(udpatch);
10744
10745 done:
10746 RegDeleteValueA(patches, patch_squashed);
10747 RegDeleteValueA(patches, "Patches");
10748 delete_key(patches, "", access & KEY_WOW64_64KEY);
10749 RegCloseKey(patches);
10750 RegDeleteValueA(hpatch, "State");
10751 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10752 RegCloseKey(udprod);
10753 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10754 RegCloseKey(prodkey);
10755 }
10756
10757 static void test_MsiEnumPatchesEx(void)
10758 {
10759 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10760 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10761 CHAR patchcode[MAX_PATH];
10762 MSIINSTALLCONTEXT context;
10763 LPSTR usersid;
10764 DWORD size;
10765 UINT r;
10766
10767 if (!pMsiEnumPatchesExA)
10768 {
10769 win_skip("MsiEnumPatchesExA not implemented\n");
10770 return;
10771 }
10772
10773 create_test_guid(prodcode, prod_squashed);
10774 usersid = get_user_sid();
10775
10776 /* empty szProductCode */
10777 lstrcpyA(patchcode, "apple");
10778 lstrcpyA(targetprod, "banana");
10779 context = 0xdeadbeef;
10780 lstrcpyA(targetsid, "kiwi");
10781 size = MAX_PATH;
10782 r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10783 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10784 targetsid, &size);
10785 ok(r == ERROR_INVALID_PARAMETER,
10786 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10787 ok(!lstrcmpA(patchcode, "apple"),
10788 "Expected patchcode to be unchanged, got %s\n", patchcode);
10789 ok(!lstrcmpA(targetprod, "banana"),
10790 "Expected targetprod to be unchanged, got %s\n", targetprod);
10791 ok(context == 0xdeadbeef,
10792 "Expected context to be unchanged, got %d\n", context);
10793 ok(!lstrcmpA(targetsid, "kiwi"),
10794 "Expected targetsid to be unchanged, got %s\n", targetsid);
10795 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10796
10797 /* garbage szProductCode */
10798 lstrcpyA(patchcode, "apple");
10799 lstrcpyA(targetprod, "banana");
10800 context = 0xdeadbeef;
10801 lstrcpyA(targetsid, "kiwi");
10802 size = MAX_PATH;
10803 r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10804 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10805 targetsid, &size);
10806 ok(r == ERROR_INVALID_PARAMETER,
10807 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10808 ok(!lstrcmpA(patchcode, "apple"),
10809 "Expected patchcode to be unchanged, got %s\n", patchcode);
10810 ok(!lstrcmpA(targetprod, "banana"),
10811 "Expected targetprod to be unchanged, got %s\n", targetprod);
10812 ok(context == 0xdeadbeef,
10813 "Expected context to be unchanged, got %d\n", context);
10814 ok(!lstrcmpA(targetsid, "kiwi"),
10815 "Expected targetsid to be unchanged, got %s\n", targetsid);
10816 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10817
10818 /* guid without brackets */
10819 lstrcpyA(patchcode, "apple");
10820 lstrcpyA(targetprod, "banana");
10821 context = 0xdeadbeef;
10822 lstrcpyA(targetsid, "kiwi");
10823 size = MAX_PATH;
10824 r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
10825 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10826 0, patchcode, targetprod, &context,
10827 targetsid, &size);
10828 ok(r == ERROR_INVALID_PARAMETER,
10829 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10830 ok(!lstrcmpA(patchcode, "apple"),
10831 "Expected patchcode to be unchanged, got %s\n", patchcode);
10832 ok(!lstrcmpA(targetprod, "banana"),
10833 "Expected targetprod to be unchanged, got %s\n", targetprod);
10834 ok(context == 0xdeadbeef,
10835 "Expected context to be unchanged, got %d\n", context);
10836 ok(!lstrcmpA(targetsid, "kiwi"),
10837 "Expected targetsid to be unchanged, got %s\n", targetsid);
10838 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10839
10840 /* guid with brackets */
10841 lstrcpyA(patchcode, "apple");
10842 lstrcpyA(targetprod, "banana");
10843 context = 0xdeadbeef;
10844 lstrcpyA(targetsid, "kiwi");
10845 size = MAX_PATH;
10846 r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
10847 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10848 0, patchcode, targetprod, &context,
10849 targetsid, &size);
10850 ok(r == ERROR_NO_MORE_ITEMS,
10851 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10852 ok(!lstrcmpA(patchcode, "apple"),
10853 "Expected patchcode to be unchanged, got %s\n", patchcode);
10854 ok(!lstrcmpA(targetprod, "banana"),
10855 "Expected targetprod to be unchanged, got %s\n", targetprod);
10856 ok(context == 0xdeadbeef,
10857 "Expected context to be unchanged, got %d\n", context);
10858 ok(!lstrcmpA(targetsid, "kiwi"),
10859 "Expected targetsid to be unchanged, got %s\n", targetsid);
10860 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10861
10862 /* szUserSid is S-1-5-18 */
10863 lstrcpyA(patchcode, "apple");
10864 lstrcpyA(targetprod, "banana");
10865 context = 0xdeadbeef;
10866 lstrcpyA(targetsid, "kiwi");
10867 size = MAX_PATH;
10868 r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
10869 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10870 0, patchcode, targetprod, &context,
10871 targetsid, &size);
10872 ok(r == ERROR_INVALID_PARAMETER,
10873 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10874 ok(!lstrcmpA(patchcode, "apple"),
10875 "Expected patchcode to be unchanged, got %s\n", patchcode);
10876 ok(!lstrcmpA(targetprod, "banana"),
10877 "Expected targetprod to be unchanged, got %s\n", targetprod);
10878 ok(context == 0xdeadbeef,
10879 "Expected context to be unchanged, got %d\n", context);
10880 ok(!lstrcmpA(targetsid, "kiwi"),
10881 "Expected targetsid to be unchanged, got %s\n", targetsid);
10882 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10883
10884 /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
10885 lstrcpyA(patchcode, "apple");
10886 lstrcpyA(targetprod, "banana");
10887 context = 0xdeadbeef;
10888 lstrcpyA(targetsid, "kiwi");
10889 size = MAX_PATH;
10890 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
10891 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10892 &context, targetsid, &size);
10893 ok(r == ERROR_INVALID_PARAMETER,
10894 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10895 ok(!lstrcmpA(patchcode, "apple"),
10896 "Expected patchcode to be unchanged, got %s\n", patchcode);
10897 ok(!lstrcmpA(targetprod, "banana"),
10898 "Expected targetprod to be unchanged, got %s\n", targetprod);
10899 ok(context == 0xdeadbeef,
10900 "Expected context to be unchanged, got %d\n", context);
10901 ok(!lstrcmpA(targetsid, "kiwi"),
10902 "Expected targetsid to be unchanged, got %s\n", targetsid);
10903 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10904
10905 /* dwContext is out of bounds */
10906 lstrcpyA(patchcode, "apple");
10907 lstrcpyA(targetprod, "banana");
10908 context = 0xdeadbeef;
10909 lstrcpyA(targetsid, "kiwi");
10910 size = MAX_PATH;
10911 r = pMsiEnumPatchesExA(prodcode, usersid, 0,
10912 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10913 &context, targetsid, &size);
10914 ok(r == ERROR_INVALID_PARAMETER,
10915 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10916 ok(!lstrcmpA(patchcode, "apple"),
10917 "Expected patchcode to be unchanged, got %s\n", patchcode);
10918 ok(!lstrcmpA(targetprod, "banana"),
10919 "Expected targetprod to be unchanged, got %s\n", targetprod);
10920 ok(context == 0xdeadbeef,
10921 "Expected context to be unchanged, got %d\n", context);
10922 ok(!lstrcmpA(targetsid, "kiwi"),
10923 "Expected targetsid to be unchanged, got %s\n", targetsid);
10924 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10925
10926 /* dwContext is out of bounds */
10927 lstrcpyA(patchcode, "apple");
10928 lstrcpyA(targetprod, "banana");
10929 context = 0xdeadbeef;
10930 lstrcpyA(targetsid, "kiwi");
10931 size = MAX_PATH;
10932 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
10933 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10934 &context, targetsid, &size);
10935 ok(r == ERROR_INVALID_PARAMETER,
10936 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10937 ok(!lstrcmpA(patchcode, "apple"),
10938 "Expected patchcode to be unchanged, got %s\n", patchcode);
10939 ok(!lstrcmpA(targetprod, "banana"),
10940 "Expected targetprod to be unchanged, got %s\n", targetprod);
10941 ok(context == 0xdeadbeef,
10942 "Expected context to be unchanged, got %d\n", context);
10943 ok(!lstrcmpA(targetsid, "kiwi"),
10944 "Expected targetsid to be unchanged, got %s\n", targetsid);
10945 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10946
10947 /* dwFilter is out of bounds */
10948 lstrcpyA(patchcode, "apple");
10949 lstrcpyA(targetprod, "banana");
10950 context = 0xdeadbeef;
10951 lstrcpyA(targetsid, "kiwi");
10952 size = MAX_PATH;
10953 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10954 MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
10955 &context, targetsid, &size);
10956 ok(r == ERROR_INVALID_PARAMETER,
10957 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10958 ok(!lstrcmpA(patchcode, "apple"),
10959 "Expected patchcode to be unchanged, got %s\n", patchcode);
10960 ok(!lstrcmpA(targetprod, "banana"),
10961 "Expected targetprod to be unchanged, got %s\n", targetprod);
10962 ok(context == 0xdeadbeef,
10963 "Expected context to be unchanged, got %d\n", context);
10964 ok(!lstrcmpA(targetsid, "kiwi"),
10965 "Expected targetsid to be unchanged, got %s\n", targetsid);
10966 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10967
10968 /* dwFilter is out of bounds */
10969 lstrcpyA(patchcode, "apple");
10970 lstrcpyA(targetprod, "banana");
10971 context = 0xdeadbeef;
10972 lstrcpyA(targetsid, "kiwi");
10973 size = MAX_PATH;
10974 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10975 MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
10976 &context, targetsid, &size);
10977 ok(r == ERROR_INVALID_PARAMETER,
10978 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10979 ok(!lstrcmpA(patchcode, "apple"),
10980 "Expected patchcode to be unchanged, got %s\n", patchcode);
10981 ok(!lstrcmpA(targetprod, "banana"),
10982 "Expected targetprod to be unchanged, got %s\n", targetprod);
10983 ok(context == 0xdeadbeef,
10984 "Expected context to be unchanged, got %d\n", context);
10985 ok(!lstrcmpA(targetsid, "kiwi"),
10986 "Expected targetsid to be unchanged, got %s\n", targetsid);
10987 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10988
10989 /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
10990 lstrcpyA(patchcode, "apple");
10991 lstrcpyA(targetprod, "banana");
10992 context = 0xdeadbeef;
10993 lstrcpyA(targetsid, "kiwi");
10994 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10995 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10996 &context, targetsid, NULL);
10997 ok(r == ERROR_INVALID_PARAMETER,
10998 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10999 ok(!lstrcmpA(patchcode, "apple"),
11000 "Expected patchcode to be unchanged, got %s\n", patchcode);
11001 ok(!lstrcmpA(targetprod, "banana"),
11002 "Expected targetprod to be unchanged, got %s\n", targetprod);
11003 ok(context == 0xdeadbeef,
11004 "Expected context to be unchanged, got %d\n", context);
11005 ok(!lstrcmpA(targetsid, "kiwi"),
11006 "Expected targetsid to be unchanged, got %s\n", targetsid);
11007
11008 test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
11009 test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
11010 test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
11011 test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
11012 test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
11013 /* FIXME: Successfully test userunmanaged with a different user */
11014 test_MsiEnumPatchesEx_machine();
11015 LocalFree(usersid);
11016 }
11017
11018 static void test_MsiEnumPatches(void)
11019 {
11020 CHAR keypath[MAX_PATH], patch[MAX_PATH];
11021 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
11022 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11023 CHAR transforms[MAX_PATH];
11024 WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
11025 HKEY prodkey, patches, udprod;
11026 HKEY userkey, hpatch, udpatch;
11027 DWORD size, data;
11028 LPSTR usersid;
11029 LONG res;
11030 UINT r;
11031 REGSAM access = KEY_ALL_ACCESS;
11032
11033 create_test_guid(prodcode, prod_squashed);
11034 create_test_guid(patchcode, patch_squashed);
11035 usersid = get_user_sid();
11036
11037 if (is_wow64)
11038 access |= KEY_WOW64_64KEY;
11039
11040 /* NULL szProduct */
11041 size = MAX_PATH;
11042 lstrcpyA(patch, "apple");
11043 lstrcpyA(transforms, "banana");
11044 r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
11045 ok(r == ERROR_INVALID_PARAMETER,
11046 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11047 ok(!lstrcmpA(patch, "apple"),
11048 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11049 ok(!lstrcmpA(transforms, "banana"),
11050 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11051 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11052
11053 /* empty szProduct */
11054 size = MAX_PATH;
11055 lstrcpyA(patch, "apple");
11056 lstrcpyA(transforms, "banana");
11057 r = MsiEnumPatchesA("", 0, patch, transforms, &size);
11058 ok(r == ERROR_INVALID_PARAMETER,
11059 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11060 ok(!lstrcmpA(patch, "apple"),
11061 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11062 ok(!lstrcmpA(transforms, "banana"),
11063 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11064 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11065
11066 /* garbage szProduct */
11067 size = MAX_PATH;
11068 lstrcpyA(patch, "apple");
11069 lstrcpyA(transforms, "banana");
11070 r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
11071 ok(r == ERROR_INVALID_PARAMETER,
11072 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11073 ok(!lstrcmpA(patch, "apple"),
11074 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11075 ok(!lstrcmpA(transforms, "banana"),
11076 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11077 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11078
11079 /* guid without brackets */
11080 size = MAX_PATH;
11081 lstrcpyA(patch, "apple");
11082 lstrcpyA(transforms, "banana");
11083 r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
11084 transforms, &size);
11085 ok(r == ERROR_INVALID_PARAMETER,
11086 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11087 ok(!lstrcmpA(patch, "apple"),
11088 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11089 ok(!lstrcmpA(transforms, "banana"),
11090 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11091 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11092
11093 /* guid with brackets */
11094 size = MAX_PATH;
11095 lstrcpyA(patch, "apple");
11096 lstrcpyA(transforms, "banana");
11097 r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
11098 transforms, &size);
11099 ok(r == ERROR_UNKNOWN_PRODUCT,
11100 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11101 ok(!lstrcmpA(patch, "apple"),
11102 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11103 ok(!lstrcmpA(transforms, "banana"),
11104 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11105 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11106
11107 /* same length as guid, but random */
11108 size = MAX_PATH;
11109 lstrcpyA(patch, "apple");
11110 lstrcpyA(transforms, "banana");
11111 r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
11112 transforms, &size);
11113 ok(r == ERROR_INVALID_PARAMETER,
11114 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11115 ok(!lstrcmpA(patch, "apple"),
11116 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11117 ok(!lstrcmpA(transforms, "banana"),
11118 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11119 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11120
11121 /* MSIINSTALLCONTEXT_USERMANAGED */
11122
11123 size = MAX_PATH;
11124 lstrcpyA(patch, "apple");
11125 lstrcpyA(transforms, "banana");
11126 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11127 ok(r == ERROR_UNKNOWN_PRODUCT,
11128 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11129 ok(!lstrcmpA(patch, "apple"),
11130 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11131 ok(!lstrcmpA(transforms, "banana"),
11132 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11133 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11134
11135 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11136 lstrcatA(keypath, usersid);
11137 lstrcatA(keypath, "\\Installer\\Products\\");
11138 lstrcatA(keypath, prod_squashed);
11139
11140 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11141 if (res == ERROR_ACCESS_DENIED)
11142 {
11143 skip("Not enough rights to perform tests\n");
11144 LocalFree(usersid);
11145 return;
11146 }
11147 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11148
11149 /* managed product key exists */
11150 size = MAX_PATH;
11151 lstrcpyA(patch, "apple");
11152 lstrcpyA(transforms, "banana");
11153 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11154 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11155 ok(!lstrcmpA(patch, "apple"),
11156 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11157 ok(!lstrcmpA(transforms, "banana"),
11158 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11159 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11160
11161 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11162 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11163
11164 /* patches key exists */
11165 size = MAX_PATH;
11166 lstrcpyA(patch, "apple");
11167 lstrcpyA(transforms, "banana");
11168 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11169 ok(r == ERROR_NO_MORE_ITEMS ||
11170 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11171 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11172 ok(!lstrcmpA(patch, "apple"),
11173 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11174 ok(!lstrcmpA(transforms, "banana"),
11175 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11176 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11177
11178 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11179 (const BYTE *)patch_squashed,
11180 lstrlenA(patch_squashed) + 1);
11181 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11182
11183 /* Patches value exists, is not REG_MULTI_SZ */
11184 size = MAX_PATH;
11185 lstrcpyA(patch, "apple");
11186 lstrcpyA(transforms, "banana");
11187 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11188 ok(r == ERROR_BAD_CONFIGURATION ||
11189 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11190 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11191 ok(!lstrcmpA(patch, "apple"),
11192 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11193 ok(!lstrcmpA(transforms, "banana"),
11194 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11195 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11196
11197 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11198 (const BYTE *)"a\0b\0c\0\0", 7);
11199 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11200
11201 /* Patches value exists, is not a squashed guid */
11202 size = MAX_PATH;
11203 lstrcpyA(patch, "apple");
11204 lstrcpyA(transforms, "banana");
11205 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11206 ok(r == ERROR_BAD_CONFIGURATION,
11207 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11208 ok(!lstrcmpA(patch, "apple"),
11209 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11210 ok(!lstrcmpA(transforms, "banana"),
11211 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11212 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11213
11214 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11215 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11216 (const BYTE *)patch_squashed,
11217 lstrlenA(patch_squashed) + 2);
11218 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11219
11220 /* Patches value exists */
11221 size = MAX_PATH;
11222 lstrcpyA(patch, "apple");
11223 lstrcpyA(transforms, "banana");
11224 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11225 ok(r == ERROR_NO_MORE_ITEMS ||
11226 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11227 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11228 ok(!lstrcmpA(patch, "apple") ||
11229 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
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 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11236 (const BYTE *)"whatever", 9);
11237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11238
11239 /* patch squashed value exists */
11240 size = MAX_PATH;
11241 lstrcpyA(patch, "apple");
11242 lstrcpyA(transforms, "banana");
11243 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11244 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11245 ok(!lstrcmpA(patch, patchcode),
11246 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11247 ok(!lstrcmpA(transforms, "whatever"),
11248 "Expected \"whatever\", got \"%s\"\n", transforms);
11249 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11250
11251 /* lpPatchBuf is NULL */
11252 size = MAX_PATH;
11253 lstrcpyA(transforms, "banana");
11254 r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
11255 ok(r == ERROR_INVALID_PARAMETER,
11256 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11257 ok(!lstrcmpA(transforms, "banana"),
11258 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11259 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11260
11261 /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
11262 size = MAX_PATH;
11263 lstrcpyA(patch, "apple");
11264 r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
11265 ok(r == ERROR_INVALID_PARAMETER,
11266 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11267 ok(!lstrcmpA(patch, "apple"),
11268 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11269 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11270
11271 /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
11272 lstrcpyA(patch, "apple");
11273 lstrcpyA(transforms, "banana");
11274 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
11275 ok(r == ERROR_INVALID_PARAMETER,
11276 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11277 ok(!lstrcmpA(patch, "apple"),
11278 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11279 ok(!lstrcmpA(transforms, "banana"),
11280 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11281
11282 /* pcchTransformsBuf is too small */
11283 size = 6;
11284 lstrcpyA(patch, "apple");
11285 lstrcpyA(transforms, "banana");
11286 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11287 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11288 ok(!lstrcmpA(patch, patchcode),
11289 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11290 ok(!lstrcmpA(transforms, "whate") ||
11291 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11292 "Expected \"whate\", got \"%s\"\n", transforms);
11293 ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
11294
11295 /* increase the index */
11296 size = MAX_PATH;
11297 lstrcpyA(patch, "apple");
11298 lstrcpyA(transforms, "banana");
11299 r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
11300 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11301 ok(!lstrcmpA(patch, "apple"),
11302 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11303 ok(!lstrcmpA(transforms, "banana"),
11304 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11305 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11306
11307 /* increase again */
11308 size = MAX_PATH;
11309 lstrcpyA(patch, "apple");
11310 lstrcpyA(transforms, "banana");
11311 r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
11312 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11313 ok(!lstrcmpA(patch, "apple"),
11314 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11315 ok(!lstrcmpA(transforms, "banana"),
11316 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11317 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11318
11319 RegDeleteValueA(patches, "Patches");
11320 delete_key(patches, "", access & KEY_WOW64_64KEY);
11321 RegCloseKey(patches);
11322 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11323 RegCloseKey(prodkey);
11324
11325 /* MSIINSTALLCONTEXT_USERUNMANAGED */
11326
11327 size = MAX_PATH;
11328 lstrcpyA(patch, "apple");
11329 lstrcpyA(transforms, "banana");
11330 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11331 ok(r == ERROR_UNKNOWN_PRODUCT,
11332 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11333 ok(!lstrcmpA(patch, "apple"),
11334 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11335 ok(!lstrcmpA(transforms, "banana"),
11336 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11337 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11338
11339 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11340 lstrcatA(keypath, prod_squashed);
11341
11342 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11344
11345 /* current user product key exists */
11346 size = MAX_PATH;
11347 lstrcpyA(patch, "apple");
11348 lstrcpyA(transforms, "banana");
11349 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11350 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11351 ok(!lstrcmpA(patch, "apple"),
11352 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11353 ok(!lstrcmpA(transforms, "banana"),
11354 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11355 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11356
11357 res = RegCreateKeyA(prodkey, "Patches", &patches);
11358 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11359
11360 /* Patches key exists */
11361 size = MAX_PATH;
11362 lstrcpyA(patch, "apple");
11363 lstrcpyA(transforms, "banana");
11364 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11365 ok(r == ERROR_NO_MORE_ITEMS ||
11366 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11367 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11368 ok(!lstrcmpA(patch, "apple"),
11369 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11370 ok(!lstrcmpA(transforms, "banana"),
11371 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11372 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11373
11374 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11375 (const BYTE *)patch_squashed,
11376 lstrlenA(patch_squashed) + 1);
11377 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11378
11379 /* Patches value exists, is not REG_MULTI_SZ */
11380 size = MAX_PATH;
11381 lstrcpyA(patch, "apple");
11382 lstrcpyA(transforms, "banana");
11383 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11384 ok(r == ERROR_BAD_CONFIGURATION ||
11385 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11386 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11387 ok(!lstrcmpA(patch, "apple"),
11388 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11389 ok(!lstrcmpA(transforms, "banana"),
11390 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11391 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11392
11393 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11394 (const BYTE *)"a\0b\0c\0\0", 7);
11395 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11396
11397 /* Patches value exists, is not a squashed guid */
11398 size = MAX_PATH;
11399 lstrcpyA(patch, "apple");
11400 lstrcpyA(transforms, "banana");
11401 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11402 ok(r == ERROR_BAD_CONFIGURATION,
11403 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11404 ok(!lstrcmpA(patch, "apple"),
11405 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11406 ok(!lstrcmpA(transforms, "banana"),
11407 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11408 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11409
11410 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11411 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11412 (const BYTE *)patch_squashed,
11413 lstrlenA(patch_squashed) + 2);
11414 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11415
11416 /* Patches value exists */
11417 size = MAX_PATH;
11418 lstrcpyA(patch, "apple");
11419 lstrcpyA(transforms, "banana");
11420 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11421 ok(r == ERROR_NO_MORE_ITEMS ||
11422 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11423 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11424 ok(!lstrcmpA(patch, "apple") ||
11425 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11426 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11427 ok(!lstrcmpA(transforms, "banana"),
11428 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11429 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11430
11431 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11432 (const BYTE *)"whatever", 9);
11433 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11434
11435 /* patch code value exists */
11436 size = MAX_PATH;
11437 lstrcpyA(patch, "apple");
11438 lstrcpyA(transforms, "banana");
11439 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11440 ok(r == ERROR_NO_MORE_ITEMS ||
11441 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11442 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11443 ok(!lstrcmpA(patch, "apple") ||
11444 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11445 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11446 ok(!lstrcmpA(transforms, "banana") ||
11447 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11448 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11449 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11450
11451 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11452 lstrcatA(keypath, usersid);
11453 lstrcatA(keypath, "\\Patches\\");
11454 lstrcatA(keypath, patch_squashed);
11455
11456 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
11457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11458
11459 /* userdata patch key exists */
11460 size = MAX_PATH;
11461 lstrcpyA(patch, "apple");
11462 lstrcpyA(transforms, "banana");
11463 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11464 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11465 ok(!lstrcmpA(patch, patchcode),
11466 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11467 ok(!lstrcmpA(transforms, "whatever"),
11468 "Expected \"whatever\", got \"%s\"\n", transforms);
11469 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11470
11471 delete_key(userkey, "", access & KEY_WOW64_64KEY);
11472 RegCloseKey(userkey);
11473 RegDeleteValueA(patches, patch_squashed);
11474 RegDeleteValueA(patches, "Patches");
11475 RegDeleteKeyA(patches, "");
11476 RegCloseKey(patches);
11477 RegDeleteKeyA(prodkey, "");
11478 RegCloseKey(prodkey);
11479
11480 /* MSIINSTALLCONTEXT_MACHINE */
11481
11482 size = MAX_PATH;
11483 lstrcpyA(patch, "apple");
11484 lstrcpyA(transforms, "banana");
11485 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11486 ok(r == ERROR_UNKNOWN_PRODUCT,
11487 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11488 ok(!lstrcmpA(patch, "apple"),
11489 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11490 ok(!lstrcmpA(transforms, "banana"),
11491 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11492 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11493
11494 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11495 lstrcatA(keypath, prod_squashed);
11496
11497 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11498 if (res == ERROR_ACCESS_DENIED)
11499 {
11500 skip("Not enough rights to perform tests\n");
11501 LocalFree(usersid);
11502 return;
11503 }
11504 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11505
11506 /* local product key exists */
11507 size = MAX_PATH;
11508 lstrcpyA(patch, "apple");
11509 lstrcpyA(transforms, "banana");
11510 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11511 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11512 ok(!lstrcmpA(patch, "apple"),
11513 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11514 ok(!lstrcmpA(transforms, "banana"),
11515 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11516 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11517
11518 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11519 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11520
11521 /* Patches key exists */
11522 size = MAX_PATH;
11523 lstrcpyA(patch, "apple");
11524 lstrcpyA(transforms, "banana");
11525 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11526 ok(r == ERROR_NO_MORE_ITEMS ||
11527 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11528 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11529 ok(!lstrcmpA(patch, "apple"),
11530 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11531 ok(!lstrcmpA(transforms, "banana"),
11532 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11533 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11534
11535 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11536 (const BYTE *)patch_squashed,
11537 lstrlenA(patch_squashed) + 1);
11538 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11539
11540 /* Patches value exists, is not REG_MULTI_SZ */
11541 size = MAX_PATH;
11542 lstrcpyA(patch, "apple");
11543 lstrcpyA(transforms, "banana");
11544 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11545 ok(r == ERROR_BAD_CONFIGURATION ||
11546 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11547 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11548 ok(!lstrcmpA(patch, "apple"),
11549 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11550 ok(!lstrcmpA(transforms, "banana"),
11551 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11552 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11553
11554 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11555 (const BYTE *)"a\0b\0c\0\0", 7);
11556 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11557
11558 /* Patches value exists, is not a squashed guid */
11559 size = MAX_PATH;
11560 lstrcpyA(patch, "apple");
11561 lstrcpyA(transforms, "banana");
11562 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11563 ok(r == ERROR_BAD_CONFIGURATION,
11564 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11565 ok(!lstrcmpA(patch, "apple"),
11566 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11567 ok(!lstrcmpA(transforms, "banana"),
11568 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11569 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11570
11571 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11572 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11573 (const BYTE *)patch_squashed,
11574 lstrlenA(patch_squashed) + 2);
11575 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11576
11577 /* Patches value exists */
11578 size = MAX_PATH;
11579 lstrcpyA(patch, "apple");
11580 lstrcpyA(transforms, "banana");
11581 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11582 ok(r == ERROR_NO_MORE_ITEMS ||
11583 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11584 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11585 ok(!lstrcmpA(patch, "apple") ||
11586 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11587 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11588 ok(!lstrcmpA(transforms, "banana"),
11589 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11590 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11591
11592 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11593 (const BYTE *)"whatever", 9);
11594 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11595
11596 /* patch code value exists */
11597 size = MAX_PATH;
11598 lstrcpyA(patch, "apple");
11599 lstrcpyA(transforms, "banana");
11600 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11601 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11602 ok(!lstrcmpA(patch, patchcode),
11603 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11604 ok(!lstrcmpA(transforms, "whatever"),
11605 "Expected \"whatever\", got \"%s\"\n", transforms);
11606 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11607
11608 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
11609 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
11610 lstrcatA(keypath, prod_squashed);
11611
11612 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11613 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11614
11615 /* local UserData product 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 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
11628 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11629
11630 /* local UserData Patches key exists */
11631 size = MAX_PATH;
11632 lstrcpyA(patch, "apple");
11633 lstrcpyA(transforms, "banana");
11634 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11636 ok(!lstrcmpA(patch, patchcode),
11637 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11638 ok(!lstrcmpA(transforms, "whatever"),
11639 "Expected \"whatever\", got \"%s\"\n", transforms);
11640 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11641
11642 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11643 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11644
11645 /* local UserData Product patch key exists */
11646 size = MAX_PATH;
11647 lstrcpyA(patch, "apple");
11648 lstrcpyA(transforms, "banana");
11649 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11650 ok(r == ERROR_NO_MORE_ITEMS ||
11651 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11652 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11653 ok(!lstrcmpA(patch, "apple") ||
11654 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11655 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11656 ok(!lstrcmpA(transforms, "banana") ||
11657 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11658 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11659 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11660
11661 data = MSIPATCHSTATE_APPLIED;
11662 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11663 (const BYTE *)&data, sizeof(DWORD));
11664 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11665
11666 /* State value exists */
11667 size = MAX_PATH;
11668 lstrcpyA(patch, "apple");
11669 lstrcpyA(transforms, "banana");
11670 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11672 ok(!lstrcmpA(patch, patchcode),
11673 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11674 ok(!lstrcmpA(transforms, "whatever"),
11675 "Expected \"whatever\", got \"%s\"\n", transforms);
11676 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11677
11678 /* now duplicate some of the tests for the W version */
11679
11680 /* pcchTransformsBuf is too small */
11681 size = 6;
11682 MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
11683 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11684 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11685 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11686 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11687 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11688 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11689 ok(!lstrcmpA(patch, patchcode),
11690 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11691 ok(!lstrcmpA(transforms, "whate") ||
11692 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11693 "Expected \"whate\", got \"%s\"\n", transforms);
11694 ok(size == 8, "Expected 8, got %d\n", size);
11695
11696 /* patch code value exists */
11697 size = MAX_PATH;
11698 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11699 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11700 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11702 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11703 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11704 ok(!lstrcmpA(patch, patchcode),
11705 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11706 ok(!lstrcmpA(transforms, "whatever"),
11707 "Expected \"whatever\", got \"%s\"\n", transforms);
11708 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11709
11710 RegDeleteValueA(patches, patch_squashed);
11711 RegDeleteValueA(patches, "Patches");
11712 delete_key(patches, "", access & KEY_WOW64_64KEY);
11713 RegCloseKey(patches);
11714 RegDeleteValueA(hpatch, "State");
11715 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11716 RegCloseKey(hpatch);
11717 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11718 RegCloseKey(udpatch);
11719 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11720 RegCloseKey(udprod);
11721 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11722 RegCloseKey(prodkey);
11723 LocalFree(usersid);
11724 }
11725
11726 static void test_MsiGetPatchInfoEx(void)
11727 {
11728 CHAR keypath[MAX_PATH], val[MAX_PATH];
11729 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
11730 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11731 HKEY prodkey, patches, udprod, props;
11732 HKEY hpatch, udpatch, prodpatches;
11733 LPSTR usersid;
11734 DWORD size;
11735 LONG res;
11736 UINT r;
11737 REGSAM access = KEY_ALL_ACCESS;
11738
11739 if (!pMsiGetPatchInfoExA)
11740 {
11741 win_skip("MsiGetPatchInfoEx not implemented\n");
11742 return;
11743 }
11744
11745 create_test_guid(prodcode, prod_squashed);
11746 create_test_guid(patchcode, patch_squashed);
11747 usersid = get_user_sid();
11748
11749 if (is_wow64)
11750 access |= KEY_WOW64_64KEY;
11751
11752 /* NULL szPatchCode */
11753 lstrcpyA(val, "apple");
11754 size = MAX_PATH;
11755 r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11756 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11757 ok(r == ERROR_INVALID_PARAMETER,
11758 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11759 ok(!lstrcmpA(val, "apple"),
11760 "Expected val to be unchanged, got \"%s\"\n", val);
11761 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11762
11763 /* empty szPatchCode */
11764 size = MAX_PATH;
11765 lstrcpyA(val, "apple");
11766 r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11767 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11768 ok(r == ERROR_INVALID_PARAMETER,
11769 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11770 ok(!lstrcmpA(val, "apple"),
11771 "Expected val to be unchanged, got \"%s\"\n", val);
11772 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11773
11774 /* garbage szPatchCode */
11775 size = MAX_PATH;
11776 lstrcpyA(val, "apple");
11777 r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
11778 MSIINSTALLCONTEXT_USERMANAGED,
11779 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11780 ok(r == ERROR_INVALID_PARAMETER,
11781 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11782 ok(!lstrcmpA(val, "apple"),
11783 "Expected val to be unchanged, got \"%s\"\n", val);
11784 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11785
11786 /* guid without brackets */
11787 size = MAX_PATH;
11788 lstrcpyA(val, "apple");
11789 r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
11790 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11791 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11792 ok(r == ERROR_INVALID_PARAMETER,
11793 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11794 ok(!lstrcmpA(val, "apple"),
11795 "Expected val to be unchanged, got \"%s\"\n", val);
11796 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11797
11798 /* guid with brackets */
11799 size = MAX_PATH;
11800 lstrcpyA(val, "apple");
11801 r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
11802 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11803 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11804 ok(r == ERROR_UNKNOWN_PRODUCT,
11805 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11806 ok(!lstrcmpA(val, "apple"),
11807 "Expected val to be unchanged, got \"%s\"\n", val);
11808 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11809
11810 /* same length as guid, but random */
11811 size = MAX_PATH;
11812 lstrcpyA(val, "apple");
11813 r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
11814 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11815 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11816 ok(r == ERROR_INVALID_PARAMETER,
11817 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11818 ok(!lstrcmpA(val, "apple"),
11819 "Expected val to be unchanged, got \"%s\"\n", val);
11820 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11821
11822 /* NULL szProductCode */
11823 lstrcpyA(val, "apple");
11824 size = MAX_PATH;
11825 r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11826 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11827 ok(r == ERROR_INVALID_PARAMETER,
11828 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11829 ok(!lstrcmpA(val, "apple"),
11830 "Expected val to be unchanged, got \"%s\"\n", val);
11831 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11832
11833 /* empty szProductCode */
11834 size = MAX_PATH;
11835 lstrcpyA(val, "apple");
11836 r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
11837 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11838 ok(r == ERROR_INVALID_PARAMETER,
11839 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11840 ok(!lstrcmpA(val, "apple"),
11841 "Expected val to be unchanged, got \"%s\"\n", val);
11842 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11843
11844 /* garbage szProductCode */
11845 size = MAX_PATH;
11846 lstrcpyA(val, "apple");
11847 r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
11848 MSIINSTALLCONTEXT_USERMANAGED,
11849 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11850 ok(r == ERROR_INVALID_PARAMETER,
11851 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11852 ok(!lstrcmpA(val, "apple"),
11853 "Expected val to be unchanged, got \"%s\"\n", val);
11854 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11855
11856 /* guid without brackets */
11857 size = MAX_PATH;
11858 lstrcpyA(val, "apple");
11859 r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
11860 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11861 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11862 ok(r == ERROR_INVALID_PARAMETER,
11863 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11864 ok(!lstrcmpA(val, "apple"),
11865 "Expected val to be unchanged, got \"%s\"\n", val);
11866 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11867
11868 /* guid with brackets */
11869 size = MAX_PATH;
11870 lstrcpyA(val, "apple");
11871 r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
11872 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11873 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11874 ok(r == ERROR_UNKNOWN_PRODUCT,
11875 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11876 ok(!lstrcmpA(val, "apple"),
11877 "Expected val to be unchanged, got \"%s\"\n", val);
11878 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11879
11880 /* same length as guid, but random */
11881 size = MAX_PATH;
11882 lstrcpyA(val, "apple");
11883 r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
11884 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11885 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11886 ok(r == ERROR_INVALID_PARAMETER,
11887 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11888 ok(!lstrcmpA(val, "apple"),
11889 "Expected val to be unchanged, got \"%s\"\n", val);
11890 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11891
11892 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
11893 size = MAX_PATH;
11894 lstrcpyA(val, "apple");
11895 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11896 MSIINSTALLCONTEXT_USERMANAGED,
11897 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11898 ok(r == ERROR_INVALID_PARAMETER,
11899 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11900 ok(!lstrcmpA(val, "apple"),
11901 "Expected val to be unchanged, got \"%s\"\n", val);
11902 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11903
11904 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
11905 size = MAX_PATH;
11906 lstrcpyA(val, "apple");
11907 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11908 MSIINSTALLCONTEXT_USERUNMANAGED,
11909 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11910 ok(r == ERROR_INVALID_PARAMETER,
11911 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11912 ok(!lstrcmpA(val, "apple"),
11913 "Expected val to be unchanged, got \"%s\"\n", val);
11914 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11915
11916 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
11917 size = MAX_PATH;
11918 lstrcpyA(val, "apple");
11919 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11920 MSIINSTALLCONTEXT_MACHINE,
11921 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11922 ok(r == ERROR_INVALID_PARAMETER,
11923 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11924 ok(!lstrcmpA(val, "apple"),
11925 "Expected val to be unchanged, got \"%s\"\n", val);
11926 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11927
11928 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
11929 size = MAX_PATH;
11930 lstrcpyA(val, "apple");
11931 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11932 MSIINSTALLCONTEXT_MACHINE,
11933 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11934 ok(r == ERROR_INVALID_PARAMETER,
11935 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11936 ok(!lstrcmpA(val, "apple"),
11937 "Expected val to be unchanged, got \"%s\"\n", val);
11938 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11939
11940 /* dwContext is out of range */
11941 size = MAX_PATH;
11942 lstrcpyA(val, "apple");
11943 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11944 MSIINSTALLCONTEXT_NONE,
11945 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11946 ok(r == ERROR_INVALID_PARAMETER,
11947 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11948 ok(!lstrcmpA(val, "apple"),
11949 "Expected val to be unchanged, got \"%s\"\n", val);
11950 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11951
11952 /* dwContext is out of range */
11953 size = MAX_PATH;
11954 lstrcpyA(val, "apple");
11955 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11956 MSIINSTALLCONTEXT_ALL,
11957 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11958 ok(r == ERROR_INVALID_PARAMETER,
11959 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11960 ok(!lstrcmpA(val, "apple"),
11961 "Expected val to be unchanged, got \"%s\"\n", val);
11962 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11963
11964 /* dwContext is invalid */
11965 size = MAX_PATH;
11966 lstrcpyA(val, "apple");
11967 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
11968 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11969 ok(r == ERROR_INVALID_PARAMETER,
11970 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11971 ok(!lstrcmpA(val, "apple"),
11972 "Expected val to be unchanged, got \"%s\"\n", val);
11973 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11974
11975 /* MSIINSTALLCONTEXT_USERMANAGED */
11976
11977 size = MAX_PATH;
11978 lstrcpyA(val, "apple");
11979 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11980 MSIINSTALLCONTEXT_USERMANAGED,
11981 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11982 ok(r == ERROR_UNKNOWN_PRODUCT,
11983 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11984 ok(!lstrcmpA(val, "apple"),
11985 "Expected val to be unchanged, got \"%s\"\n", val);
11986 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11987
11988 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11989 lstrcatA(keypath, usersid);
11990 lstrcatA(keypath, "\\Products\\");
11991 lstrcatA(keypath, prod_squashed);
11992
11993 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11994 if (res == ERROR_ACCESS_DENIED)
11995 {
11996 skip("Not enough rights to perform tests\n");
11997 LocalFree(usersid);
11998 return;
11999 }
12000 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12001
12002 /* local UserData product key exists */
12003 size = MAX_PATH;
12004 lstrcpyA(val, "apple");
12005 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12006 MSIINSTALLCONTEXT_USERMANAGED,
12007 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12008 ok(r == ERROR_UNKNOWN_PRODUCT,
12009 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12010 ok(!lstrcmpA(val, "apple"),
12011 "Expected val to be unchanged, got \"%s\"\n", val);
12012 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12013
12014 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12015 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12016
12017 /* InstallProperties key exists */
12018 size = MAX_PATH;
12019 lstrcpyA(val, "apple");
12020 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12021 MSIINSTALLCONTEXT_USERMANAGED,
12022 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12023 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12024 ok(!lstrcmpA(val, "apple"),
12025 "Expected val to be unchanged, got \"%s\"\n", val);
12026 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12027
12028 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12030
12031 /* Patches key exists */
12032 size = MAX_PATH;
12033 lstrcpyA(val, "apple");
12034 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12035 MSIINSTALLCONTEXT_USERMANAGED,
12036 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12037 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCHA, got %d\n", r);
12038 ok(!lstrcmpA(val, "apple"),
12039 "Expected val to be unchanged, got \"%s\"\n", val);
12040 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12041
12042 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12043 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12044
12045 /* Patches key exists */
12046 size = MAX_PATH;
12047 lstrcpyA(val, "apple");
12048 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12049 MSIINSTALLCONTEXT_USERMANAGED,
12050 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12051 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12052 ok(!lstrcmpA(val, "apple"),
12053 "Expected val to be unchanged, got \"%s\"\n", val);
12054 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12055
12056 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
12057 lstrcatA(keypath, usersid);
12058 lstrcatA(keypath, "\\Installer\\Products\\");
12059 lstrcatA(keypath, prod_squashed);
12060
12061 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
12062 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12063
12064 /* managed product key exists */
12065 size = MAX_PATH;
12066 lstrcpyA(val, "apple");
12067 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12068 MSIINSTALLCONTEXT_USERMANAGED,
12069 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12070 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12071 ok(!lstrcmpA(val, "apple"),
12072 "Expected val to be unchanged, got \"%s\"\n", val);
12073 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12074
12075 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
12076 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12077
12078 /* Patches key exists */
12079 size = MAX_PATH;
12080 lstrcpyA(val, "apple");
12081 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12082 MSIINSTALLCONTEXT_USERMANAGED,
12083 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12084 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12085 ok(!lstrcmpA(val, "apple"),
12086 "Expected val to be unchanged, got \"%s\"\n", val);
12087 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12088
12089 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12090 (const BYTE *)"transforms", 11);
12091 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12092
12093 /* specific patch value exists */
12094 size = MAX_PATH;
12095 lstrcpyA(val, "apple");
12096 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12097 MSIINSTALLCONTEXT_USERMANAGED,
12098 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12099 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12100 ok(!lstrcmpA(val, "apple"),
12101 "Expected val to be unchanged, got \"%s\"\n", val);
12102 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12103
12104 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12105 lstrcatA(keypath, usersid);
12106 lstrcatA(keypath, "\\Patches\\");
12107 lstrcatA(keypath, patch_squashed);
12108
12109 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12110 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12111
12112 /* UserData Patches key exists */
12113 size = MAX_PATH;
12114 lstrcpyA(val, "apple");
12115 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12116 MSIINSTALLCONTEXT_USERMANAGED,
12117 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12118 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12119 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12120 ok(size == 0, "Expected 0, got %d\n", size);
12121
12122 res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
12123 (const BYTE *)"pack", 5);
12124 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12125
12126 /* ManagedLocalPatch value exists */
12127 size = MAX_PATH;
12128 lstrcpyA(val, "apple");
12129 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12130 MSIINSTALLCONTEXT_USERMANAGED,
12131 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12132 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12133 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12134 ok(size == 4, "Expected 4, got %d\n", size);
12135
12136 size = MAX_PATH;
12137 lstrcpyA(val, "apple");
12138 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12139 MSIINSTALLCONTEXT_USERMANAGED,
12140 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12141 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12142 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12143 ok(size == 10, "Expected 10, got %d\n", size);
12144
12145 res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
12146 (const BYTE *)"mydate", 7);
12147 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12148
12149 /* Installed value exists */
12150 size = MAX_PATH;
12151 lstrcpyA(val, "apple");
12152 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12153 MSIINSTALLCONTEXT_USERMANAGED,
12154 INSTALLPROPERTY_INSTALLDATEA, val, &size);
12155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12156 ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
12157 ok(size == 6, "Expected 6, got %d\n", size);
12158
12159 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
12160 (const BYTE *)"yes", 4);
12161 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12162
12163 /* Uninstallable value exists */
12164 size = MAX_PATH;
12165 lstrcpyA(val, "apple");
12166 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12167 MSIINSTALLCONTEXT_USERMANAGED,
12168 INSTALLPROPERTY_UNINSTALLABLEA, val, &size);
12169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12170 ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
12171 ok(size == 3, "Expected 3, got %d\n", size);
12172
12173 res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
12174 (const BYTE *)"good", 5);
12175 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12176
12177 /* State value exists */
12178 size = MAX_PATH;
12179 lstrcpyA(val, "apple");
12180 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12181 MSIINSTALLCONTEXT_USERMANAGED,
12182 INSTALLPROPERTY_PATCHSTATEA, val, &size);
12183 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12184 ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
12185 ok(size == 4, "Expected 4, got %d\n", size);
12186
12187 size = 1;
12188 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
12189 (const BYTE *)&size, sizeof(DWORD));
12190 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12191
12192 /* State value exists */
12193 size = MAX_PATH;
12194 lstrcpyA(val, "apple");
12195 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12196 MSIINSTALLCONTEXT_USERMANAGED,
12197 INSTALLPROPERTY_PATCHSTATEA, val, &size);
12198 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12199 todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
12200 ok(size == 1, "Expected 1, got %d\n", size);
12201
12202 res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
12203 (const BYTE *)"display", 8);
12204 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12205
12206 /* DisplayName value exists */
12207 size = MAX_PATH;
12208 lstrcpyA(val, "apple");
12209 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12210 MSIINSTALLCONTEXT_USERMANAGED,
12211 INSTALLPROPERTY_DISPLAYNAMEA, val, &size);
12212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12213 ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
12214 ok(size == 7, "Expected 7, got %d\n", size);
12215
12216 res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
12217 (const BYTE *)"moreinfo", 9);
12218 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12219
12220 /* MoreInfoURL value exists */
12221 size = MAX_PATH;
12222 lstrcpyA(val, "apple");
12223 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12224 MSIINSTALLCONTEXT_USERMANAGED,
12225 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12226 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12227 ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
12228 ok(size == 8, "Expected 8, got %d\n", size);
12229
12230 /* szProperty is invalid */
12231 size = MAX_PATH;
12232 lstrcpyA(val, "apple");
12233 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12234 MSIINSTALLCONTEXT_USERMANAGED,
12235 "IDontExist", val, &size);
12236 ok(r == ERROR_UNKNOWN_PROPERTY,
12237 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
12238 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12239 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12240
12241 /* lpValue is NULL, while pcchValue is non-NULL */
12242 size = MAX_PATH;
12243 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12244 MSIINSTALLCONTEXT_USERMANAGED,
12245 INSTALLPROPERTY_MOREINFOURLA, NULL, &size);
12246 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12247 ok(size == 16, "Expected 16, got %d\n", size);
12248
12249 /* pcchValue is NULL, while lpValue is non-NULL */
12250 lstrcpyA(val, "apple");
12251 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12252 MSIINSTALLCONTEXT_USERMANAGED,
12253 INSTALLPROPERTY_MOREINFOURLA, val, NULL);
12254 ok(r == ERROR_INVALID_PARAMETER,
12255 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12256 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12257
12258 /* both lpValue and pcchValue are NULL */
12259 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12260 MSIINSTALLCONTEXT_USERMANAGED,
12261 INSTALLPROPERTY_MOREINFOURLA, NULL, NULL);
12262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12263
12264 /* pcchValue doesn't have enough room for NULL terminator */
12265 size = 8;
12266 lstrcpyA(val, "apple");
12267 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12268 MSIINSTALLCONTEXT_USERMANAGED,
12269 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12270 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
12271 ok(!lstrcmpA(val, "moreinf"),
12272 "Expected \"moreinf\", got \"%s\"\n", val);
12273 ok(size == 16, "Expected 16, got %d\n", size);
12274
12275 /* pcchValue has exactly enough room for NULL terminator */
12276 size = 9;
12277 lstrcpyA(val, "apple");
12278 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12279 MSIINSTALLCONTEXT_USERMANAGED,
12280 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12281 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12282 ok(!lstrcmpA(val, "moreinfo"),
12283 "Expected \"moreinfo\", got \"%s\"\n", val);
12284 ok(size == 8, "Expected 8, got %d\n", size);
12285
12286 /* pcchValue is too small, lpValue is NULL */
12287 size = 0;
12288 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12289 MSIINSTALLCONTEXT_USERMANAGED,
12290 INSTALLPROPERTY_MOREINFOURLA, NULL, &size);
12291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12292 ok(size == 16, "Expected 16, got %d\n", size);
12293
12294 RegDeleteValueA(prodpatches, patch_squashed);
12295 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12296 RegCloseKey(prodpatches);
12297 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12298 RegCloseKey(prodkey);
12299
12300 /* UserData is sufficient for all properties
12301 * except INSTALLPROPERTY_TRANSFORMS
12302 */
12303 size = MAX_PATH;
12304 lstrcpyA(val, "apple");
12305 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12306 MSIINSTALLCONTEXT_USERMANAGED,
12307 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12309 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12310 ok(size == 4, "Expected 4, got %d\n", size);
12311
12312 /* UserData is sufficient for all properties
12313 * except INSTALLPROPERTY_TRANSFORMS
12314 */
12315 size = MAX_PATH;
12316 lstrcpyA(val, "apple");
12317 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12318 MSIINSTALLCONTEXT_USERMANAGED,
12319 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12320 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12321 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12322 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12323
12324 RegDeleteValueA(hpatch, "MoreInfoURL");
12325 RegDeleteValueA(hpatch, "Display");
12326 RegDeleteValueA(hpatch, "State");
12327 RegDeleteValueA(hpatch, "Uninstallable");
12328 RegDeleteValueA(hpatch, "Installed");
12329 RegDeleteValueA(udpatch, "ManagedLocalPackage");
12330 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12331 RegCloseKey(udpatch);
12332 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12333 RegCloseKey(hpatch);
12334 delete_key(patches, "", access & KEY_WOW64_64KEY);
12335 RegCloseKey(patches);
12336 delete_key(props, "", access & KEY_WOW64_64KEY);
12337 RegCloseKey(props);
12338 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12339 RegCloseKey(udprod);
12340
12341 /* MSIINSTALLCONTEXT_USERUNMANAGED */
12342
12343 size = MAX_PATH;
12344 lstrcpyA(val, "apple");
12345 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12346 MSIINSTALLCONTEXT_USERUNMANAGED,
12347 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12348 ok(r == ERROR_UNKNOWN_PRODUCT,
12349 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12350 ok(!lstrcmpA(val, "apple"),
12351 "Expected val to be unchanged, got \"%s\"\n", val);
12352 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12353
12354 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12355 lstrcatA(keypath, usersid);
12356 lstrcatA(keypath, "\\Products\\");
12357 lstrcatA(keypath, prod_squashed);
12358
12359 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12360 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12361
12362 /* local UserData product key exists */
12363 size = MAX_PATH;
12364 lstrcpyA(val, "apple");
12365 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12366 MSIINSTALLCONTEXT_USERUNMANAGED,
12367 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12368 ok(r == ERROR_UNKNOWN_PRODUCT,
12369 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12370 ok(!lstrcmpA(val, "apple"),
12371 "Expected val to be unchanged, got \"%s\"\n", val);
12372 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12373
12374 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12375 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12376
12377 /* InstallProperties key exists */
12378 size = MAX_PATH;
12379 lstrcpyA(val, "apple");
12380 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12381 MSIINSTALLCONTEXT_USERUNMANAGED,
12382 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12383 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12384 ok(!lstrcmpA(val, "apple"),
12385 "Expected val to be unchanged, got \"%s\"\n", val);
12386 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12387
12388 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12390
12391 /* Patches key exists */
12392 size = MAX_PATH;
12393 lstrcpyA(val, "apple");
12394 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12395 MSIINSTALLCONTEXT_USERUNMANAGED,
12396 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12397 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12398 ok(!lstrcmpA(val, "apple"),
12399 "Expected val to be unchanged, got \"%s\"\n", val);
12400 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12401
12402 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12403 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12404
12405 /* Patches key exists */
12406 size = MAX_PATH;
12407 lstrcpyA(val, "apple");
12408 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12409 MSIINSTALLCONTEXT_USERUNMANAGED,
12410 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12411 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12412 ok(!lstrcmpA(val, "apple"),
12413 "Expected val to be unchanged, got \"%s\"\n", val);
12414 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12415
12416 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
12417 lstrcatA(keypath, prod_squashed);
12418
12419 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
12420 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12421
12422 /* current user product key exists */
12423 size = MAX_PATH;
12424 lstrcpyA(val, "apple");
12425 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12426 MSIINSTALLCONTEXT_USERUNMANAGED,
12427 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12428 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12429 ok(!lstrcmpA(val, "apple"),
12430 "Expected val to be unchanged, got \"%s\"\n", val);
12431 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12432
12433 res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
12434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12435
12436 /* Patches key exists */
12437 size = MAX_PATH;
12438 lstrcpyA(val, "apple");
12439 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12440 MSIINSTALLCONTEXT_USERUNMANAGED,
12441 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12442 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12443 ok(!lstrcmpA(val, "apple"),
12444 "Expected val to be unchanged, got \"%s\"\n", val);
12445 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12446
12447 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12448 (const BYTE *)"transforms", 11);
12449 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12450
12451 /* specific patch value exists */
12452 size = MAX_PATH;
12453 lstrcpyA(val, "apple");
12454 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12455 MSIINSTALLCONTEXT_USERUNMANAGED,
12456 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12457 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12458 ok(!lstrcmpA(val, "apple"),
12459 "Expected val to be unchanged, got \"%s\"\n", val);
12460 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12461
12462 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12463 lstrcatA(keypath, usersid);
12464 lstrcatA(keypath, "\\Patches\\");
12465 lstrcatA(keypath, patch_squashed);
12466
12467 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12469
12470 /* UserData Patches key exists */
12471 size = MAX_PATH;
12472 lstrcpyA(val, "apple");
12473 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12474 MSIINSTALLCONTEXT_USERUNMANAGED,
12475 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12476 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12477 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12478 ok(size == 0, "Expected 0, got %d\n", size);
12479
12480 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12481 (const BYTE *)"pack", 5);
12482 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12483
12484 /* LocalPatch value exists */
12485 size = MAX_PATH;
12486 lstrcpyA(val, "apple");
12487 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12488 MSIINSTALLCONTEXT_USERUNMANAGED,
12489 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12490 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12491 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12492 ok(size == 4, "Expected 4, got %d\n", size);
12493
12494 size = MAX_PATH;
12495 lstrcpyA(val, "apple");
12496 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12497 MSIINSTALLCONTEXT_USERUNMANAGED,
12498 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12500 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12501 ok(size == 10, "Expected 10, got %d\n", size);
12502
12503 RegDeleteValueA(prodpatches, patch_squashed);
12504 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12505 RegCloseKey(prodpatches);
12506 RegDeleteKeyA(prodkey, "");
12507 RegCloseKey(prodkey);
12508
12509 /* UserData is sufficient for all properties
12510 * except INSTALLPROPERTY_TRANSFORMS
12511 */
12512 size = MAX_PATH;
12513 lstrcpyA(val, "apple");
12514 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12515 MSIINSTALLCONTEXT_USERUNMANAGED,
12516 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12518 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12519 ok(size == 4, "Expected 4, got %d\n", size);
12520
12521 /* UserData is sufficient for all properties
12522 * except INSTALLPROPERTY_TRANSFORMS
12523 */
12524 size = MAX_PATH;
12525 lstrcpyA(val, "apple");
12526 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12527 MSIINSTALLCONTEXT_USERUNMANAGED,
12528 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12529 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12530 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12531 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12532
12533 RegDeleteValueA(udpatch, "LocalPackage");
12534 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12535 RegCloseKey(udpatch);
12536 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12537 RegCloseKey(hpatch);
12538 delete_key(patches, "", access & KEY_WOW64_64KEY);
12539 RegCloseKey(patches);
12540 delete_key(props, "", access & KEY_WOW64_64KEY);
12541 RegCloseKey(props);
12542 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12543 RegCloseKey(udprod);
12544
12545 /* MSIINSTALLCONTEXT_MACHINE */
12546
12547 size = MAX_PATH;
12548 lstrcpyA(val, "apple");
12549 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12550 MSIINSTALLCONTEXT_MACHINE,
12551 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12552 ok(r == ERROR_UNKNOWN_PRODUCT,
12553 "Expected ERROR_UNKNOWN_PRODUCT, 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 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12559 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
12560 lstrcatA(keypath, prod_squashed);
12561
12562 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12563 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12564
12565 /* local UserData product key exists */
12566 size = MAX_PATH;
12567 lstrcpyA(val, "apple");
12568 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12569 MSIINSTALLCONTEXT_MACHINE,
12570 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12571 ok(r == ERROR_UNKNOWN_PRODUCT,
12572 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12573 ok(!lstrcmpA(val, "apple"),
12574 "Expected val to be unchanged, got \"%s\"\n", val);
12575 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12576
12577 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12578 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12579
12580 /* InstallProperties key exists */
12581 size = MAX_PATH;
12582 lstrcpyA(val, "apple");
12583 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12584 MSIINSTALLCONTEXT_MACHINE,
12585 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12586 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12587 ok(!lstrcmpA(val, "apple"),
12588 "Expected val to be unchanged, got \"%s\"\n", val);
12589 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12590
12591 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12593
12594 /* Patches key exists */
12595 size = MAX_PATH;
12596 lstrcpyA(val, "apple");
12597 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12598 MSIINSTALLCONTEXT_MACHINE,
12599 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12600 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12601 ok(!lstrcmpA(val, "apple"),
12602 "Expected val to be unchanged, got \"%s\"\n", val);
12603 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12604
12605 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12606 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12607
12608 /* Patches key exists */
12609 size = MAX_PATH;
12610 lstrcpyA(val, "apple");
12611 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12612 MSIINSTALLCONTEXT_MACHINE,
12613 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12614 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12615 ok(!lstrcmpA(val, "apple"),
12616 "Expected val to be unchanged, got \"%s\"\n", val);
12617 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12618
12619 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
12620 lstrcatA(keypath, prod_squashed);
12621
12622 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
12623 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12624
12625 /* local product key exists */
12626 size = MAX_PATH;
12627 lstrcpyA(val, "apple");
12628 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12629 MSIINSTALLCONTEXT_MACHINE,
12630 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12631 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12632 ok(!lstrcmpA(val, "apple"),
12633 "Expected val to be unchanged, got \"%s\"\n", val);
12634 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12635
12636 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
12637 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12638
12639 /* Patches key exists */
12640 size = MAX_PATH;
12641 lstrcpyA(val, "apple");
12642 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12643 MSIINSTALLCONTEXT_MACHINE,
12644 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12645 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12646 ok(!lstrcmpA(val, "apple"),
12647 "Expected val to be unchanged, got \"%s\"\n", val);
12648 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12649
12650 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12651 (const BYTE *)"transforms", 11);
12652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12653
12654 /* specific patch value exists */
12655 size = MAX_PATH;
12656 lstrcpyA(val, "apple");
12657 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12658 MSIINSTALLCONTEXT_MACHINE,
12659 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12660 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12661 ok(!lstrcmpA(val, "apple"),
12662 "Expected val to be unchanged, got \"%s\"\n", val);
12663 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12664
12665 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12666 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
12667 lstrcatA(keypath, patch_squashed);
12668
12669 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12670 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12671
12672 /* UserData Patches key exists */
12673 size = MAX_PATH;
12674 lstrcpyA(val, "apple");
12675 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12676 MSIINSTALLCONTEXT_MACHINE,
12677 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12679 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12680 ok(size == 0, "Expected 0, got %d\n", size);
12681
12682 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12683 (const BYTE *)"pack", 5);
12684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12685
12686 /* LocalPatch value exists */
12687 size = MAX_PATH;
12688 lstrcpyA(val, "apple");
12689 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12690 MSIINSTALLCONTEXT_MACHINE,
12691 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12693 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12694 ok(size == 4, "Expected 4, got %d\n", size);
12695
12696 size = MAX_PATH;
12697 lstrcpyA(val, "apple");
12698 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12699 MSIINSTALLCONTEXT_MACHINE,
12700 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12701 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12702 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12703 ok(size == 10, "Expected 10, got %d\n", size);
12704
12705 RegDeleteValueA(prodpatches, patch_squashed);
12706 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12707 RegCloseKey(prodpatches);
12708 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12709 RegCloseKey(prodkey);
12710
12711 /* UserData is sufficient for all properties
12712 * except INSTALLPROPERTY_TRANSFORMS
12713 */
12714 size = MAX_PATH;
12715 lstrcpyA(val, "apple");
12716 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12717 MSIINSTALLCONTEXT_MACHINE,
12718 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12719 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12720 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12721 ok(size == 4, "Expected 4, got %d\n", size);
12722
12723 /* UserData is sufficient for all properties
12724 * except INSTALLPROPERTY_TRANSFORMS
12725 */
12726 size = MAX_PATH;
12727 lstrcpyA(val, "apple");
12728 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12729 MSIINSTALLCONTEXT_MACHINE,
12730 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12731 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12732 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12733 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12734
12735 RegDeleteValueA(udpatch, "LocalPackage");
12736 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12737 RegCloseKey(udpatch);
12738 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12739 RegCloseKey(hpatch);
12740 delete_key(patches, "", access & KEY_WOW64_64KEY);
12741 RegCloseKey(patches);
12742 delete_key(props, "", access & KEY_WOW64_64KEY);
12743 RegCloseKey(props);
12744 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12745 RegCloseKey(udprod);
12746 LocalFree(usersid);
12747 }
12748
12749 static void test_MsiGetPatchInfo(void)
12750 {
12751 UINT r;
12752 char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
12753 char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
12754 WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
12755 HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
12756 HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
12757 DWORD size;
12758 LONG res;
12759 REGSAM access = KEY_ALL_ACCESS;
12760
12761 create_test_guid(patch_code, patch_squashed);
12762 create_test_guid(prod_code, prod_squashed);
12763 MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
12764
12765 if (is_wow64)
12766 access |= KEY_WOW64_64KEY;
12767
12768 r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
12769 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12770
12771 r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
12772 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12773
12774 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
12775 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
12776
12777 size = 0;
12778 r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
12779 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12780
12781 r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
12782 ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
12783
12784 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
12785 lstrcatA(keypath, prod_squashed);
12786
12787 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
12788 if (res == ERROR_ACCESS_DENIED)
12789 {
12790 skip("Not enough rights to perform tests\n");
12791 return;
12792 }
12793 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12794
12795 /* product key exists */
12796 size = MAX_PATH;
12797 lstrcpyA(val, "apple");
12798 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12799 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12800 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
12801 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12802
12803 res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
12804 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12805
12806 /* patches key exists */
12807 size = MAX_PATH;
12808 lstrcpyA(val, "apple");
12809 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12810 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12811 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12812 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12813
12814 res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
12815 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12816
12817 /* patch key exists */
12818 size = MAX_PATH;
12819 lstrcpyA(val, "apple");
12820 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12821 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12822 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12823 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12824
12825 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12826 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
12827 lstrcatA(keypath, prod_squashed);
12828
12829 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
12830 if (res == ERROR_ACCESS_DENIED)
12831 {
12832 skip("Not enough rights to perform tests\n");
12833 goto done;
12834 }
12835 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
12836
12837 /* UserData product key exists */
12838 size = MAX_PATH;
12839 lstrcpyA(val, "apple");
12840 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12841 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12842 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12843 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12844
12845 res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
12846 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12847
12848 /* InstallProperties key exists */
12849 size = MAX_PATH;
12850 lstrcpyA(val, "apple");
12851 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12852 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12853 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
12854 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12855
12856 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
12857 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12858
12859 /* UserData Patches key exists */
12860 size = MAX_PATH;
12861 lstrcpyA(val, "apple");
12862 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12863 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12864 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12865 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12866
12867 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
12868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12869
12870 res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
12871 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12872
12873 /* UserData product patch key exists */
12874 size = MAX_PATH;
12875 lstrcpyA(val, "apple");
12876 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12877 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12878 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12879 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12880
12881 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12882 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
12883 lstrcatA(keypath, patch_squashed);
12884
12885 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
12886 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12887
12888 res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
12889 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12890
12891 /* UserData Patch key exists */
12892 size = 0;
12893 lstrcpyA(val, "apple");
12894 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12895 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
12896 ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
12897 ok(size == 11, "expected 11 got %u\n", size);
12898
12899 size = MAX_PATH;
12900 lstrcpyA(val, "apple");
12901 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12902 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
12903 ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
12904 ok(size == 11, "expected 11 got %u\n", size);
12905
12906 size = 0;
12907 valW[0] = 0;
12908 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
12909 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
12910 ok(!valW[0], "expected 0 got %u\n", valW[0]);
12911 ok(size == 11, "expected 11 got %u\n", size);
12912
12913 size = MAX_PATH;
12914 valW[0] = 0;
12915 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
12916 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
12917 ok(valW[0], "expected > 0 got %u\n", valW[0]);
12918 ok(size == 11, "expected 11 got %u\n", size);
12919
12920 delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
12921 RegCloseKey(hkey_udproductpatch);
12922 delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
12923 RegCloseKey(hkey_udproductpatches);
12924 delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
12925 RegCloseKey(hkey_udpatch);
12926 delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
12927 RegCloseKey(hkey_udpatches);
12928 delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
12929 RegCloseKey(hkey_udprops);
12930 delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
12931 RegCloseKey(hkey_udproduct);
12932
12933 done:
12934 delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
12935 RegCloseKey(hkey_patches);
12936 delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
12937 RegCloseKey(hkey_product);
12938 delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
12939 RegCloseKey(hkey_patch);
12940 }
12941
12942 static void test_MsiEnumProducts(void)
12943 {
12944 UINT r;
12945 BOOL found1, found2, found3;
12946 DWORD index;
12947 char product1[39], product2[39], product3[39], guid[39];
12948 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
12949 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
12950 char *usersid;
12951 HKEY key1, key2, key3;
12952 REGSAM access = KEY_ALL_ACCESS;
12953
12954 create_test_guid(product1, product_squashed1);
12955 create_test_guid(product2, product_squashed2);
12956 create_test_guid(product3, product_squashed3);
12957 usersid = get_user_sid();
12958
12959 if (is_wow64)
12960 access |= KEY_WOW64_64KEY;
12961
12962 strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
12963 strcat(keypath2, usersid);
12964 strcat(keypath2, "\\Installer\\Products\\");
12965 strcat(keypath2, product_squashed2);
12966
12967 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
12968 if (r == ERROR_ACCESS_DENIED)
12969 {
12970 skip("Not enough rights to perform tests\n");
12971 LocalFree(usersid);
12972 return;
12973 }
12974 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12975
12976 strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
12977 strcat(keypath1, product_squashed1);
12978
12979 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
12980 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12981
12982 strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
12983 strcat(keypath3, product_squashed3);
12984
12985 r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
12986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12987
12988 index = 0;
12989 r = MsiEnumProductsA(index, guid);
12990 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12991
12992 r = MsiEnumProductsA(index, NULL);
12993 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12994
12995 index = 2;
12996 r = MsiEnumProductsA(index, guid);
12997 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12998
12999 index = 0;
13000 r = MsiEnumProductsA(index, guid);
13001 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13002
13003 found1 = found2 = found3 = FALSE;
13004 while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
13005 {
13006 if (!strcmp(product1, guid)) found1 = TRUE;
13007 if (!strcmp(product2, guid)) found2 = TRUE;
13008 if (!strcmp(product3, guid)) found3 = TRUE;
13009 index++;
13010 }
13011 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
13012 ok(found1, "product1 not found\n");
13013 ok(found2, "product2 not found\n");
13014 ok(found3, "product3 not found\n");
13015
13016 delete_key(key1, "", access & KEY_WOW64_64KEY);
13017 delete_key(key2, "", access & KEY_WOW64_64KEY);
13018 RegDeleteKeyA(key3, "");
13019 RegCloseKey(key1);
13020 RegCloseKey(key2);
13021 RegCloseKey(key3);
13022 LocalFree(usersid);
13023 }
13024
13025 static void test_MsiGetFileSignatureInformation(void)
13026 {
13027 HRESULT hr;
13028 const CERT_CONTEXT *cert;
13029 DWORD len;
13030
13031 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
13032 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13033
13034 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
13035 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13036
13037 hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
13038 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13039
13040 hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
13041 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13042
13043 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
13044 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13045
13046 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
13047 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13048
13049 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
13050 todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
13051
13052 create_file( "signature.bin", "signature", sizeof("signature") );
13053
13054 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
13055 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13056
13057 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
13058 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13059
13060 cert = (const CERT_CONTEXT *)0xdeadbeef;
13061 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
13062 todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
13063 ok(cert == NULL, "got %p\n", cert);
13064
13065 DeleteFileA( "signature.bin" );
13066 }
13067
13068 static void test_MsiEnumProductsEx(void)
13069 {
13070 UINT r;
13071 DWORD len, index;
13072 MSIINSTALLCONTEXT context;
13073 char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
13074 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
13075 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
13076 HKEY key1 = NULL, key2 = NULL, key3 = NULL;
13077 REGSAM access = KEY_ALL_ACCESS;
13078 char *usersid = get_user_sid();
13079
13080 if (!pMsiEnumProductsExA)
13081 {
13082 win_skip("MsiEnumProductsExA not implemented\n");
13083 return;
13084 }
13085
13086 create_test_guid( product0, NULL );
13087 create_test_guid( product1, product_squashed1 );
13088 create_test_guid( product2, product_squashed2 );
13089 create_test_guid( product3, product_squashed3 );
13090
13091 if (is_wow64) access |= KEY_WOW64_64KEY;
13092
13093 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
13094 strcat( keypath2, usersid );
13095 strcat( keypath2, "\\Installer\\Products\\" );
13096 strcat( keypath2, product_squashed2 );
13097
13098 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13099 if (r == ERROR_ACCESS_DENIED)
13100 {
13101 skip( "insufficient rights\n" );
13102 goto done;
13103 }
13104 ok( r == ERROR_SUCCESS, "got %u\n", r );
13105
13106 strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
13107 strcat( keypath1, product_squashed1 );
13108
13109 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13110 ok( r == ERROR_SUCCESS, "got %u\n", r );
13111
13112 strcpy( keypath3, usersid );
13113 strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
13114 strcat( keypath3, product_squashed3 );
13115
13116 r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
13117 ok( r == ERROR_SUCCESS, "got %u\n", r );
13118
13119 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
13120 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13121
13122 len = sizeof(sid);
13123 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
13124 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13125 ok( len == sizeof(sid), "got %u\n", len );
13126
13127 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
13128 ok( r == ERROR_SUCCESS, "got %u\n", r );
13129
13130 sid[0] = 0;
13131 len = sizeof(sid);
13132 r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
13133 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
13134 ok( len == sizeof(sid), "got %u\n", len );
13135 ok( !sid[0], "got %s\n", sid );
13136
13137 sid[0] = 0;
13138 len = sizeof(sid);
13139 r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
13140 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
13141 ok( len == sizeof(sid), "got %u\n", len );
13142 ok( !sid[0], "got %s\n", sid );
13143
13144 sid[0] = 0;
13145 len = 0;
13146 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
13147 ok( r == ERROR_MORE_DATA, "got %u\n", r );
13148 ok( len, "length unchanged\n" );
13149 ok( !sid[0], "got %s\n", sid );
13150
13151 guid[0] = 0;
13152 context = 0xdeadbeef;
13153 sid[0] = 0;
13154 len = sizeof(sid);
13155 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13156 ok( r == ERROR_SUCCESS, "got %u\n", r );
13157 ok( guid[0], "empty guid\n" );
13158 ok( context != 0xdeadbeef, "context unchanged\n" );
13159 ok( !len, "got %u\n", len );
13160 ok( !sid[0], "got %s\n", sid );
13161
13162 guid[0] = 0;
13163 context = 0xdeadbeef;
13164 sid[0] = 0;
13165 len = sizeof(sid);
13166 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13167 ok( r == ERROR_SUCCESS, "got %u\n", r );
13168 ok( guid[0], "empty guid\n" );
13169 ok( context != 0xdeadbeef, "context unchanged\n" );
13170 ok( !len, "got %u\n", len );
13171 ok( !sid[0], "got %s\n", sid );
13172
13173 guid[0] = 0;
13174 context = 0xdeadbeef;
13175 sid[0] = 0;
13176 len = sizeof(sid);
13177 r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13178 if (r == ERROR_ACCESS_DENIED)
13179 {
13180 skip( "insufficient rights\n" );
13181 goto done;
13182 }
13183 ok( r == ERROR_SUCCESS, "got %u\n", r );
13184 ok( guid[0], "empty guid\n" );
13185 ok( context != 0xdeadbeef, "context unchanged\n" );
13186 ok( !len, "got %u\n", len );
13187 ok( !sid[0], "got %s\n", sid );
13188
13189 index = 0;
13190 guid[0] = 0;
13191 context = 0xdeadbeef;
13192 sid[0] = 0;
13193 len = sizeof(sid);
13194 while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13195 {
13196 if (!strcmp( product1, guid ))
13197 {
13198 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13199 ok( !sid[0], "got \"%s\"\n", sid );
13200 ok( !len, "unexpected length %u\n", len );
13201 }
13202 if (!strcmp( product2, guid ))
13203 {
13204 ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
13205 ok( sid[0], "empty sid\n" );
13206 ok( len == strlen(sid), "unexpected length %u\n", len );
13207 }
13208 if (!strcmp( product3, guid ))
13209 {
13210 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13211 ok( sid[0], "empty sid\n" );
13212 ok( len == strlen(sid), "unexpected length %u\n", len );
13213 }
13214 index++;
13215 guid[0] = 0;
13216 context = 0xdeadbeef;
13217 sid[0] = 0;
13218 len = sizeof(sid);
13219 }
13220
13221 done:
13222 delete_key( key1, "", access );
13223 delete_key( key2, "", access );
13224 delete_key( key3, "", access );
13225 RegCloseKey( key1 );
13226 RegCloseKey( key2 );
13227 RegCloseKey( key3 );
13228 LocalFree( usersid );
13229 }
13230
13231 static void test_MsiEnumComponents(void)
13232 {
13233 UINT r;
13234 BOOL found1, found2;
13235 DWORD index;
13236 char comp1[39], comp2[39], guid[39];
13237 char comp_squashed1[33], comp_squashed2[33];
13238 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13239 REGSAM access = KEY_ALL_ACCESS;
13240 char *usersid = get_user_sid();
13241 HKEY key1 = NULL, key2 = NULL;
13242
13243 create_test_guid( comp1, comp_squashed1 );
13244 create_test_guid( comp2, comp_squashed2 );
13245
13246 if (is_wow64) access |= KEY_WOW64_64KEY;
13247
13248 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13249 strcat( keypath1, "S-1-5-18\\Components\\" );
13250 strcat( keypath1, comp_squashed1 );
13251
13252 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13253 if (r == ERROR_ACCESS_DENIED)
13254 {
13255 skip( "insufficient rights\n" );
13256 goto done;
13257 }
13258 ok( r == ERROR_SUCCESS, "got %u\n", r );
13259
13260 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13261 strcat( keypath2, usersid );
13262 strcat( keypath2, "\\Components\\" );
13263 strcat( keypath2, comp_squashed2 );
13264
13265 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13266 if (r == ERROR_ACCESS_DENIED)
13267 {
13268 skip( "insufficient rights\n" );
13269 goto done;
13270 }
13271
13272 r = MsiEnumComponentsA( 0, NULL );
13273 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13274
13275 index = 0;
13276 guid[0] = 0;
13277 found1 = found2 = FALSE;
13278 while (!MsiEnumComponentsA( index, guid ))
13279 {
13280 if (!strcmp( guid, comp1 )) found1 = TRUE;
13281 if (!strcmp( guid, comp2 )) found2 = TRUE;
13282 ok( guid[0], "empty guid\n" );
13283 guid[0] = 0;
13284 index++;
13285 }
13286 ok( found1, "comp1 not found\n" );
13287 ok( found2, "comp2 not found\n" );
13288
13289 done:
13290 delete_key( key1, "", access );
13291 delete_key( key2, "", access );
13292 RegCloseKey( key1 );
13293 RegCloseKey( key2 );
13294 LocalFree( usersid );
13295 }
13296
13297 static void test_MsiEnumComponentsEx(void)
13298 {
13299 UINT r;
13300 BOOL found1, found2;
13301 DWORD len, index;
13302 MSIINSTALLCONTEXT context;
13303 char comp1[39], comp2[39], guid[39], sid[128];
13304 char comp_squashed1[33], comp_squashed2[33];
13305 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13306 HKEY key1 = NULL, key2 = NULL;
13307 REGSAM access = KEY_ALL_ACCESS;
13308 char *usersid = get_user_sid();
13309
13310 if (!pMsiEnumComponentsExA)
13311 {
13312 win_skip( "MsiEnumComponentsExA not implemented\n" );
13313 return;
13314 }
13315 create_test_guid( comp1, comp_squashed1 );
13316 create_test_guid( comp2, comp_squashed2 );
13317
13318 if (is_wow64) access |= KEY_WOW64_64KEY;
13319
13320 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13321 strcat( keypath1, "S-1-5-18\\Components\\" );
13322 strcat( keypath1, comp_squashed1 );
13323
13324 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13325 if (r == ERROR_ACCESS_DENIED)
13326 {
13327 skip( "insufficient rights\n" );
13328 goto done;
13329 }
13330 ok( r == ERROR_SUCCESS, "got %u\n", r );
13331
13332 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13333 strcat( keypath2, usersid );
13334 strcat( keypath2, "\\Components\\" );
13335 strcat( keypath2, comp_squashed2 );
13336
13337 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13338 if (r == ERROR_ACCESS_DENIED)
13339 {
13340 skip( "insufficient rights\n" );
13341 goto done;
13342 }
13343 ok( r == ERROR_SUCCESS, "got %u\n", r );
13344 r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
13345 sizeof("c:\\doesnotexist"));
13346 ok( r == ERROR_SUCCESS, "got %u\n", r );
13347
13348 index = 0;
13349 guid[0] = 0;
13350 context = 0xdeadbeef;
13351 sid[0] = 0;
13352 len = sizeof(sid);
13353 found1 = found2 = FALSE;
13354 while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13355 {
13356 if (!strcmp( comp1, guid ))
13357 {
13358 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13359 ok( !sid[0], "got \"%s\"\n", sid );
13360 ok( !len, "unexpected length %u\n", len );
13361 found1 = TRUE;
13362 }
13363 if (!strcmp( comp2, guid ))
13364 {
13365 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13366 ok( sid[0], "empty sid\n" );
13367 ok( len == strlen(sid), "unexpected length %u\n", len );
13368 found2 = TRUE;
13369 }
13370 index++;
13371 guid[0] = 0;
13372 context = 0xdeadbeef;
13373 sid[0] = 0;
13374 len = sizeof(sid);
13375 }
13376 ok( found1, "comp1 not found\n" );
13377 ok( found2, "comp2 not found\n" );
13378
13379 r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
13380 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13381
13382 r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
13383 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13384
13385 done:
13386 RegDeleteValueA( key2, comp_squashed2 );
13387 delete_key( key1, "", access );
13388 delete_key( key2, "", access );
13389 RegCloseKey( key1 );
13390 RegCloseKey( key2 );
13391 LocalFree( usersid );
13392 }
13393
13394 static void test_MsiConfigureProductEx(void)
13395 {
13396 UINT r;
13397 LONG res;
13398 DWORD type, size;
13399 HKEY props, source;
13400 CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
13401 REGSAM access = KEY_ALL_ACCESS;
13402
13403 if (is_process_limited())
13404 {
13405 skip("process is limited\n");
13406 return;
13407 }
13408
13409 CreateDirectoryA("msitest", NULL);
13410 create_file("msitest\\hydrogen", "hydrogen", 500);
13411 create_file("msitest\\helium", "helium", 500);
13412 create_file("msitest\\lithium", "lithium", 500);
13413
13414 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13415
13416 if (is_wow64)
13417 access |= KEY_WOW64_64KEY;
13418
13419 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13420
13421 /* NULL szProduct */
13422 r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
13423 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13424 ok(r == ERROR_INVALID_PARAMETER,
13425 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13426
13427 /* empty szProduct */
13428 r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
13429 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13430 ok(r == ERROR_INVALID_PARAMETER,
13431 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13432
13433 /* garbage szProduct */
13434 r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
13435 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13436 ok(r == ERROR_INVALID_PARAMETER,
13437 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13438
13439 /* guid without brackets */
13440 r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
13441 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13442 "PROPVAR=42");
13443 ok(r == ERROR_INVALID_PARAMETER,
13444 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13445
13446 /* guid with brackets */
13447 r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
13448 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13449 "PROPVAR=42");
13450 ok(r == ERROR_UNKNOWN_PRODUCT,
13451 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13452
13453 /* same length as guid, but random */
13454 r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
13455 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13456 "PROPVAR=42");
13457 ok(r == ERROR_UNKNOWN_PRODUCT,
13458 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13459
13460 /* product not installed yet */
13461 r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
13462 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13463 "PROPVAR=42");
13464 ok(r == ERROR_UNKNOWN_PRODUCT,
13465 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13466
13467 /* install the product, per-user unmanaged */
13468 r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
13469 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13470 {
13471 skip("Not enough rights to perform tests\n");
13472 goto error;
13473 }
13474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13475 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13476 ok(pf_exists("msitest\\helium"), "File not installed\n");
13477 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13478 ok(pf_exists("msitest"), "File not installed\n");
13479
13480 /* product is installed per-user managed, remove it */
13481 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13482 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13483 "PROPVAR=42");
13484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13485 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13486 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13487 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13488 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13489
13490 /* product has been removed */
13491 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13492 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13493 "PROPVAR=42");
13494 ok(r == ERROR_UNKNOWN_PRODUCT,
13495 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13496
13497 /* install the product, machine */
13498 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13500 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13501 ok(pf_exists("msitest\\helium"), "File not installed\n");
13502 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13503 ok(pf_exists("msitest"), "File not installed\n");
13504
13505 /* product is installed machine, remove it */
13506 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13507 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13508 "PROPVAR=42");
13509 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13510 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13511 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13512 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13513 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13514
13515 /* product has been removed */
13516 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13517 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13518 "PROPVAR=42");
13519 ok(r == ERROR_UNKNOWN_PRODUCT,
13520 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13521
13522 /* install the product, machine */
13523 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13524 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13525 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13526 ok(pf_exists("msitest\\helium"), "File not installed\n");
13527 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13528 ok(pf_exists("msitest"), "File not installed\n");
13529
13530 DeleteFileA(msifile);
13531
13532 /* msifile is removed */
13533 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13534 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13535 "PROPVAR=42");
13536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13537 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13538 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13539 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13540 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13541
13542 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13543
13544 /* install the product, machine */
13545 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13547 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13548 ok(pf_exists("msitest\\helium"), "File not installed\n");
13549 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13550 ok(pf_exists("msitest"), "File not installed\n");
13551
13552 DeleteFileA(msifile);
13553
13554 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13555 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13556 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13557
13558 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
13559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13560
13561 type = REG_SZ;
13562 size = MAX_PATH;
13563 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13564 (LPBYTE)localpackage, &size);
13565 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13566
13567 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13568 (const BYTE *)"C:\\idontexist.msi", 18);
13569 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13570
13571 /* LocalPackage is used to find the cached msi package */
13572 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13573 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13574 "PROPVAR=42");
13575 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
13576 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13577 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13578 ok(pf_exists("msitest\\helium"), "File not installed\n");
13579 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13580 ok(pf_exists("msitest"), "File not installed\n");
13581
13582 RegCloseKey(props);
13583 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13584
13585 /* LastUsedSource can be used as a last resort */
13586 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13587 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13588 "PROPVAR=42");
13589 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13590 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13591 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13592 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13593 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13594 DeleteFileA( localpackage );
13595
13596 /* install the product, machine */
13597 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13598 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13599 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13600 ok(pf_exists("msitest\\helium"), "File not installed\n");
13601 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13602 ok(pf_exists("msitest"), "File not installed\n");
13603
13604 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13605 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13606 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13607
13608 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
13609 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13610
13611 type = REG_SZ;
13612 size = MAX_PATH;
13613 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13614 (LPBYTE)localpackage, &size);
13615 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13616
13617 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13618 (const BYTE *)"C:\\idontexist.msi", 18);
13619 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13620
13621 lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
13622 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\SourceList");
13623
13624 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source);
13625 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13626
13627 type = REG_SZ;
13628 size = MAX_PATH;
13629 res = RegQueryValueExA(source, "PackageName", NULL, &type,
13630 (LPBYTE)packagename, &size);
13631 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13632
13633 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13634 (const BYTE *)"idontexist.msi", 15);
13635 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13636
13637 /* SourceList is altered */
13638 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13639 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13640 "PROPVAR=42");
13641 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
13642 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13643 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13644 ok(pf_exists("msitest\\helium"), "File not installed\n");
13645 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13646 ok(pf_exists("msitest"), "File not installed\n");
13647
13648 /* restore PackageName */
13649 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13650 (const BYTE *)packagename, lstrlenA(packagename) + 1);
13651 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13652
13653 /* restore LocalPackage */
13654 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13655 (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
13656 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13657
13658 /* finally remove the product */
13659 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13660 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13661 "PROPVAR=42");
13662 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13663 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13664 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13665 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13666 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13667
13668 RegCloseKey(source);
13669 RegCloseKey(props);
13670
13671 error:
13672 DeleteFileA("msitest\\hydrogen");
13673 DeleteFileA("msitest\\helium");
13674 DeleteFileA("msitest\\lithium");
13675 RemoveDirectoryA("msitest");
13676 DeleteFileA(msifile);
13677 }
13678
13679 static void test_MsiSetFeatureAttributes(void)
13680 {
13681 UINT r;
13682 DWORD attrs;
13683 char path[MAX_PATH];
13684 MSIHANDLE package;
13685
13686 if (is_process_limited())
13687 {
13688 skip("process is limited\n");
13689 return;
13690 }
13691 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
13692
13693 strcpy( path, CURR_DIR );
13694 strcat( path, "\\" );
13695 strcat( path, msifile );
13696
13697 r = MsiOpenPackageA( path, &package );
13698 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13699 {
13700 skip("Not enough rights to perform tests\n");
13701 DeleteFileA( msifile );
13702 return;
13703 }
13704 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13705
13706 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13707 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r);
13708
13709 r = MsiDoActionA( package, "CostInitialize" );
13710 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13711
13712 r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13713 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
13714
13715 r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13716 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13717
13718 r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13719 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13720
13721 r = MsiSetFeatureAttributesA( package, "One", 0 );
13722 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13723
13724 attrs = 0xdeadbeef;
13725 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13726 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13727 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
13728 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
13729
13730 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13731 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13732
13733 attrs = 0;
13734 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13735 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13736 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
13737 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
13738
13739 r = MsiDoActionA( package, "FileCost" );
13740 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13741
13742 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE );
13743 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13744
13745 attrs = 0;
13746 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13747 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13748 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE,
13749 "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs);
13750
13751 r = MsiDoActionA( package, "CostFinalize" );
13752 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13753
13754 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13755 ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r);
13756
13757 MsiCloseHandle( package );
13758 DeleteFileA( msifile );
13759 }
13760
13761 static void test_MsiGetFeatureInfo(void)
13762 {
13763 UINT r;
13764 MSIHANDLE package;
13765 char title[32], help[32], path[MAX_PATH];
13766 DWORD attrs, title_len, help_len;
13767
13768 if (is_process_limited())
13769 {
13770 skip("process is limited\n");
13771 return;
13772 }
13773 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
13774
13775 strcpy( path, CURR_DIR );
13776 strcat( path, "\\" );
13777 strcat( path, msifile );
13778
13779 r = MsiOpenPackageA( path, &package );
13780 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13781 {
13782 skip("Not enough rights to perform tests\n");
13783 DeleteFileA( msifile );
13784 return;
13785 }
13786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13787
13788 r = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL );
13789 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13790
13791 r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
13792 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13793
13794 r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
13795 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13796
13797 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
13798 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13799
13800 r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
13801 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
13802
13803 title_len = help_len = 0;
13804 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
13805 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13806 ok(title_len == 3, "expected 3, got %u\n", title_len);
13807 ok(help_len == 3, "expected 3, got %u\n", help_len);
13808
13809 title[0] = help[0] = 0;
13810 title_len = help_len = 0;
13811 r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
13812 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
13813 ok(title_len == 3, "expected 3, got %u\n", title_len);
13814 ok(help_len == 3, "expected 3, got %u\n", help_len);
13815
13816 attrs = 0;
13817 title[0] = help[0] = 0;
13818 title_len = sizeof(title);
13819 help_len = sizeof(help);
13820 r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
13821 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13822 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
13823 ok(title_len == 3, "expected 3, got %u\n", title_len);
13824 ok(help_len == 3, "expected 3, got %u\n", help_len);
13825 ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
13826 ok(!strcmp(help, "One"), "expected \"One\", got \"%s\"\n", help);
13827
13828 attrs = 0;
13829 title[0] = help[0] = 0;
13830 title_len = sizeof(title);
13831 help_len = sizeof(help);
13832 r = MsiGetFeatureInfoA( package, "Two", &attrs, title, &title_len, help, &help_len );
13833 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13834 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
13835 ok(!title_len, "expected 0, got %u\n", title_len);
13836 ok(!help_len, "expected 0, got %u\n", help_len);
13837 ok(!title[0], "expected \"\", got \"%s\"\n", title);
13838 ok(!help[0], "expected \"\", got \"%s\"\n", help);
13839
13840 MsiCloseHandle( package );
13841 DeleteFileA( msifile );
13842 }
13843
13844 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
13845 {
13846 return IDOK;
13847 }
13848
13849 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
13850 {
13851 return IDOK;
13852 }
13853
13854 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
13855 {
13856 return IDOK;
13857 }
13858
13859 static void test_MsiSetExternalUI(void)
13860 {
13861 INSTALLUI_HANDLERA ret_a;
13862 INSTALLUI_HANDLERW ret_w;
13863 INSTALLUI_HANDLER_RECORD prev;
13864 UINT error;
13865
13866 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
13867 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13868
13869 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
13870 ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
13871
13872 /* Not present before Installer 3.1 */
13873 if (!pMsiSetExternalUIRecord) {
13874 win_skip("MsiSetExternalUIRecord is not available\n");
13875 return;
13876 }
13877
13878 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
13879 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13880 ok(prev == NULL, "expected NULL, got %p\n", prev);
13881
13882 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13883 error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
13884 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13885 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
13886
13887 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
13888 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13889
13890 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
13891 ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
13892
13893 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
13894 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13895
13896 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
13897 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13898
13899 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13900 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
13901 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13902 ok(prev == NULL, "expected NULL, got %p\n", prev);
13903
13904 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
13905 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13906
13907 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
13908 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13909
13910 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13911 error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
13912 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13913 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
13914
13915 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
13916 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13917
13918 error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
13919 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13920 }
13921
13922 static void test_lastusedsource(void)
13923 {
13924 static const char prodcode[] = "{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}";
13925 char value[MAX_PATH], path[MAX_PATH];
13926 DWORD size;
13927 UINT r;
13928
13929 if (!pMsiSourceListGetInfoA)
13930 {
13931 win_skip("MsiSourceListGetInfoA is not available\n");
13932 return;
13933 }
13934
13935 CreateDirectoryA("msitest", NULL);
13936 create_file("maximus", "maximus", 500);
13937 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
13938 DeleteFileA("maximus");
13939
13940 create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
13941 create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
13942 create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
13943
13944 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13945
13946 /* no cabinet file */
13947
13948 size = MAX_PATH;
13949 lstrcpyA(value, "aaa");
13950 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13951 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13952 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13953 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13954
13955 r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
13956 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13957 {
13958 skip("Not enough rights to perform tests\n");
13959 goto error;
13960 }
13961 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13962
13963 lstrcpyA(path, CURR_DIR);
13964 lstrcatA(path, "\\");
13965
13966 size = MAX_PATH;
13967 lstrcpyA(value, "aaa");
13968 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13969 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13970 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13971 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13972 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
13973
13974 r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
13975 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13976
13977 /* separate cabinet file */
13978
13979 size = MAX_PATH;
13980 lstrcpyA(value, "aaa");
13981 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13982 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13983 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13984 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13985
13986 r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
13987 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13988
13989 lstrcpyA(path, CURR_DIR);
13990 lstrcatA(path, "\\");
13991
13992 size = MAX_PATH;
13993 lstrcpyA(value, "aaa");
13994 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13995 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
13996 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13997 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13998 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
13999
14000 r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
14001 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14002
14003 size = MAX_PATH;
14004 lstrcpyA(value, "aaa");
14005 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14006 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14007 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14008 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14009
14010 /* embedded cabinet stream */
14011
14012 add_cabinet_storage("msifile2.msi", "test1.cab");
14013
14014 r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
14015 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14016
14017 size = MAX_PATH;
14018 lstrcpyA(value, "aaa");
14019 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14020 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14021 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14022 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14023 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
14024
14025 r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
14026 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14027
14028 size = MAX_PATH;
14029 lstrcpyA(value, "aaa");
14030 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14031 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14032 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14033 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14034
14035 error:
14036 delete_cab_files();
14037 DeleteFileA("msitest\\maximus");
14038 RemoveDirectoryA("msitest");
14039 DeleteFileA("msifile0.msi");
14040 DeleteFileA("msifile1.msi");
14041 DeleteFileA("msifile2.msi");
14042 }
14043
14044 static void test_setpropertyfolder(void)
14045 {
14046 UINT r;
14047 CHAR path[MAX_PATH];
14048 DWORD attr;
14049
14050 if (is_process_limited())
14051 {
14052 skip("process is limited\n");
14053 return;
14054 }
14055
14056 lstrcpyA(path, PROG_FILES_DIR);
14057 lstrcatA(path, "\\msitest\\added");
14058
14059 CreateDirectoryA("msitest", NULL);
14060 create_file("msitest\\maximus", "msitest\\maximus", 500);
14061
14062 create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
14063
14064 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14065
14066 r = MsiInstallProductA(msifile, NULL);
14067 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14068 {
14069 skip("Not enough rights to perform tests\n");
14070 goto error;
14071 }
14072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14073 attr = GetFileAttributesA(path);
14074 if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
14075 {
14076 ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
14077 ok(delete_pf("msitest\\added", FALSE), "Directory not created\n");
14078 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14079 }
14080 else
14081 {
14082 trace("changing folder property not supported\n");
14083 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14084 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14085 }
14086
14087 error:
14088 DeleteFileA(msifile);
14089 DeleteFileA("msitest\\maximus");
14090 RemoveDirectoryA("msitest");
14091 }
14092
14093 static void test_sourcedir_props(void)
14094 {
14095 UINT r;
14096
14097 if (is_process_limited())
14098 {
14099 skip("process is limited\n");
14100 return;
14101 }
14102
14103 create_test_files();
14104 create_file("msitest\\sourcedir.txt", "msitest\\sourcedir.txt", 1000);
14105 create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
14106
14107 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14108
14109 /* full UI, no ResolveSource action */
14110 r = MsiInstallProductA(msifile, NULL);
14111 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14112
14113 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14115
14116 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14117 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14118
14119 /* full UI, ResolveSource action */
14120 r = MsiInstallProductA(msifile, "ResolveSource=1");
14121 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14122
14123 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14124 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14125
14126 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14127 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14128
14129 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14130
14131 /* no UI, no ResolveSource action */
14132 r = MsiInstallProductA(msifile, NULL);
14133 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14134
14135 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14136 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14137
14138 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14139 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14140
14141 /* no UI, ResolveSource action */
14142 r = MsiInstallProductA(msifile, "ResolveSource=1");
14143 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14144
14145 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14146 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14147
14148 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14149 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14150
14151 DeleteFileA("msitest\\sourcedir.txt");
14152 delete_test_files();
14153 DeleteFileA(msifile);
14154 }
14155
14156 static void test_concurrentinstall(void)
14157 {
14158 UINT r;
14159 CHAR path[MAX_PATH];
14160
14161 if (is_process_limited())
14162 {
14163 skip("process is limited\n");
14164 return;
14165 }
14166
14167 CreateDirectoryA("msitest", NULL);
14168 CreateDirectoryA("msitest\\msitest", NULL);
14169 create_file("msitest\\maximus", "msitest\\maximus", 500);
14170 create_file("msitest\\msitest\\augustus", "msitest\\msitest\\augustus", 500);
14171
14172 create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
14173
14174 lstrcpyA(path, CURR_DIR);
14175 lstrcatA(path, "\\msitest\\concurrent.msi");
14176 create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
14177
14178 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14179
14180 r = MsiInstallProductA(msifile, NULL);
14181 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14182 {
14183 skip("Not enough rights to perform tests\n");
14184 DeleteFileA(path);
14185 goto error;
14186 }
14187 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14188 if (!delete_pf("msitest\\augustus", TRUE))
14189 trace("concurrent installs not supported\n");
14190 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14191 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14192
14193 r = MsiConfigureProductA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", INSTALLLEVEL_DEFAULT,
14194 INSTALLSTATE_ABSENT);
14195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14196
14197 DeleteFileA(path);
14198
14199 error:
14200 DeleteFileA(msifile);
14201 DeleteFileA("msitest\\msitest\\augustus");
14202 DeleteFileA("msitest\\maximus");
14203 RemoveDirectoryA("msitest\\msitest");
14204 RemoveDirectoryA("msitest");
14205 }
14206
14207 static void test_command_line_parsing(void)
14208 {
14209 UINT r;
14210 const char *cmd;
14211
14212 if (is_process_limited())
14213 {
14214 skip("process is limited\n");
14215 return;
14216 }
14217
14218 create_test_files();
14219 create_database(msifile, cl_tables, sizeof(cl_tables)/sizeof(msi_table));
14220
14221 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14222
14223 cmd = " ";
14224 r = MsiInstallProductA(msifile, cmd);
14225 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14226
14227 cmd = "=";
14228 r = MsiInstallProductA(msifile, cmd);
14229 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14230
14231 cmd = "==";
14232 r = MsiInstallProductA(msifile, cmd);
14233 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14234
14235 cmd = "one";
14236 r = MsiInstallProductA(msifile, cmd);
14237 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14238
14239 cmd = "=one";
14240 r = MsiInstallProductA(msifile, cmd);
14241 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14242
14243 cmd = "P=";
14244 r = MsiInstallProductA(msifile, cmd);
14245 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14246
14247 cmd = " P=";
14248 r = MsiInstallProductA(msifile, cmd);
14249 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14250
14251 cmd = "P= ";
14252 r = MsiInstallProductA(msifile, cmd);
14253 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14254
14255 cmd = "P=\"";
14256 r = MsiInstallProductA(msifile, cmd);
14257 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14258
14259 cmd = "P=\"\"";
14260 r = MsiInstallProductA(msifile, cmd);
14261 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14262
14263 cmd = "P=\"\"\"";
14264 r = MsiInstallProductA(msifile, cmd);
14265 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14266
14267 cmd = "P=\"\"\"\"";
14268 r = MsiInstallProductA(msifile, cmd);
14269 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14270
14271 cmd = "P=\" ";
14272 r = MsiInstallProductA(msifile, cmd);
14273 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14274
14275 cmd = "P= \"";
14276 r = MsiInstallProductA(msifile, cmd);
14277 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14278
14279 cmd = "P= \"\" ";
14280 r = MsiInstallProductA(msifile, cmd);
14281 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14282
14283 cmd = "P=\" \"";
14284 r = MsiInstallProductA(msifile, cmd);
14285 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14286
14287 cmd = "P=one";
14288 r = MsiInstallProductA(msifile, cmd);
14289 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14290
14291 cmd = "P= one";
14292 r = MsiInstallProductA(msifile, cmd);
14293 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14294
14295 cmd = "P=\"one";
14296 r = MsiInstallProductA(msifile, cmd);
14297 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14298
14299 cmd = "P=one\"";
14300 r = MsiInstallProductA(msifile, cmd);
14301 todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14302
14303 cmd = "P=\"one\"";
14304 r = MsiInstallProductA(msifile, cmd);
14305 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14306
14307 cmd = "P= \"one\" ";
14308 r = MsiInstallProductA(msifile, cmd);
14309 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14310
14311 cmd = "P=\"one\"\"";
14312 r = MsiInstallProductA(msifile, cmd);
14313 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14314
14315 cmd = "P=\"\"one\"";
14316 r = MsiInstallProductA(msifile, cmd);
14317 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14318
14319 cmd = "P=\"\"one\"\"";
14320 r = MsiInstallProductA(msifile, cmd);
14321 todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14322
14323 cmd = "P=\"one two\"";
14324 r = MsiInstallProductA(msifile, cmd);
14325 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14326
14327 cmd = "P=\"\"\"one\"\" two\"";
14328 r = MsiInstallProductA(msifile, cmd);
14329 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14330
14331 cmd = "P=\"\"\"one\"\" two\" Q=three";
14332 r = MsiInstallProductA(msifile, cmd);
14333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14334
14335 cmd = "P=\"\" Q=\"two\"";
14336 r = MsiInstallProductA(msifile, cmd);
14337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14338
14339 cmd = "P=\"one\" Q=\"two\"";
14340 r = MsiInstallProductA(msifile, cmd);
14341 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14342
14343 cmd = "P=\"one=two\"";
14344 r = MsiInstallProductA(msifile, cmd);
14345 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14346
14347 cmd = "Q=\"\" P=\"one\"";
14348 r = MsiInstallProductA(msifile, cmd);
14349 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14350
14351 cmd = "P=\"\"\"one\"\"\" Q=\"two\"";
14352 r = MsiInstallProductA(msifile, cmd);
14353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14354
14355 cmd = "P=\"one \"\"two\"\"\" Q=\"three\"";
14356 r = MsiInstallProductA(msifile, cmd);
14357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14358
14359 cmd = "P=\"\"\"one\"\" two\" Q=\"three\"";
14360 r = MsiInstallProductA(msifile, cmd);
14361 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14362
14363 DeleteFileA(msifile);
14364 delete_test_files();
14365 }
14366
14367 START_TEST(msi)
14368 {
14369 DWORD len;
14370 char temp_path[MAX_PATH], prev_path[MAX_PATH];
14371
14372 #ifdef __REACTOS__
14373 if (!winetest_interactive &&
14374 !strcmp(winetest_platform, "windows"))
14375 {
14376 skip("ROSTESTS-180: Skipping msi_winetest:msi because it hangs on WHS-Testbot. Set winetest_interactive to run it anyway.\n");
14377 return;
14378 }
14379 #endif
14380
14381 init_functionpointers();
14382
14383 if (pIsWow64Process)
14384 pIsWow64Process(GetCurrentProcess(), &is_wow64);
14385
14386 GetCurrentDirectoryA(MAX_PATH, prev_path);
14387 GetTempPathA(MAX_PATH, temp_path);
14388 SetCurrentDirectoryA(temp_path);
14389
14390 lstrcpyA(CURR_DIR, temp_path);
14391 len = lstrlenA(CURR_DIR);
14392
14393 if(len && (CURR_DIR[len - 1] == '\\'))
14394 CURR_DIR[len - 1] = 0;
14395
14396 ok(get_system_dirs(), "failed to retrieve system dirs\n");
14397
14398 test_usefeature();
14399 test_null();
14400 test_getcomponentpath();
14401 test_MsiGetFileHash();
14402
14403 if (!pConvertSidToStringSidA)
14404 win_skip("ConvertSidToStringSidA not implemented\n");
14405 else
14406 {
14407 /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
14408 test_MsiQueryProductState();
14409 test_MsiQueryFeatureState();
14410 test_MsiQueryComponentState();
14411 test_MsiGetComponentPath();
14412 test_MsiProvideComponent();
14413 test_MsiGetProductCode();
14414 test_MsiEnumClients();
14415 test_MsiGetProductInfo();
14416 test_MsiGetProductInfoEx();
14417 test_MsiGetUserInfo();
14418 test_MsiOpenProduct();
14419 test_MsiEnumPatchesEx();
14420 test_MsiEnumPatches();
14421 test_MsiGetPatchInfoEx();
14422 test_MsiGetPatchInfo();
14423 test_MsiEnumProducts();
14424 test_MsiEnumProductsEx();
14425 test_MsiEnumComponents();
14426 test_MsiEnumComponentsEx();
14427 }
14428 test_MsiGetFileVersion();
14429 test_MsiGetFileSignatureInformation();
14430 test_MsiConfigureProductEx();
14431 test_MsiSetFeatureAttributes();
14432 test_MsiGetFeatureInfo();
14433 test_MsiSetExternalUI();
14434 test_lastusedsource();
14435 test_setpropertyfolder();
14436 test_sourcedir_props();
14437 if (pMsiGetComponentPathExA)
14438 test_concurrentinstall();
14439 test_command_line_parsing();
14440
14441 SetCurrentDirectoryA(prev_path);
14442 }