Merge PR #283 "[USBPORT] Transaction Translator (TT) support bringup"
[reactos.git] / modules / 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 #include <shellapi.h>
32 #include <objidl.h>
33
34 #include "wine/test.h"
35
36 static BOOL is_wow64;
37 static const char msifile[] = "winetest.msi";
38 static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','.','m','s','i',0};
39 static char CURR_DIR[MAX_PATH];
40 static char PROG_FILES_DIR[MAX_PATH];
41 static char PROG_FILES_DIR_NATIVE[MAX_PATH];
42 static char COMMON_FILES_DIR[MAX_PATH];
43 static char WINDOWS_DIR[MAX_PATH];
44
45 static BOOL (WINAPI *pCheckTokenMembership)(HANDLE,PSID,PBOOL);
46 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
47 static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
48 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
49 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
50
51 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
52 (LPCSTR, LPCSTR, LPSTR, DWORD*);
53 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
54 (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
55 static INSTALLSTATE (WINAPI *pMsiProvideComponentA)
56 (LPCSTR, LPCSTR, LPCSTR, DWORD, LPSTR, LPDWORD);
57 static INSTALLSTATE (WINAPI *pMsiProvideComponentW)
58 (LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPWSTR, LPDWORD);
59 static UINT (WINAPI *pMsiGetFileHashA)
60 (LPCSTR, DWORD, PMSIFILEHASHINFO);
61 static UINT (WINAPI *pMsiGetProductInfoExA)
62 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
63 static UINT (WINAPI *pMsiOpenPackageExA)
64 (LPCSTR, DWORD, MSIHANDLE*);
65 static UINT (WINAPI *pMsiOpenPackageExW)
66 (LPCWSTR, DWORD, MSIHANDLE*);
67 static UINT (WINAPI *pMsiEnumPatchesExA)
68 (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
69 MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
70 static UINT (WINAPI *pMsiQueryComponentStateA)
71 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
72 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
73 (LPCSTR, LPCSTR ,DWORD, DWORD);
74 static UINT (WINAPI *pMsiGetPatchInfoExA)
75 (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
76 static UINT (WINAPI *pMsiEnumProductsExA)
77 (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
78 static UINT (WINAPI *pMsiEnumComponentsExA)
79 (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
80 static UINT (WINAPI *pMsiSetExternalUIRecord)
81 (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
82 static UINT (WINAPI *pMsiSourceListGetInfoA)
83 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
84
85 static void init_functionpointers(void)
86 {
87 HMODULE hmsi = GetModuleHandleA("msi.dll");
88 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
89 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
90
91 #define GET_PROC(dll, func) \
92 p ## func = (void *)GetProcAddress(dll, #func); \
93 if(!p ## func) \
94 trace("GetProcAddress(%s) failed\n", #func);
95
96 GET_PROC(hmsi, MsiGetComponentPathA)
97 GET_PROC(hmsi, MsiGetComponentPathExA);
98 GET_PROC(hmsi, MsiProvideComponentA)
99 GET_PROC(hmsi, MsiProvideComponentW)
100 GET_PROC(hmsi, MsiGetFileHashA)
101 GET_PROC(hmsi, MsiGetProductInfoExA)
102 GET_PROC(hmsi, MsiOpenPackageExA)
103 GET_PROC(hmsi, MsiOpenPackageExW)
104 GET_PROC(hmsi, MsiEnumPatchesExA)
105 GET_PROC(hmsi, MsiQueryComponentStateA)
106 GET_PROC(hmsi, MsiSetExternalUIRecord)
107 GET_PROC(hmsi, MsiUseFeatureExA)
108 GET_PROC(hmsi, MsiGetPatchInfoExA)
109 GET_PROC(hmsi, MsiEnumProductsExA)
110 GET_PROC(hmsi, MsiEnumComponentsExA)
111 GET_PROC(hmsi, MsiSourceListGetInfoA)
112
113 GET_PROC(hadvapi32, CheckTokenMembership);
114 GET_PROC(hadvapi32, ConvertSidToStringSidA)
115 GET_PROC(hadvapi32, OpenProcessToken);
116 GET_PROC(hadvapi32, RegDeleteKeyExA)
117 GET_PROC(hkernel32, IsWow64Process)
118
119 #undef GET_PROC
120 }
121
122 static BOOL get_system_dirs(void)
123 {
124 HKEY hkey;
125 DWORD type, size;
126
127 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
128 return FALSE;
129
130 size = MAX_PATH;
131 if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
132 RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
133 {
134 RegCloseKey(hkey);
135 return FALSE;
136 }
137 size = MAX_PATH;
138 if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
139 RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
140 {
141 RegCloseKey(hkey);
142 return FALSE;
143 }
144 size = MAX_PATH;
145 if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR_NATIVE, &size))
146 {
147 RegCloseKey(hkey);
148 return FALSE;
149 }
150 RegCloseKey(hkey);
151 if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH)) return FALSE;
152 return TRUE;
153 }
154
155 static BOOL file_exists(const char *file)
156 {
157 return GetFileAttributesA(file) != INVALID_FILE_ATTRIBUTES;
158 }
159
160 static BOOL pf_exists(const char *file)
161 {
162 char path[MAX_PATH];
163
164 lstrcpyA(path, PROG_FILES_DIR);
165 lstrcatA(path, "\\");
166 lstrcatA(path, file);
167 return file_exists(path);
168 }
169
170 static BOOL delete_pf(const char *rel_path, BOOL is_file)
171 {
172 char path[MAX_PATH];
173
174 lstrcpyA(path, PROG_FILES_DIR);
175 lstrcatA(path, "\\");
176 lstrcatA(path, rel_path);
177
178 if (is_file)
179 return DeleteFileA(path);
180 else
181 return RemoveDirectoryA(path);
182 }
183
184 static BOOL is_process_limited(void)
185 {
186 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
187 PSID Group = NULL;
188 BOOL IsInGroup;
189 HANDLE token;
190
191 if (!pCheckTokenMembership || !pOpenProcessToken) return FALSE;
192
193 if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
194 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
195 !pCheckTokenMembership(NULL, Group, &IsInGroup))
196 {
197 trace("Could not check if the current user is an administrator\n");
198 FreeSid(Group);
199 return FALSE;
200 }
201 FreeSid(Group);
202
203 if (!IsInGroup)
204 {
205 /* Only administrators have enough privileges for these tests */
206 return TRUE;
207 }
208
209 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
210 {
211 BOOL ret;
212 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
213 DWORD size;
214
215 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
216 CloseHandle(token);
217 return (ret && type == TokenElevationTypeLimited);
218 }
219 return FALSE;
220 }
221
222 /* cabinet definitions */
223
224 /* make the max size large so there is only one cab file */
225 #define MEDIA_SIZE 0x7FFFFFFF
226 #define FOLDER_THRESHOLD 900000
227
228 /* the FCI callbacks */
229
230 static void * CDECL mem_alloc(ULONG cb)
231 {
232 return HeapAlloc(GetProcessHeap(), 0, cb);
233 }
234
235 static void CDECL mem_free(void *memory)
236 {
237 HeapFree(GetProcessHeap(), 0, memory);
238 }
239
240 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
241 {
242 sprintf(pccab->szCab, pv, pccab->iCab);
243 return TRUE;
244 }
245
246 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
247 {
248 return 0;
249 }
250
251 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
252 BOOL fContinuation, void *pv)
253 {
254 return 0;
255 }
256
257 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
258 {
259 HANDLE handle;
260 DWORD dwAccess = 0;
261 DWORD dwShareMode = 0;
262 DWORD dwCreateDisposition = OPEN_EXISTING;
263
264 dwAccess = GENERIC_READ | GENERIC_WRITE;
265 /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
266 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
267
268 if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
269 dwCreateDisposition = OPEN_EXISTING;
270 else
271 dwCreateDisposition = CREATE_NEW;
272
273 handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
274 dwCreateDisposition, 0, NULL);
275
276 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
277
278 return (INT_PTR)handle;
279 }
280
281 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
282 {
283 HANDLE handle = (HANDLE)hf;
284 DWORD dwRead;
285 BOOL res;
286
287 res = ReadFile(handle, memory, cb, &dwRead, NULL);
288 ok(res, "Failed to ReadFile\n");
289
290 return dwRead;
291 }
292
293 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
294 {
295 HANDLE handle = (HANDLE)hf;
296 DWORD dwWritten;
297 BOOL res;
298
299 res = WriteFile(handle, memory, cb, &dwWritten, NULL);
300 ok(res, "Failed to WriteFile\n");
301
302 return dwWritten;
303 }
304
305 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
306 {
307 HANDLE handle = (HANDLE)hf;
308 ok(CloseHandle(handle), "Failed to CloseHandle\n");
309
310 return 0;
311 }
312
313 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
314 {
315 HANDLE handle = (HANDLE)hf;
316 DWORD ret;
317
318 ret = SetFilePointer(handle, dist, NULL, seektype);
319 ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
320
321 return ret;
322 }
323
324 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
325 {
326 BOOL ret = DeleteFileA(pszFile);
327 ok(ret, "Failed to DeleteFile %s\n", pszFile);
328
329 return 0;
330 }
331
332 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
333 {
334 LPSTR tempname;
335
336 tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
337 GetTempFileNameA(".", "xx", 0, tempname);
338
339 if (tempname && (strlen(tempname) < (unsigned)cbTempName))
340 {
341 lstrcpyA(pszTempName, tempname);
342 HeapFree(GetProcessHeap(), 0, tempname);
343 return TRUE;
344 }
345
346 HeapFree(GetProcessHeap(), 0, tempname);
347
348 return FALSE;
349 }
350
351 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
352 USHORT *pattribs, int *err, void *pv)
353 {
354 BY_HANDLE_FILE_INFORMATION finfo;
355 FILETIME filetime;
356 HANDLE handle;
357 DWORD attrs;
358 BOOL res;
359
360 handle = CreateFileA(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
361 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
362 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
363
364 res = GetFileInformationByHandle(handle, &finfo);
365 ok(res, "Expected GetFileInformationByHandle to succeed\n");
366
367 FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
368 FileTimeToDosDateTime(&filetime, pdate, ptime);
369
370 attrs = GetFileAttributesA(pszName);
371 ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
372
373 return (INT_PTR)handle;
374 }
375
376 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
377 {
378 char path[MAX_PATH];
379 char filename[MAX_PATH];
380
381 lstrcpyA(path, CURR_DIR);
382 lstrcatA(path, "\\");
383 lstrcatA(path, file);
384
385 lstrcpyA(filename, file);
386
387 return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
388 progress, get_open_info, compress);
389 }
390
391 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
392 {
393 ZeroMemory(pCabParams, sizeof(CCAB));
394
395 pCabParams->cb = max_size;
396 pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
397 pCabParams->setID = 0xbeef;
398 pCabParams->iCab = 1;
399 lstrcpyA(pCabParams->szCabPath, CURR_DIR);
400 lstrcatA(pCabParams->szCabPath, "\\");
401 lstrcpyA(pCabParams->szCab, name);
402 }
403
404 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
405 {
406 CCAB cabParams;
407 LPCSTR ptr;
408 HFCI hfci;
409 ERF erf;
410 BOOL res;
411
412 set_cab_parameters(&cabParams, name, max_size);
413
414 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
415 fci_read, fci_write, fci_close, fci_seek, fci_delete,
416 get_temp_file, &cabParams, NULL);
417
418 ok(hfci != NULL, "Failed to create an FCI context\n");
419
420 ptr = files;
421 while (*ptr)
422 {
423 res = add_file(hfci, ptr, tcompTYPE_MSZIP);
424 ok(res, "Failed to add file: %s\n", ptr);
425 ptr += lstrlenA(ptr) + 1;
426 }
427
428 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
429 ok(res, "Failed to flush the cabinet\n");
430
431 res = FCIDestroy(hfci);
432 ok(res, "Failed to destroy the cabinet\n");
433 }
434
435 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
436 {
437 WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
438 IStorage *stg;
439 IStream *stm;
440 HRESULT hr;
441 HANDLE handle;
442
443 MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
444 hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
445 if (FAILED(hr))
446 return FALSE;
447
448 MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
449 hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
450 if (FAILED(hr))
451 {
452 IStorage_Release(stg);
453 return FALSE;
454 }
455
456 handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
457 if (handle != INVALID_HANDLE_VALUE)
458 {
459 DWORD count;
460 char buffer[1024];
461 if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
462 IStream_Write(stm, buffer, count, &count);
463 CloseHandle(handle);
464 }
465
466 IStream_Release(stm);
467 IStorage_Release(stg);
468
469 return TRUE;
470 }
471
472 static void delete_cab_files(void)
473 {
474 SHFILEOPSTRUCTA shfl;
475 CHAR path[MAX_PATH+10];
476
477 lstrcpyA(path, CURR_DIR);
478 lstrcatA(path, "\\*.cab");
479 path[strlen(path) + 1] = '\0';
480
481 shfl.hwnd = NULL;
482 shfl.wFunc = FO_DELETE;
483 shfl.pFrom = path;
484 shfl.pTo = NULL;
485 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
486
487 SHFileOperationA(&shfl);
488 }
489
490 /* msi database data */
491
492 static const char directory_dat[] =
493 "Directory\tDirectory_Parent\tDefaultDir\n"
494 "s72\tS72\tl255\n"
495 "Directory\tDirectory\n"
496 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
497 "ProgramFilesFolder\tTARGETDIR\t.\n"
498 "TARGETDIR\t\tSourceDir";
499
500 static const char component_dat[] =
501 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
502 "s72\tS38\ts72\ti2\tS255\tS72\n"
503 "Component\tComponent\n"
504 "One\t{8F5BAEEF-DD92-40AC-9397-BE3CF9F97C81}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n";
505
506 static const char feature_dat[] =
507 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
508 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
509 "Feature\tFeature\n"
510 "One\t\tOne\tOne\t1\t3\tMSITESTDIR\t0\n"
511 "Two\t\t\t\t2\t1\tTARGETDIR\t0\n";
512
513 static const char feature_comp_dat[] =
514 "Feature_\tComponent_\n"
515 "s38\ts72\n"
516 "FeatureComponents\tFeature_\tComponent_\n"
517 "One\tOne\n";
518
519 static const char file_dat[] =
520 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
521 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
522 "File\tFile\n"
523 "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n";
524
525 static const char install_exec_seq_dat[] =
526 "Action\tCondition\tSequence\n"
527 "s72\tS255\tI2\n"
528 "InstallExecuteSequence\tAction\n"
529 "ValidateProductID\t\t700\n"
530 "CostInitialize\t\t800\n"
531 "FileCost\t\t900\n"
532 "CostFinalize\t\t1000\n"
533 "InstallValidate\t\t1400\n"
534 "InstallInitialize\t\t1500\n"
535 "ProcessComponents\t\t1600\n"
536 "UnpublishFeatures\t\t1800\n"
537 "RemoveFiles\t\t3500\n"
538 "InstallFiles\t\t4000\n"
539 "RegisterProduct\t\t6100\n"
540 "PublishFeatures\t\t6300\n"
541 "PublishProduct\t\t6400\n"
542 "InstallFinalize\t\t6600";
543
544 static const char media_dat[] =
545 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
546 "i2\ti4\tL64\tS255\tS32\tS72\n"
547 "Media\tDiskId\n"
548 "1\t1\t\t\tDISK1\t\n";
549
550 static const char property_dat[] =
551 "Property\tValue\n"
552 "s72\tl0\n"
553 "Property\tProperty\n"
554 "INSTALLLEVEL\t3\n"
555 "Manufacturer\tWine\n"
556 "ProductCode\t{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}\n"
557 "ProductName\tMSITEST\n"
558 "ProductVersion\t1.1.1\n"
559 "UpgradeCode\t{9574448F-9B86-4E07-B6F6-8D199DA12127}\n"
560 "MSIFASTINSTALL\t1\n";
561
562 static const char ci2_property_dat[] =
563 "Property\tValue\n"
564 "s72\tl0\n"
565 "Property\tProperty\n"
566 "INSTALLLEVEL\t3\n"
567 "Manufacturer\tWine\n"
568 "ProductCode\t{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}\n"
569 "ProductName\tMSITEST2\n"
570 "ProductVersion\t1.1.1\n"
571 "UpgradeCode\t{6B60C3CA-B8CA-4FB7-A395-092D98FF5D2A}\n"
572 "MSIFASTINSTALL\t1\n";
573
574 static const char mcp_component_dat[] =
575 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
576 "s72\tS38\ts72\ti2\tS255\tS72\n"
577 "Component\tComponent\n"
578 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
579 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
580 "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
581
582 static const char mcp_feature_dat[] =
583 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
584 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
585 "Feature\tFeature\n"
586 "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
587 "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
588 "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
589
590 static const char mcp_feature_comp_dat[] =
591 "Feature_\tComponent_\n"
592 "s38\ts72\n"
593 "FeatureComponents\tFeature_\tComponent_\n"
594 "hydroxyl\thydrogen\n"
595 "heliox\thelium\n"
596 "lithia\tlithium";
597
598 static const char mcp_file_dat[] =
599 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
600 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
601 "File\tFile\n"
602 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
603 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
604 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
605
606 static const char lus_component_dat[] =
607 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
608 "s72\tS38\ts72\ti2\tS255\tS72\n"
609 "Component\tComponent\n"
610 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
611
612 static const char lus_feature_dat[] =
613 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
614 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
615 "Feature\tFeature\n"
616 "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
617 "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
618
619 static const char lus_file_dat[] =
620 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
621 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
622 "File\tFile\n"
623 "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
624
625 static const char lus_feature_comp_dat[] =
626 "Feature_\tComponent_\n"
627 "s38\ts72\n"
628 "FeatureComponents\tFeature_\tComponent_\n"
629 "feature\tmaximus\n"
630 "montecristo\tmaximus";
631
632 static const char lus_install_exec_seq_dat[] =
633 "Action\tCondition\tSequence\n"
634 "s72\tS255\tI2\n"
635 "InstallExecuteSequence\tAction\n"
636 "ValidateProductID\t\t700\n"
637 "CostInitialize\t\t800\n"
638 "FileCost\t\t900\n"
639 "CostFinalize\t\t1000\n"
640 "InstallValidate\t\t1400\n"
641 "InstallInitialize\t\t1500\n"
642 "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
643 "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
644 "RemoveFiles\t\t3500\n"
645 "InstallFiles\t\t4000\n"
646 "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
647 "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
648 "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
649 "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
650 "InstallFinalize\t\t6600";
651
652 static const char lus0_media_dat[] =
653 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
654 "i2\ti4\tL64\tS255\tS32\tS72\n"
655 "Media\tDiskId\n"
656 "1\t1\t\t\tDISK1\t\n";
657
658 static const char lus1_media_dat[] =
659 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
660 "i2\ti4\tL64\tS255\tS32\tS72\n"
661 "Media\tDiskId\n"
662 "1\t1\t\ttest1.cab\tDISK1\t\n";
663
664 static const char lus2_media_dat[] =
665 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
666 "i2\ti4\tL64\tS255\tS32\tS72\n"
667 "Media\tDiskId\n"
668 "1\t1\t\t#test1.cab\tDISK1\t\n";
669
670 static const char spf_custom_action_dat[] =
671 "Action\tType\tSource\tTarget\tISComments\n"
672 "s72\ti2\tS64\tS0\tS255\n"
673 "CustomAction\tAction\n"
674 "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
675
676 static const char spf_install_exec_seq_dat[] =
677 "Action\tCondition\tSequence\n"
678 "s72\tS255\tI2\n"
679 "InstallExecuteSequence\tAction\n"
680 "CostFinalize\t\t1000\n"
681 "CostInitialize\t\t800\n"
682 "FileCost\t\t900\n"
683 "SetFolderProp\t\t950\n"
684 "InstallFiles\t\t4000\n"
685 "InstallServices\t\t5000\n"
686 "InstallFinalize\t\t6600\n"
687 "InstallInitialize\t\t1500\n"
688 "InstallValidate\t\t1400\n"
689 "LaunchConditions\t\t100";
690
691 static const char spf_install_ui_seq_dat[] =
692 "Action\tCondition\tSequence\n"
693 "s72\tS255\tI2\n"
694 "InstallUISequence\tAction\n"
695 "CostInitialize\t\t800\n"
696 "FileCost\t\t900\n"
697 "CostFinalize\t\t1000\n"
698 "ExecuteAction\t\t1100\n";
699
700 static const char sd_file_dat[] =
701 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
702 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
703 "File\tFile\n"
704 "sourcedir.txt\tsourcedir\tsourcedir.txt\t1000\t\t\t8192\t1\n";
705
706 static const char sd_feature_dat[] =
707 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
708 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
709 "Feature\tFeature\n"
710 "sourcedir\t\t\tsourcedir feature\t1\t2\tMSITESTDIR\t0\n";
711
712 static const char sd_feature_comp_dat[] =
713 "Feature_\tComponent_\n"
714 "s38\ts72\n"
715 "FeatureComponents\tFeature_\tComponent_\n"
716 "sourcedir\tsourcedir\n";
717
718 static const char sd_component_dat[] =
719 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
720 "s72\tS38\ts72\ti2\tS255\tS72\n"
721 "Component\tComponent\n"
722 "sourcedir\t{DD422F92-3ED8-49B5-A0B7-F266F98357DF}\tMSITESTDIR\t0\t\tsourcedir.txt\n";
723
724 static const char sd_install_ui_seq_dat[] =
725 "Action\tCondition\tSequence\n"
726 "s72\tS255\tI2\n"
727 "InstallUISequence\tAction\n"
728 "TestSourceDirProp1\tnot SourceDir and not SOURCEDIR and not Installed\t99\n"
729 "AppSearch\t\t100\n"
730 "TestSourceDirProp2\tnot SourceDir and not SOURCEDIR and not Installed\t101\n"
731 "LaunchConditions\tnot Installed \t110\n"
732 "TestSourceDirProp3\tnot SourceDir and not SOURCEDIR and not Installed\t111\n"
733 "FindRelatedProducts\t\t120\n"
734 "TestSourceDirProp4\tnot SourceDir and not SOURCEDIR and not Installed\t121\n"
735 "CCPSearch\t\t130\n"
736 "TestSourceDirProp5\tnot SourceDir and not SOURCEDIR and not Installed\t131\n"
737 "RMCCPSearch\t\t140\n"
738 "TestSourceDirProp6\tnot SourceDir and not SOURCEDIR and not Installed\t141\n"
739 "ValidateProductID\t\t150\n"
740 "TestSourceDirProp7\tnot SourceDir and not SOURCEDIR and not Installed\t151\n"
741 "CostInitialize\t\t800\n"
742 "TestSourceDirProp8\tnot SourceDir and not SOURCEDIR and not Installed\t801\n"
743 "FileCost\t\t900\n"
744 "TestSourceDirProp9\tnot SourceDir and not SOURCEDIR and not Installed\t901\n"
745 "IsolateComponents\t\t1000\n"
746 "TestSourceDirProp10\tnot SourceDir and not SOURCEDIR and not Installed\t1001\n"
747 "CostFinalize\t\t1100\n"
748 "TestSourceDirProp11\tnot SourceDir and not SOURCEDIR and not Installed\t1101\n"
749 "MigrateFeatureStates\t\t1200\n"
750 "TestSourceDirProp12\tnot SourceDir and not SOURCEDIR and not Installed\t1201\n"
751 "ExecuteAction\t\t1300\n"
752 "TestSourceDirProp13\tnot SourceDir and not SOURCEDIR and not Installed\t1301\n";
753
754 static const char sd_install_exec_seq_dat[] =
755 "Action\tCondition\tSequence\n"
756 "s72\tS255\tI2\n"
757 "InstallExecuteSequence\tAction\n"
758 "TestSourceDirProp14\tSourceDir and SOURCEDIR and not Installed\t99\n"
759 "LaunchConditions\t\t100\n"
760 "TestSourceDirProp15\tSourceDir and SOURCEDIR and not Installed\t101\n"
761 "ValidateProductID\t\t700\n"
762 "TestSourceDirProp16\tSourceDir and SOURCEDIR and not Installed\t701\n"
763 "CostInitialize\t\t800\n"
764 "TestSourceDirProp17\tSourceDir and SOURCEDIR and not Installed\t801\n"
765 "ResolveSource\tResolveSource and not Installed\t850\n"
766 "TestSourceDirProp18\tResolveSource and not SourceDir and not SOURCEDIR and not Installed\t851\n"
767 "TestSourceDirProp19\tnot ResolveSource and SourceDir and SOURCEDIR and not Installed\t852\n"
768 "FileCost\t\t900\n"
769 "TestSourceDirProp20\tSourceDir and SOURCEDIR and not Installed\t901\n"
770 "IsolateComponents\t\t1000\n"
771 "TestSourceDirProp21\tSourceDir and SOURCEDIR and not Installed\t1001\n"
772 "CostFinalize\t\t1100\n"
773 "TestSourceDirProp22\tSourceDir and SOURCEDIR and not Installed\t1101\n"
774 "MigrateFeatureStates\t\t1200\n"
775 "TestSourceDirProp23\tSourceDir and SOURCEDIR and not Installed\t1201\n"
776 "InstallValidate\t\t1400\n"
777 "TestSourceDirProp24\tSourceDir and SOURCEDIR and not Installed\t1401\n"
778 "InstallInitialize\t\t1500\n"
779 "TestSourceDirProp25\tSourceDir and SOURCEDIR and not Installed\t1501\n"
780 "ProcessComponents\t\t1600\n"
781 "TestSourceDirProp26\tnot SourceDir and not SOURCEDIR and not Installed\t1601\n"
782 "UnpublishFeatures\t\t1800\n"
783 "TestSourceDirProp27\tnot SourceDir and not SOURCEDIR and not Installed\t1801\n"
784 "RemoveFiles\t\t3500\n"
785 "TestSourceDirProp28\tnot SourceDir and not SOURCEDIR and not Installed\t3501\n"
786 "InstallFiles\t\t4000\n"
787 "TestSourceDirProp29\tnot SourceDir and not SOURCEDIR and not Installed\t4001\n"
788 "RegisterUser\t\t6000\n"
789 "TestSourceDirProp30\tnot SourceDir and not SOURCEDIR and not Installed\t6001\n"
790 "RegisterProduct\t\t6100\n"
791 "TestSourceDirProp31\tnot SourceDir and not SOURCEDIR and not Installed\t6101\n"
792 "PublishFeatures\t\t6300\n"
793 "TestSourceDirProp32\tnot SourceDir and not SOURCEDIR and not Installed\t6301\n"
794 "PublishProduct\t\t6400\n"
795 "TestSourceDirProp33\tnot SourceDir and not SOURCEDIR and not Installed\t6401\n"
796 "InstallExecute\t\t6500\n"
797 "TestSourceDirProp34\tnot SourceDir and not SOURCEDIR and not Installed\t6501\n"
798 "InstallFinalize\t\t6600\n"
799 "TestSourceDirProp35\tnot SourceDir and not SOURCEDIR and not Installed\t6601\n";
800
801 static const char sd_custom_action_dat[] =
802 "Action\tType\tSource\tTarget\tISComments\n"
803 "s72\ti2\tS64\tS0\tS255\n"
804 "CustomAction\tAction\n"
805 "TestSourceDirProp1\t19\t\tTest 1 failed\t\n"
806 "TestSourceDirProp2\t19\t\tTest 2 failed\t\n"
807 "TestSourceDirProp3\t19\t\tTest 3 failed\t\n"
808 "TestSourceDirProp4\t19\t\tTest 4 failed\t\n"
809 "TestSourceDirProp5\t19\t\tTest 5 failed\t\n"
810 "TestSourceDirProp6\t19\t\tTest 6 failed\t\n"
811 "TestSourceDirProp7\t19\t\tTest 7 failed\t\n"
812 "TestSourceDirProp8\t19\t\tTest 8 failed\t\n"
813 "TestSourceDirProp9\t19\t\tTest 9 failed\t\n"
814 "TestSourceDirProp10\t19\t\tTest 10 failed\t\n"
815 "TestSourceDirProp11\t19\t\tTest 11 failed\t\n"
816 "TestSourceDirProp12\t19\t\tTest 12 failed\t\n"
817 "TestSourceDirProp13\t19\t\tTest 13 failed\t\n"
818 "TestSourceDirProp14\t19\t\tTest 14 failed\t\n"
819 "TestSourceDirProp15\t19\t\tTest 15 failed\t\n"
820 "TestSourceDirProp16\t19\t\tTest 16 failed\t\n"
821 "TestSourceDirProp17\t19\t\tTest 17 failed\t\n"
822 "TestSourceDirProp18\t19\t\tTest 18 failed\t\n"
823 "TestSourceDirProp19\t19\t\tTest 19 failed\t\n"
824 "TestSourceDirProp20\t19\t\tTest 20 failed\t\n"
825 "TestSourceDirProp21\t19\t\tTest 21 failed\t\n"
826 "TestSourceDirProp22\t19\t\tTest 22 failed\t\n"
827 "TestSourceDirProp23\t19\t\tTest 23 failed\t\n"
828 "TestSourceDirProp24\t19\t\tTest 24 failed\t\n"
829 "TestSourceDirProp25\t19\t\tTest 25 failed\t\n"
830 "TestSourceDirProp26\t19\t\tTest 26 failed\t\n"
831 "TestSourceDirProp27\t19\t\tTest 27 failed\t\n"
832 "TestSourceDirProp28\t19\t\tTest 28 failed\t\n"
833 "TestSourceDirProp29\t19\t\tTest 29 failed\t\n"
834 "TestSourceDirProp30\t19\t\tTest 30 failed\t\n"
835 "TestSourceDirProp31\t19\t\tTest 31 failed\t\n"
836 "TestSourceDirProp32\t19\t\tTest 32 failed\t\n"
837 "TestSourceDirProp33\t19\t\tTest 33 failed\t\n"
838 "TestSourceDirProp34\t19\t\tTest 34 failed\t\n"
839 "TestSourceDirProp35\t19\t\tTest 35 failed\t\n";
840
841 static const char ci_install_exec_seq_dat[] =
842 "Action\tCondition\tSequence\n"
843 "s72\tS255\tI2\n"
844 "InstallExecuteSequence\tAction\n"
845 "CostInitialize\t\t800\n"
846 "FileCost\t\t900\n"
847 "CostFinalize\t\t1000\n"
848 "InstallValidate\t\t1400\n"
849 "InstallInitialize\t\t1500\n"
850 "RunInstall\tnot Installed\t1550\n"
851 "ProcessComponents\t\t1600\n"
852 "UnpublishFeatures\t\t1800\n"
853 "RemoveFiles\t\t3500\n"
854 "InstallFiles\t\t4000\n"
855 "RegisterProduct\t\t6100\n"
856 "PublishFeatures\t\t6300\n"
857 "PublishProduct\t\t6400\n"
858 "InstallFinalize\t\t6600\n";
859
860 static const char ci_custom_action_dat[] =
861 "Action\tType\tSource\tTarget\tISComments\n"
862 "s72\ti2\tS64\tS0\tS255\n"
863 "CustomAction\tAction\n"
864 "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
865
866 static const char ci_component_dat[] =
867 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
868 "s72\tS38\ts72\ti2\tS255\tS72\n"
869 "Component\tComponent\n"
870 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
871
872 static const char ci2_component_dat[] =
873 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
874 "s72\tS38\ts72\ti2\tS255\tS72\n"
875 "Component\tComponent\n"
876 "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
877
878 static const char ci2_feature_comp_dat[] =
879 "Feature_\tComponent_\n"
880 "s38\ts72\n"
881 "FeatureComponents\tFeature_\tComponent_\n"
882 "feature\taugustus";
883
884 static const char ci2_file_dat[] =
885 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
886 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
887 "File\tFile\n"
888 "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
889
890 static const char cl_custom_action_dat[] =
891 "Action\tType\tSource\tTarget\tISComments\n"
892 "s72\ti2\tS64\tS0\tS255\n"
893 "CustomAction\tAction\n"
894 "TestCommandlineProp\t19\t\tTest1\t\n";
895
896 static const char cl_install_exec_seq_dat[] =
897 "Action\tCondition\tSequence\n"
898 "s72\tS255\tI2\n"
899 "InstallExecuteSequence\tAction\n"
900 "LaunchConditions\t\t100\n"
901 "ValidateProductID\t\t700\n"
902 "CostInitialize\t\t800\n"
903 "FileCost\t\t900\n"
904 "CostFinalize\t\t1000\n"
905 "TestCommandlineProp\tP=\"one\"\t1100\n"
906 "InstallInitialize\t\t1500\n"
907 "ProcessComponents\t\t1600\n"
908 "InstallValidate\t\t1400\n"
909 "InstallFinalize\t\t5000\n";
910
911 typedef struct _msi_table
912 {
913 const CHAR *filename;
914 const CHAR *data;
915 int size;
916 } msi_table;
917
918 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
919
920 static const msi_table tables[] =
921 {
922 ADD_TABLE(directory),
923 ADD_TABLE(component),
924 ADD_TABLE(feature),
925 ADD_TABLE(feature_comp),
926 ADD_TABLE(file),
927 ADD_TABLE(install_exec_seq),
928 ADD_TABLE(media),
929 ADD_TABLE(property),
930 };
931
932 static const msi_table mcp_tables[] =
933 {
934 ADD_TABLE(directory),
935 ADD_TABLE(mcp_component),
936 ADD_TABLE(mcp_feature),
937 ADD_TABLE(mcp_feature_comp),
938 ADD_TABLE(mcp_file),
939 ADD_TABLE(install_exec_seq),
940 ADD_TABLE(media),
941 ADD_TABLE(property)
942 };
943
944 static const msi_table lus0_tables[] =
945 {
946 ADD_TABLE(lus_component),
947 ADD_TABLE(directory),
948 ADD_TABLE(lus_feature),
949 ADD_TABLE(lus_feature_comp),
950 ADD_TABLE(lus_file),
951 ADD_TABLE(lus_install_exec_seq),
952 ADD_TABLE(lus0_media),
953 ADD_TABLE(property)
954 };
955
956 static const msi_table lus1_tables[] =
957 {
958 ADD_TABLE(lus_component),
959 ADD_TABLE(directory),
960 ADD_TABLE(lus_feature),
961 ADD_TABLE(lus_feature_comp),
962 ADD_TABLE(lus_file),
963 ADD_TABLE(lus_install_exec_seq),
964 ADD_TABLE(lus1_media),
965 ADD_TABLE(property)
966 };
967
968 static const msi_table lus2_tables[] =
969 {
970 ADD_TABLE(lus_component),
971 ADD_TABLE(directory),
972 ADD_TABLE(lus_feature),
973 ADD_TABLE(lus_feature_comp),
974 ADD_TABLE(lus_file),
975 ADD_TABLE(lus_install_exec_seq),
976 ADD_TABLE(lus2_media),
977 ADD_TABLE(property)
978 };
979
980 static const msi_table spf_tables[] =
981 {
982 ADD_TABLE(lus_component),
983 ADD_TABLE(directory),
984 ADD_TABLE(lus_feature),
985 ADD_TABLE(lus_feature_comp),
986 ADD_TABLE(lus_file),
987 ADD_TABLE(lus0_media),
988 ADD_TABLE(property),
989 ADD_TABLE(spf_custom_action),
990 ADD_TABLE(spf_install_exec_seq),
991 ADD_TABLE(spf_install_ui_seq)
992 };
993
994 static const msi_table sd_tables[] =
995 {
996 ADD_TABLE(directory),
997 ADD_TABLE(sd_component),
998 ADD_TABLE(sd_feature),
999 ADD_TABLE(sd_feature_comp),
1000 ADD_TABLE(sd_file),
1001 ADD_TABLE(sd_install_exec_seq),
1002 ADD_TABLE(sd_install_ui_seq),
1003 ADD_TABLE(sd_custom_action),
1004 ADD_TABLE(media),
1005 ADD_TABLE(property)
1006 };
1007
1008 static const msi_table ci_tables[] =
1009 {
1010 ADD_TABLE(ci_component),
1011 ADD_TABLE(directory),
1012 ADD_TABLE(lus_feature),
1013 ADD_TABLE(lus_feature_comp),
1014 ADD_TABLE(lus_file),
1015 ADD_TABLE(ci_install_exec_seq),
1016 ADD_TABLE(lus0_media),
1017 ADD_TABLE(property),
1018 ADD_TABLE(ci_custom_action),
1019 };
1020
1021 static const msi_table ci2_tables[] =
1022 {
1023 ADD_TABLE(ci2_component),
1024 ADD_TABLE(directory),
1025 ADD_TABLE(lus_feature),
1026 ADD_TABLE(ci2_feature_comp),
1027 ADD_TABLE(ci2_file),
1028 ADD_TABLE(install_exec_seq),
1029 ADD_TABLE(lus0_media),
1030 ADD_TABLE(ci2_property),
1031 };
1032
1033 static const msi_table cl_tables[] =
1034 {
1035 ADD_TABLE(component),
1036 ADD_TABLE(directory),
1037 ADD_TABLE(feature),
1038 ADD_TABLE(feature_comp),
1039 ADD_TABLE(file),
1040 ADD_TABLE(cl_custom_action),
1041 ADD_TABLE(cl_install_exec_seq),
1042 ADD_TABLE(media),
1043 ADD_TABLE(property)
1044 };
1045
1046 static void write_file(const CHAR *filename, const char *data, int data_size)
1047 {
1048 DWORD size;
1049
1050 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
1051 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1052 WriteFile(hf, data, data_size, &size, NULL);
1053 CloseHandle(hf);
1054 }
1055
1056 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
1057 {
1058 MSIHANDLE summary;
1059 UINT r;
1060
1061 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1062 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1063
1064 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
1065 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1066
1067 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1068 "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
1069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1070
1071 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
1072 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1073
1074 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
1075 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1076
1077 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1078 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1079
1080 /* write the summary changes back to the stream */
1081 r = MsiSummaryInfoPersist(summary);
1082 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1083
1084 MsiCloseHandle(summary);
1085 }
1086
1087 #define create_database(name, tables, num_tables) \
1088 create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
1089
1090 #define create_database_template(name, tables, num_tables, version, template) \
1091 create_database_wordcount(name, tables, num_tables, version, 0, template);
1092
1093 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
1094 int num_tables, INT version, INT wordcount,
1095 const char *template)
1096 {
1097 MSIHANDLE db;
1098 UINT r;
1099 WCHAR *nameW;
1100 int j, len;
1101
1102 len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
1103 if (!(nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return;
1104 MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
1105
1106 r = MsiOpenDatabaseW(nameW, MSIDBOPEN_CREATE, &db);
1107 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1108
1109 /* import the tables into the database */
1110 for (j = 0; j < num_tables; j++)
1111 {
1112 const msi_table *table = &tables[j];
1113
1114 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1115
1116 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1117 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1118
1119 DeleteFileA(table->filename);
1120 }
1121
1122 write_msi_summary_info(db, version, wordcount, template);
1123
1124 r = MsiDatabaseCommit(db);
1125 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1126
1127 MsiCloseHandle(db);
1128 HeapFree( GetProcessHeap(), 0, nameW );
1129 }
1130
1131 static UINT run_query(MSIHANDLE hdb, const char *query)
1132 {
1133 MSIHANDLE hview = 0;
1134 UINT r;
1135
1136 r = MsiDatabaseOpenViewA(hdb, query, &hview);
1137 if (r != ERROR_SUCCESS)
1138 return r;
1139
1140 r = MsiViewExecute(hview, 0);
1141 if (r == ERROR_SUCCESS)
1142 r = MsiViewClose(hview);
1143 MsiCloseHandle(hview);
1144 return r;
1145 }
1146
1147 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
1148 {
1149 UINT res;
1150 MSIHANDLE suminfo;
1151
1152 /* build summary info */
1153 res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo);
1154 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
1155
1156 res = MsiSummaryInfoSetPropertyA(suminfo, 2, VT_LPSTR, 0, NULL,
1157 "Installation Database");
1158 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1159
1160 res = MsiSummaryInfoSetPropertyA(suminfo, 3, VT_LPSTR, 0, NULL,
1161 "Installation Database");
1162 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1163
1164 res = MsiSummaryInfoSetPropertyA(suminfo, 4, VT_LPSTR, 0, NULL,
1165 "Wine Hackers");
1166 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1167
1168 res = MsiSummaryInfoSetPropertyA(suminfo, 7, VT_LPSTR, 0, NULL,
1169 ";1033");
1170 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1171
1172 res = MsiSummaryInfoSetPropertyA(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1173 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
1174 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1175
1176 res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL);
1177 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1178
1179 res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL);
1180 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1181
1182 res = MsiSummaryInfoPersist(suminfo);
1183 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
1184
1185 res = MsiCloseHandle(suminfo);
1186 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
1187
1188 return res;
1189 }
1190
1191 static MSIHANDLE create_package_db(LPSTR prodcode)
1192 {
1193 MSIHANDLE hdb = 0;
1194 CHAR query[MAX_PATH];
1195 UINT res;
1196
1197 DeleteFileA(msifile);
1198
1199 /* create an empty database */
1200 res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb);
1201 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1202 if (res != ERROR_SUCCESS)
1203 return hdb;
1204
1205 res = MsiDatabaseCommit(hdb);
1206 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1207
1208 set_summary_info(hdb, prodcode);
1209
1210 res = run_query(hdb,
1211 "CREATE TABLE `Directory` ( "
1212 "`Directory` CHAR(255) NOT NULL, "
1213 "`Directory_Parent` CHAR(255), "
1214 "`DefaultDir` CHAR(255) NOT NULL "
1215 "PRIMARY KEY `Directory`)");
1216 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1217
1218 res = run_query(hdb,
1219 "CREATE TABLE `Property` ( "
1220 "`Property` CHAR(72) NOT NULL, "
1221 "`Value` CHAR(255) "
1222 "PRIMARY KEY `Property`)");
1223 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1224
1225 sprintf(query, "INSERT INTO `Property` "
1226 "(`Property`, `Value`) "
1227 "VALUES( 'ProductCode', '%s' )", prodcode);
1228 res = run_query(hdb, query);
1229 ok(res == ERROR_SUCCESS , "Failed\n");
1230
1231 res = MsiDatabaseCommit(hdb);
1232 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1233
1234 return hdb;
1235 }
1236
1237 static void test_usefeature(void)
1238 {
1239 INSTALLSTATE r;
1240
1241 if (!pMsiUseFeatureExA)
1242 {
1243 win_skip("MsiUseFeatureExA not implemented\n");
1244 return;
1245 }
1246
1247 r = MsiQueryFeatureStateA(NULL, NULL);
1248 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1249
1250 r = MsiQueryFeatureStateA("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
1251 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1252
1253 r = pMsiUseFeatureExA(NULL,NULL,0,0);
1254 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1255
1256 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
1257 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1258
1259 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1260 NULL, -2, 0 );
1261 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1262
1263 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
1264 "WORDVIEWFiles", -2, 0 );
1265 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1266
1267 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
1268 "WORDVIEWFiles", -2, 0 );
1269 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1270
1271 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1272 "WORDVIEWFiles", -2, 1 );
1273 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1274 }
1275
1276 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
1277 {
1278 if (pRegDeleteKeyExA)
1279 return pRegDeleteKeyExA( key, subkey, access, 0 );
1280 return RegDeleteKeyA( key, subkey );
1281 }
1282
1283 static void test_null(void)
1284 {
1285 MSIHANDLE hpkg;
1286 UINT r;
1287 HKEY hkey;
1288 DWORD dwType, cbData;
1289 LPBYTE lpData = NULL;
1290 INSTALLSTATE state;
1291 REGSAM access = KEY_ALL_ACCESS;
1292
1293 if (is_wow64)
1294 access |= KEY_WOW64_64KEY;
1295
1296 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
1297 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1298
1299 state = MsiQueryProductStateW(NULL);
1300 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
1301
1302 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
1303 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1304
1305 r = MsiConfigureFeatureW(NULL, NULL, 0);
1306 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1307
1308 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
1309 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1310
1311 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
1312 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1313
1314 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
1315 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
1316
1317 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
1318 * necessary registry values */
1319
1320 /* empty product string */
1321 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
1322 if (r == ERROR_ACCESS_DENIED)
1323 {
1324 skip("Not enough rights to perform tests\n");
1325 return;
1326 }
1327 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1328
1329 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1330 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
1331 if ( r == ERROR_SUCCESS )
1332 {
1333 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
1334 if (!lpData)
1335 skip("Out of memory\n");
1336 else
1337 {
1338 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1339 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1340 }
1341 }
1342
1343 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1344 if (r == ERROR_ACCESS_DENIED)
1345 {
1346 skip("Not enough rights to perform tests\n");
1347 HeapFree(GetProcessHeap(), 0, lpData);
1348 RegCloseKey(hkey);
1349 return;
1350 }
1351 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1352
1353 r = MsiGetProductInfoA("", "", NULL, NULL);
1354 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1355
1356 if (lpData)
1357 {
1358 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
1359 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1360
1361 HeapFree(GetProcessHeap(), 0, lpData);
1362 }
1363 else
1364 {
1365 r = RegDeleteValueA(hkey, NULL);
1366 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1367 }
1368
1369 r = RegCloseKey(hkey);
1370 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1371
1372 /* empty attribute */
1373 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1374 0, NULL, 0, access, NULL, &hkey, NULL);
1375 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1376
1377 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1378 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1379
1380 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
1381 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
1382
1383 r = RegCloseKey(hkey);
1384 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1385
1386 r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1387 access & KEY_WOW64_64KEY);
1388 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1389 }
1390
1391 static void test_getcomponentpath(void)
1392 {
1393 INSTALLSTATE r;
1394 char buffer[0x100];
1395 DWORD sz;
1396
1397 if(!pMsiGetComponentPathA)
1398 return;
1399
1400 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
1401 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1402
1403 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
1404 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1405
1406 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
1407 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1408
1409 sz = sizeof buffer;
1410 buffer[0]=0;
1411 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
1412 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1413
1414 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
1415 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
1416 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1417
1418 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1419 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
1420 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1421
1422 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1423 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
1424 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1425
1426 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
1427 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
1428 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1429 }
1430
1431 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
1432 {
1433 HANDLE file;
1434 DWORD written;
1435
1436 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1437 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1438 WriteFile(file, data, strlen(data), &written, NULL);
1439
1440 if (size)
1441 {
1442 SetFilePointer(file, size, NULL, FILE_BEGIN);
1443 SetEndOfFile(file);
1444 }
1445
1446 CloseHandle(file);
1447 }
1448
1449 static void create_test_files(void)
1450 {
1451 CreateDirectoryA("msitest", NULL);
1452 create_file("msitest\\one.txt", "msitest\\one.txt", 100);
1453 CreateDirectoryA("msitest\\first", NULL);
1454 create_file("msitest\\first\\two.txt", "msitest\\first\\two.txt", 100);
1455 CreateDirectoryA("msitest\\second", NULL);
1456 create_file("msitest\\second\\three.txt", "msitest\\second\\three.txt", 100);
1457
1458 create_file("four.txt", "four.txt", 100);
1459 create_file("five.txt", "five.txt", 100);
1460 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1461
1462 create_file("msitest\\filename", "msitest\\filename", 100);
1463 create_file("msitest\\service.exe", "msitest\\service.exe", 100);
1464
1465 DeleteFileA("four.txt");
1466 DeleteFileA("five.txt");
1467 }
1468
1469 static void delete_test_files(void)
1470 {
1471 DeleteFileA("msitest.msi");
1472 DeleteFileA("msitest.cab");
1473 DeleteFileA("msitest\\second\\three.txt");
1474 DeleteFileA("msitest\\first\\two.txt");
1475 DeleteFileA("msitest\\one.txt");
1476 DeleteFileA("msitest\\service.exe");
1477 DeleteFileA("msitest\\filename");
1478 RemoveDirectoryA("msitest\\second");
1479 RemoveDirectoryA("msitest\\first");
1480 RemoveDirectoryA("msitest");
1481 }
1482
1483 #define HASHSIZE sizeof(MSIFILEHASHINFO)
1484
1485 static const struct
1486 {
1487 LPCSTR data;
1488 DWORD size;
1489 MSIFILEHASHINFO hash;
1490 } hash_data[] =
1491 {
1492 { "", 0,
1493 { HASHSIZE,
1494 { 0, 0, 0, 0 },
1495 },
1496 },
1497
1498 { "abc", 0,
1499 { HASHSIZE,
1500 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
1501 },
1502 },
1503
1504 { "C:\\Program Files\\msitest\\caesar\n", 0,
1505 { HASHSIZE,
1506 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
1507 },
1508 },
1509
1510 { "C:\\Program Files\\msitest\\caesar\n", 500,
1511 { HASHSIZE,
1512 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
1513 },
1514 },
1515 };
1516
1517 static void test_MsiGetFileHash(void)
1518 {
1519 const char name[] = "msitest.bin";
1520 UINT r;
1521 MSIFILEHASHINFO hash;
1522 DWORD i;
1523
1524 if (!pMsiGetFileHashA)
1525 {
1526 win_skip("MsiGetFileHash not implemented\n");
1527 return;
1528 }
1529
1530 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1531
1532 /* szFilePath is NULL */
1533 r = pMsiGetFileHashA(NULL, 0, &hash);
1534 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1535
1536 /* szFilePath is empty */
1537 r = pMsiGetFileHashA("", 0, &hash);
1538 ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
1539 "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
1540
1541 /* szFilePath is nonexistent */
1542 r = pMsiGetFileHashA(name, 0, &hash);
1543 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
1544
1545 /* dwOptions is non-zero */
1546 r = pMsiGetFileHashA(name, 1, &hash);
1547 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1548
1549 /* pHash.dwFileHashInfoSize is not correct */
1550 hash.dwFileHashInfoSize = 0;
1551 r = pMsiGetFileHashA(name, 0, &hash);
1552 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1553
1554 /* pHash is NULL */
1555 r = pMsiGetFileHashA(name, 0, NULL);
1556 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1557
1558 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
1559 {
1560 int ret;
1561
1562 create_file(name, hash_data[i].data, hash_data[i].size);
1563
1564 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
1565 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1566
1567 r = pMsiGetFileHashA(name, 0, &hash);
1568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1569
1570 ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
1571 ok(!ret, "Hash incorrect\n");
1572
1573 DeleteFileA(name);
1574 }
1575 }
1576
1577 /* copied from dlls/msi/registry.c */
1578 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
1579 {
1580 DWORD i,n=1;
1581 GUID guid;
1582
1583 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
1584 return FALSE;
1585
1586 for(i=0; i<8; i++)
1587 out[7-i] = in[n++];
1588 n++;
1589 for(i=0; i<4; i++)
1590 out[11-i] = in[n++];
1591 n++;
1592 for(i=0; i<4; i++)
1593 out[15-i] = in[n++];
1594 n++;
1595 for(i=0; i<2; i++)
1596 {
1597 out[17+i*2] = in[n++];
1598 out[16+i*2] = in[n++];
1599 }
1600 n++;
1601 for( ; i<8; i++)
1602 {
1603 out[17+i*2] = in[n++];
1604 out[16+i*2] = in[n++];
1605 }
1606 out[32]=0;
1607 return TRUE;
1608 }
1609
1610 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
1611 {
1612 WCHAR guidW[MAX_PATH];
1613 WCHAR squashedW[MAX_PATH];
1614 GUID guid;
1615 HRESULT hr;
1616 int size;
1617
1618 hr = CoCreateGuid(&guid);
1619 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1620
1621 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1622 ok(size == 39, "Expected 39, got %d\n", hr);
1623
1624 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
1625 if (squashed)
1626 {
1627 squash_guid(guidW, squashedW);
1628 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1629 }
1630 }
1631
1632 static char *get_user_sid(void)
1633 {
1634 HANDLE token;
1635 DWORD size = 0;
1636 TOKEN_USER *user;
1637 char *usersid = NULL;
1638
1639 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1640 GetTokenInformation(token, TokenUser, NULL, size, &size);
1641
1642 user = HeapAlloc(GetProcessHeap(), 0, size);
1643 GetTokenInformation(token, TokenUser, user, size, &size);
1644 pConvertSidToStringSidA(user->User.Sid, &usersid);
1645 HeapFree(GetProcessHeap(), 0, user);
1646
1647 CloseHandle(token);
1648 return usersid;
1649 }
1650
1651 static void test_MsiQueryProductState(void)
1652 {
1653 CHAR prodcode[MAX_PATH];
1654 CHAR prod_squashed[MAX_PATH];
1655 CHAR keypath[MAX_PATH*2];
1656 LPSTR usersid;
1657 INSTALLSTATE state;
1658 LONG res;
1659 HKEY userkey, localkey, props;
1660 HKEY prodkey;
1661 DWORD data, error;
1662 REGSAM access = KEY_ALL_ACCESS;
1663
1664 create_test_guid(prodcode, prod_squashed);
1665 usersid = get_user_sid();
1666
1667 if (is_wow64)
1668 access |= KEY_WOW64_64KEY;
1669
1670 /* NULL prodcode */
1671 SetLastError(0xdeadbeef);
1672 state = MsiQueryProductStateA(NULL);
1673 error = GetLastError();
1674 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1675 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1676
1677 /* empty prodcode */
1678 SetLastError(0xdeadbeef);
1679 state = MsiQueryProductStateA("");
1680 error = GetLastError();
1681 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1682 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1683
1684 /* garbage prodcode */
1685 SetLastError(0xdeadbeef);
1686 state = MsiQueryProductStateA("garbage");
1687 error = GetLastError();
1688 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1689 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1690
1691 /* guid without brackets */
1692 SetLastError(0xdeadbeef);
1693 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
1694 error = GetLastError();
1695 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1696 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1697
1698 /* guid with brackets */
1699 SetLastError(0xdeadbeef);
1700 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
1701 error = GetLastError();
1702 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1703 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1704 "expected ERROR_SUCCESS, got %u\n", error);
1705
1706 /* same length as guid, but random */
1707 SetLastError(0xdeadbeef);
1708 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
1709 error = GetLastError();
1710 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1711 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1712
1713 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1714
1715 SetLastError(0xdeadbeef);
1716 state = MsiQueryProductStateA(prodcode);
1717 error = GetLastError();
1718 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1719 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1720 "expected ERROR_SUCCESS, got %u\n", error);
1721
1722 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1723 lstrcatA(keypath, prod_squashed);
1724
1725 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1726 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1727
1728 /* user product key exists */
1729 SetLastError(0xdeadbeef);
1730 state = MsiQueryProductStateA(prodcode);
1731 error = GetLastError();
1732 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1733 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1734 "expected ERROR_SUCCESS, got %u\n", error);
1735
1736 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
1737 lstrcatA(keypath, prodcode);
1738
1739 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1740 if (res == ERROR_ACCESS_DENIED)
1741 {
1742 skip("Not enough rights to perform tests\n");
1743 RegDeleteKeyA(userkey, "");
1744 RegCloseKey(userkey);
1745 LocalFree(usersid);
1746 return;
1747 }
1748 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1749
1750 /* local uninstall key exists */
1751 SetLastError(0xdeadbeef);
1752 state = MsiQueryProductStateA(prodcode);
1753 error = GetLastError();
1754 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1755 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1756 "expected ERROR_SUCCESS, got %u\n", error);
1757
1758 data = 1;
1759 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1760 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1761
1762 /* WindowsInstaller value exists */
1763 SetLastError(0xdeadbeef);
1764 state = MsiQueryProductStateA(prodcode);
1765 error = GetLastError();
1766 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1767 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1768 "expected ERROR_SUCCESS, got %u\n", error);
1769
1770 RegDeleteValueA(localkey, "WindowsInstaller");
1771 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1772
1773 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1774 lstrcatA(keypath, usersid);
1775 lstrcatA(keypath, "\\Products\\");
1776 lstrcatA(keypath, prod_squashed);
1777
1778 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1779 if (res == ERROR_ACCESS_DENIED)
1780 {
1781 skip("Not enough rights to perform tests\n");
1782 RegDeleteKeyA(userkey, "");
1783 RegCloseKey(userkey);
1784 LocalFree(usersid);
1785 return;
1786 }
1787 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1788
1789 /* local product key exists */
1790 SetLastError(0xdeadbeef);
1791 state = MsiQueryProductStateA(prodcode);
1792 error = GetLastError();
1793 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1794 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1795 "expected ERROR_SUCCESS, got %u\n", error);
1796
1797 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1798 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1799
1800 /* install properties key exists */
1801 SetLastError(0xdeadbeef);
1802 state = MsiQueryProductStateA(prodcode);
1803 error = GetLastError();
1804 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1805 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1806 "expected ERROR_SUCCESS, got %u\n", error);
1807
1808 data = 1;
1809 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1810 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1811
1812 /* WindowsInstaller value exists */
1813 SetLastError(0xdeadbeef);
1814 state = MsiQueryProductStateA(prodcode);
1815 error = GetLastError();
1816 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1817 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1818 "expected ERROR_SUCCESS, got %u\n", error);
1819
1820 data = 2;
1821 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1822 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1823
1824 /* WindowsInstaller value is not 1 */
1825 SetLastError(0xdeadbeef);
1826 state = MsiQueryProductStateA(prodcode);
1827 error = GetLastError();
1828 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1829 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1830 "expected ERROR_SUCCESS, got %u\n", error);
1831
1832 RegDeleteKeyA(userkey, "");
1833
1834 /* user product key does not exist */
1835 SetLastError(0xdeadbeef);
1836 state = MsiQueryProductStateA(prodcode);
1837 error = GetLastError();
1838 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1839 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1840 "expected ERROR_SUCCESS, got %u\n", error);
1841
1842 RegDeleteValueA(props, "WindowsInstaller");
1843 delete_key(props, "", access & KEY_WOW64_64KEY);
1844 RegCloseKey(props);
1845 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1846 RegCloseKey(localkey);
1847 RegDeleteKeyA(userkey, "");
1848 RegCloseKey(userkey);
1849
1850 /* MSIINSTALLCONTEXT_USERMANAGED */
1851
1852 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1853 lstrcatA(keypath, usersid);
1854 lstrcatA(keypath, "\\Installer\\Products\\");
1855 lstrcatA(keypath, prod_squashed);
1856
1857 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1858 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1859
1860 state = MsiQueryProductStateA(prodcode);
1861 ok(state == INSTALLSTATE_ADVERTISED,
1862 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1863
1864 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1865 lstrcatA(keypath, usersid);
1866 lstrcatA(keypath, "\\Products\\");
1867 lstrcatA(keypath, prod_squashed);
1868
1869 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1870 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1871
1872 state = MsiQueryProductStateA(prodcode);
1873 ok(state == INSTALLSTATE_ADVERTISED,
1874 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1875
1876 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1877 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1878
1879 state = MsiQueryProductStateA(prodcode);
1880 ok(state == INSTALLSTATE_ADVERTISED,
1881 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1882
1883 data = 1;
1884 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1885 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1886
1887 /* WindowsInstaller value exists */
1888 state = MsiQueryProductStateA(prodcode);
1889 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1890
1891 RegDeleteValueA(props, "WindowsInstaller");
1892 delete_key(props, "", access & KEY_WOW64_64KEY);
1893 RegCloseKey(props);
1894 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1895 RegCloseKey(localkey);
1896 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1897 RegCloseKey(prodkey);
1898
1899 /* MSIINSTALLCONTEXT_MACHINE */
1900
1901 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1902 lstrcatA(keypath, prod_squashed);
1903
1904 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1905 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1906
1907 state = MsiQueryProductStateA(prodcode);
1908 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1909
1910 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1911 lstrcatA(keypath, "S-1-5-18\\Products\\");
1912 lstrcatA(keypath, prod_squashed);
1913
1914 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1915 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1916
1917 state = MsiQueryProductStateA(prodcode);
1918 ok(state == INSTALLSTATE_ADVERTISED,
1919 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1920
1921 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1922 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1923
1924 state = MsiQueryProductStateA(prodcode);
1925 ok(state == INSTALLSTATE_ADVERTISED,
1926 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1927
1928 data = 1;
1929 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1930 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1931
1932 /* WindowsInstaller value exists */
1933 state = MsiQueryProductStateA(prodcode);
1934 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1935
1936 RegDeleteValueA(props, "WindowsInstaller");
1937 delete_key(props, "", access & KEY_WOW64_64KEY);
1938 RegCloseKey(props);
1939 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1940 RegCloseKey(localkey);
1941 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1942 RegCloseKey(prodkey);
1943
1944 LocalFree(usersid);
1945 }
1946
1947 static const char table_enc85[] =
1948 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
1949 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
1950 "yz{}~";
1951
1952 /*
1953 * Encodes a base85 guid given a GUID pointer
1954 * Caller should provide a 21 character buffer for the encoded string.
1955 */
1956 static void encode_base85_guid( GUID *guid, LPWSTR str )
1957 {
1958 unsigned int x, *p, i;
1959
1960 p = (unsigned int*) guid;
1961 for( i=0; i<4; i++ )
1962 {
1963 x = p[i];
1964 *str++ = table_enc85[x%85];
1965 x = x/85;
1966 *str++ = table_enc85[x%85];
1967 x = x/85;
1968 *str++ = table_enc85[x%85];
1969 x = x/85;
1970 *str++ = table_enc85[x%85];
1971 x = x/85;
1972 *str++ = table_enc85[x%85];
1973 }
1974 *str = 0;
1975 }
1976
1977 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
1978 {
1979 WCHAR guidW[MAX_PATH];
1980 WCHAR base85W[MAX_PATH];
1981 WCHAR squashedW[MAX_PATH];
1982 GUID guid;
1983 HRESULT hr;
1984 int size;
1985
1986 hr = CoCreateGuid(&guid);
1987 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1988
1989 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1990 ok(size == 39, "Expected 39, got %d\n", hr);
1991
1992 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1993 encode_base85_guid(&guid, base85W);
1994 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1995 squash_guid(guidW, squashedW);
1996 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1997 }
1998
1999 static void test_MsiQueryFeatureState(void)
2000 {
2001 HKEY userkey, localkey, compkey, compkey2;
2002 CHAR prodcode[MAX_PATH];
2003 CHAR prod_squashed[MAX_PATH];
2004 CHAR component[MAX_PATH];
2005 CHAR comp_base85[MAX_PATH];
2006 CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
2007 CHAR keypath[MAX_PATH*2];
2008 INSTALLSTATE state;
2009 LPSTR usersid;
2010 LONG res;
2011 REGSAM access = KEY_ALL_ACCESS;
2012 DWORD error;
2013
2014 create_test_guid(prodcode, prod_squashed);
2015 compose_base85_guid(component, comp_base85, comp_squashed);
2016 compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
2017 usersid = get_user_sid();
2018
2019 if (is_wow64)
2020 access |= KEY_WOW64_64KEY;
2021
2022 /* NULL prodcode */
2023 SetLastError(0xdeadbeef);
2024 state = MsiQueryFeatureStateA(NULL, "feature");
2025 error = GetLastError();
2026 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2027 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2028
2029 /* empty prodcode */
2030 SetLastError(0xdeadbeef);
2031 state = MsiQueryFeatureStateA("", "feature");
2032 error = GetLastError();
2033 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2034 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2035
2036 /* garbage prodcode */
2037 SetLastError(0xdeadbeef);
2038 state = MsiQueryFeatureStateA("garbage", "feature");
2039 error = GetLastError();
2040 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2041 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2042
2043 /* guid without brackets */
2044 SetLastError(0xdeadbeef);
2045 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
2046 error = GetLastError();
2047 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2048 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2049
2050 /* guid with brackets */
2051 SetLastError(0xdeadbeef);
2052 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
2053 error = GetLastError();
2054 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2055 ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
2056 "expected ERROR_SUCCESS, got %u\n", error);
2057
2058 /* same length as guid, but random */
2059 SetLastError(0xdeadbeef);
2060 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
2061 error = GetLastError();
2062 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2063 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2064
2065 /* NULL szFeature */
2066 SetLastError(0xdeadbeef);
2067 state = MsiQueryFeatureStateA(prodcode, NULL);
2068 error = GetLastError();
2069 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2070 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2071
2072 /* empty szFeature */
2073 SetLastError(0xdeadbeef);
2074 state = MsiQueryFeatureStateA(prodcode, "");
2075 error = GetLastError();
2076 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2077 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2078 "expected ERROR_SUCCESS, got %u\n", error);
2079
2080 /* feature key does not exist yet */
2081 SetLastError(0xdeadbeef);
2082 state = MsiQueryFeatureStateA(prodcode, "feature");
2083 error = GetLastError();
2084 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2085 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2086 "expected ERROR_SUCCESS, got %u\n", error);
2087
2088 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2089
2090 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
2091 lstrcatA(keypath, prod_squashed);
2092
2093 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2094 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2095
2096 /* feature key exists */
2097 SetLastError(0xdeadbeef);
2098 state = MsiQueryFeatureStateA(prodcode, "feature");
2099 error = GetLastError();
2100 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2101 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2102 "expected ERROR_SUCCESS, got %u\n", error);
2103
2104 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
2105 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2106
2107 /* feature value exists */
2108 SetLastError(0xdeadbeef);
2109 state = MsiQueryFeatureStateA(prodcode, "feature");
2110 error = GetLastError();
2111 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2112 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2113 "expected ERROR_SUCCESS, got %u\n", error);
2114
2115 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2116 lstrcatA(keypath, usersid);
2117 lstrcatA(keypath, "\\Products\\");
2118 lstrcatA(keypath, prod_squashed);
2119 lstrcatA(keypath, "\\Features");
2120
2121 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2122 if (res == ERROR_ACCESS_DENIED)
2123 {
2124 skip("Not enough rights to perform tests\n");
2125 RegDeleteKeyA(userkey, "");
2126 RegCloseKey(userkey);
2127 LocalFree(usersid);
2128 return;
2129 }
2130 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2131
2132 /* userdata features key exists */
2133 SetLastError(0xdeadbeef);
2134 state = MsiQueryFeatureStateA(prodcode, "feature");
2135 error = GetLastError();
2136 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2137 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2138 "expected ERROR_SUCCESS, got %u\n", error);
2139
2140 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2141 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2142
2143 SetLastError(0xdeadbeef);
2144 state = MsiQueryFeatureStateA(prodcode, "feature");
2145 error = GetLastError();
2146 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2147 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2148 "expected ERROR_SUCCESS, got %u\n", error);
2149
2150 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2151 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2152
2153 SetLastError(0xdeadbeef);
2154 state = MsiQueryFeatureStateA(prodcode, "feature");
2155 error = GetLastError();
2156 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2157 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2158 "expected ERROR_SUCCESS, got %u\n", error);
2159
2160 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2161 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2162
2163 SetLastError(0xdeadbeef);
2164 state = MsiQueryFeatureStateA(prodcode, "feature");
2165 error = GetLastError();
2166 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2167 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2168 "expected ERROR_SUCCESS, got %u\n", error);
2169
2170 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2171 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2172
2173 SetLastError(0xdeadbeef);
2174 state = MsiQueryFeatureStateA(prodcode, "feature");
2175 error = GetLastError();
2176 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2177 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2178 "expected ERROR_SUCCESS, got %u\n", error);
2179
2180 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2181 lstrcatA(keypath, usersid);
2182 lstrcatA(keypath, "\\Components\\");
2183 lstrcatA(keypath, comp_squashed);
2184
2185 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2186 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2187
2188 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2189 lstrcatA(keypath, usersid);
2190 lstrcatA(keypath, "\\Components\\");
2191 lstrcatA(keypath, comp_squashed2);
2192
2193 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2194 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2195
2196 SetLastError(0xdeadbeef);
2197 state = MsiQueryFeatureStateA(prodcode, "feature");
2198 error = GetLastError();
2199 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2200 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2201 "expected ERROR_SUCCESS, got %u\n", error);
2202
2203 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2204 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2205
2206 SetLastError(0xdeadbeef);
2207 state = MsiQueryFeatureStateA(prodcode, "feature");
2208 error = GetLastError();
2209 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2210 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2211 "expected ERROR_SUCCESS, got %u\n", error);
2212
2213 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2214 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2215
2216 SetLastError(0xdeadbeef);
2217 state = MsiQueryFeatureStateA(prodcode, "feature");
2218 error = GetLastError();
2219 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2220 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2221 "expected ERROR_SUCCESS, got %u\n", error);
2222
2223 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2224 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2225
2226 /* INSTALLSTATE_LOCAL */
2227 SetLastError(0xdeadbeef);
2228 state = MsiQueryFeatureStateA(prodcode, "feature");
2229 error = GetLastError();
2230 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2231 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2232 "expected ERROR_SUCCESS, got %u\n", error);
2233
2234 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2235 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2236
2237 /* INSTALLSTATE_SOURCE */
2238 SetLastError(0xdeadbeef);
2239 state = MsiQueryFeatureStateA(prodcode, "feature");
2240 error = GetLastError();
2241 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2242 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2243 "expected ERROR_SUCCESS, got %u\n", error);
2244
2245 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2246 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2247
2248 /* bad INSTALLSTATE_SOURCE */
2249 SetLastError(0xdeadbeef);
2250 state = MsiQueryFeatureStateA(prodcode, "feature");
2251 error = GetLastError();
2252 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2253 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2254 "expected ERROR_SUCCESS, got %u\n", error);
2255
2256 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2257 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2258
2259 /* INSTALLSTATE_SOURCE */
2260 SetLastError(0xdeadbeef);
2261 state = MsiQueryFeatureStateA(prodcode, "feature");
2262 error = GetLastError();
2263 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2264 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2265 "expected ERROR_SUCCESS, got %u\n", error);
2266
2267 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2268 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2269
2270 /* bad INSTALLSTATE_SOURCE */
2271 SetLastError(0xdeadbeef);
2272 state = MsiQueryFeatureStateA(prodcode, "feature");
2273 error = GetLastError();
2274 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2275 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2276 "expected ERROR_SUCCESS, got %u\n", error);
2277
2278 RegDeleteValueA(compkey, prod_squashed);
2279 RegDeleteValueA(compkey2, prod_squashed);
2280 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2281 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2282 RegDeleteValueA(localkey, "feature");
2283 RegDeleteValueA(userkey, "feature");
2284 RegDeleteKeyA(userkey, "");
2285 RegCloseKey(compkey);
2286 RegCloseKey(compkey2);
2287 RegCloseKey(localkey);
2288 RegCloseKey(userkey);
2289
2290 /* MSIINSTALLCONTEXT_USERMANAGED */
2291
2292 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2293 lstrcatA(keypath, usersid);
2294 lstrcatA(keypath, "\\Installer\\Features\\");
2295 lstrcatA(keypath, prod_squashed);
2296
2297 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2298 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2299
2300 /* feature key exists */
2301 state = MsiQueryFeatureStateA(prodcode, "feature");
2302 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2303
2304 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2305 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2306
2307 /* feature value exists */
2308 state = MsiQueryFeatureStateA(prodcode, "feature");
2309 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2310
2311 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2312 lstrcatA(keypath, usersid);
2313 lstrcatA(keypath, "\\Products\\");
2314 lstrcatA(keypath, prod_squashed);
2315 lstrcatA(keypath, "\\Features");
2316
2317 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2318 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2319
2320 /* userdata features key exists */
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 *)"aaaaaaaaaaaaaaaaaaa", 20);
2325 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2326
2327 state = MsiQueryFeatureStateA(prodcode, "feature");
2328 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2329
2330 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2331 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2332
2333 state = MsiQueryFeatureStateA(prodcode, "feature");
2334 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2335
2336 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2337 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2338
2339 state = MsiQueryFeatureStateA(prodcode, "feature");
2340 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2341
2342 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2344
2345 state = MsiQueryFeatureStateA(prodcode, "feature");
2346 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2347
2348 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2349 lstrcatA(keypath, usersid);
2350 lstrcatA(keypath, "\\Components\\");
2351 lstrcatA(keypath, comp_squashed);
2352
2353 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2354 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2355
2356 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2357 lstrcatA(keypath, usersid);
2358 lstrcatA(keypath, "\\Components\\");
2359 lstrcatA(keypath, comp_squashed2);
2360
2361 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2362 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2363
2364 state = MsiQueryFeatureStateA(prodcode, "feature");
2365 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2366
2367 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2368 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2369
2370 state = MsiQueryFeatureStateA(prodcode, "feature");
2371 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2372
2373 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2375
2376 state = MsiQueryFeatureStateA(prodcode, "feature");
2377 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2378
2379 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2380 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2381
2382 state = MsiQueryFeatureStateA(prodcode, "feature");
2383 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2384
2385 RegDeleteValueA(compkey, prod_squashed);
2386 RegDeleteValueA(compkey2, prod_squashed);
2387 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2388 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2389 RegDeleteValueA(localkey, "feature");
2390 RegDeleteValueA(userkey, "feature");
2391 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2392 RegCloseKey(compkey);
2393 RegCloseKey(compkey2);
2394 RegCloseKey(localkey);
2395 RegCloseKey(userkey);
2396
2397 /* MSIINSTALLCONTEXT_MACHINE */
2398
2399 lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
2400 lstrcatA(keypath, prod_squashed);
2401
2402 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2403 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2404
2405 /* feature key exists */
2406 state = MsiQueryFeatureStateA(prodcode, "feature");
2407 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2408
2409 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2410 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2411
2412 /* feature value exists */
2413 state = MsiQueryFeatureStateA(prodcode, "feature");
2414 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2415
2416 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2417 lstrcatA(keypath, "S-1-5-18\\Products\\");
2418 lstrcatA(keypath, prod_squashed);
2419 lstrcatA(keypath, "\\Features");
2420
2421 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2422 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2423
2424 /* userdata features key exists */
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 *)"aaaaaaaaaaaaaaaaaaa", 20);
2429 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2430
2431 state = MsiQueryFeatureStateA(prodcode, "feature");
2432 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2433
2434 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2435 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2436
2437 state = MsiQueryFeatureStateA(prodcode, "feature");
2438 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2439
2440 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2442
2443 state = MsiQueryFeatureStateA(prodcode, "feature");
2444 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2445
2446 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2447 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2448
2449 state = MsiQueryFeatureStateA(prodcode, "feature");
2450 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2451
2452 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2453 lstrcatA(keypath, "S-1-5-18\\Components\\");
2454 lstrcatA(keypath, comp_squashed);
2455
2456 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2458
2459 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2460 lstrcatA(keypath, "S-1-5-18\\Components\\");
2461 lstrcatA(keypath, comp_squashed2);
2462
2463 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2464 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2465
2466 state = MsiQueryFeatureStateA(prodcode, "feature");
2467 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2468
2469 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2470 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2471
2472 state = MsiQueryFeatureStateA(prodcode, "feature");
2473 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2474
2475 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2476 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2477
2478 state = MsiQueryFeatureStateA(prodcode, "feature");
2479 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2480
2481 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2482 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2483
2484 state = MsiQueryFeatureStateA(prodcode, "feature");
2485 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2486
2487 RegDeleteValueA(compkey, prod_squashed);
2488 RegDeleteValueA(compkey2, prod_squashed);
2489 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2490 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2491 RegDeleteValueA(localkey, "feature");
2492 RegDeleteValueA(userkey, "feature");
2493 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2494 RegCloseKey(compkey);
2495 RegCloseKey(compkey2);
2496 RegCloseKey(localkey);
2497 RegCloseKey(userkey);
2498 LocalFree(usersid);
2499 }
2500
2501 static void test_MsiQueryComponentState(void)
2502 {
2503 HKEY compkey, prodkey;
2504 CHAR prodcode[MAX_PATH];
2505 CHAR prod_squashed[MAX_PATH];
2506 CHAR component[MAX_PATH];
2507 CHAR comp_base85[MAX_PATH];
2508 CHAR comp_squashed[MAX_PATH];
2509 CHAR keypath[MAX_PATH];
2510 INSTALLSTATE state;
2511 LPSTR usersid;
2512 LONG res;
2513 UINT r;
2514 REGSAM access = KEY_ALL_ACCESS;
2515 DWORD error;
2516
2517 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
2518
2519 if (!pMsiQueryComponentStateA)
2520 {
2521 win_skip("MsiQueryComponentStateA not implemented\n");
2522 return;
2523 }
2524
2525 create_test_guid(prodcode, prod_squashed);
2526 compose_base85_guid(component, comp_base85, comp_squashed);
2527 usersid = get_user_sid();
2528
2529 if (is_wow64)
2530 access |= KEY_WOW64_64KEY;
2531
2532 /* NULL szProductCode */
2533 state = MAGIC_ERROR;
2534 SetLastError(0xdeadbeef);
2535 r = pMsiQueryComponentStateA(NULL, 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 /* empty szProductCode */
2542 state = MAGIC_ERROR;
2543 SetLastError(0xdeadbeef);
2544 r = pMsiQueryComponentStateA("", 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 /* random szProductCode */
2551 state = MAGIC_ERROR;
2552 SetLastError(0xdeadbeef);
2553 r = pMsiQueryComponentStateA("random", 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 /* GUID-length szProductCode */
2560 state = MAGIC_ERROR;
2561 SetLastError(0xdeadbeef);
2562 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2563 error = GetLastError();
2564 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, 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 /* GUID-length with brackets */
2569 state = MAGIC_ERROR;
2570 SetLastError(0xdeadbeef);
2571 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2572 error = GetLastError();
2573 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2574 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2575 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2576
2577 /* actual GUID */
2578 state = MAGIC_ERROR;
2579 SetLastError(0xdeadbeef);
2580 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2581 error = GetLastError();
2582 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2583 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2584 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2585
2586 state = MAGIC_ERROR;
2587 SetLastError(0xdeadbeef);
2588 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2589 error = GetLastError();
2590 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2591 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2592 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2593
2594 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2595 lstrcatA(keypath, prod_squashed);
2596
2597 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2598 if (res == ERROR_ACCESS_DENIED)
2599 {
2600 skip("Not enough rights to perform tests\n");
2601 LocalFree(usersid);
2602 return;
2603 }
2604 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2605
2606 state = MAGIC_ERROR;
2607 SetLastError(0xdeadbeef);
2608 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2609 error = GetLastError();
2610 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2611 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2612 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2613
2614 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2615 RegCloseKey(prodkey);
2616
2617 /* create local system product key */
2618 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
2619 lstrcatA(keypath, prod_squashed);
2620 lstrcatA(keypath, "\\InstallProperties");
2621
2622 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2623 if (res == ERROR_ACCESS_DENIED)
2624 {
2625 skip("Not enough rights to perform tests\n");
2626 LocalFree(usersid);
2627 return;
2628 }
2629 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2630
2631 /* local system product key exists */
2632 state = MAGIC_ERROR;
2633 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2634 error = GetLastError();
2635 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2636 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2637 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2638
2639 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2640 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2641
2642 /* LocalPackage value exists */
2643 state = MAGIC_ERROR;
2644 SetLastError(0xdeadbeef);
2645 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2646 error = GetLastError();
2647 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2648 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2649 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2650
2651 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
2652 lstrcatA(keypath, comp_squashed);
2653
2654 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2655 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2656
2657 /* component key exists */
2658 state = MAGIC_ERROR;
2659 SetLastError(0xdeadbeef);
2660 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2661 error = GetLastError();
2662 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2663 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2664 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2665
2666 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2667 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2668
2669 /* component\product exists */
2670 state = MAGIC_ERROR;
2671 SetLastError(0xdeadbeef);
2672 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2674 error = GetLastError();
2675 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2676 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2677 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2678
2679 /* NULL component, product exists */
2680 state = MAGIC_ERROR;
2681 SetLastError(0xdeadbeef);
2682 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
2683 error = GetLastError();
2684 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2685 ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
2686 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2687
2688 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2689 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2690
2691 /* INSTALLSTATE_LOCAL */
2692 state = MAGIC_ERROR;
2693 SetLastError(0xdeadbeef);
2694 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2695 error = GetLastError();
2696 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2697 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2698 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2699
2700 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2701 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2702
2703 /* INSTALLSTATE_SOURCE */
2704 state = MAGIC_ERROR;
2705 SetLastError(0xdeadbeef);
2706 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2707 error = GetLastError();
2708 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2709 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2710 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2711
2712 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2713 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2714
2715 /* bad INSTALLSTATE_SOURCE */
2716 state = MAGIC_ERROR;
2717 SetLastError(0xdeadbeef);
2718 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2719 error = GetLastError();
2720 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2721 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2722 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2723
2724 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2725 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2726
2727 /* INSTALLSTATE_SOURCE */
2728 state = MAGIC_ERROR;
2729 SetLastError(0xdeadbeef);
2730 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2731 error = GetLastError();
2732 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2733 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2734 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2735
2736 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
2737 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2738
2739 /* registry component */
2740 state = MAGIC_ERROR;
2741 SetLastError(0xdeadbeef);
2742 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2743 error = GetLastError();
2744 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2745 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2746 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2747
2748 RegDeleteValueA(prodkey, "LocalPackage");
2749 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2750 RegDeleteValueA(compkey, prod_squashed);
2751 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2752 RegCloseKey(prodkey);
2753 RegCloseKey(compkey);
2754
2755 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2756
2757 state = MAGIC_ERROR;
2758 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2759 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2760 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2761
2762 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2763 lstrcatA(keypath, prod_squashed);
2764
2765 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2766 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2767
2768 state = MAGIC_ERROR;
2769 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2770 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2771 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2772
2773 RegDeleteKeyA(prodkey, "");
2774 RegCloseKey(prodkey);
2775
2776 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2777 lstrcatA(keypath, usersid);
2778 lstrcatA(keypath, "\\Products\\");
2779 lstrcatA(keypath, prod_squashed);
2780 lstrcatA(keypath, "\\InstallProperties");
2781
2782 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2783 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2784
2785 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2787
2788 RegCloseKey(prodkey);
2789
2790 state = MAGIC_ERROR;
2791 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2792 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2793 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2794
2795 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2796 lstrcatA(keypath, usersid);
2797 lstrcatA(keypath, "\\Components\\");
2798 lstrcatA(keypath, comp_squashed);
2799
2800 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2802
2803 /* component key exists */
2804 state = MAGIC_ERROR;
2805 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2806 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2807 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2808
2809 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2810 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2811
2812 /* component\product exists */
2813 state = MAGIC_ERROR;
2814 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2815 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2816 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2817 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2818
2819 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2820 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2821
2822 state = MAGIC_ERROR;
2823 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2824 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2825 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2826
2827 /* MSIINSTALLCONTEXT_USERMANAGED */
2828
2829 state = MAGIC_ERROR;
2830 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2831 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2832 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2833
2834 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2835 lstrcatA(keypath, prod_squashed);
2836
2837 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2838 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2839
2840 state = MAGIC_ERROR;
2841 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2842 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2843 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2844
2845 RegDeleteKeyA(prodkey, "");
2846 RegCloseKey(prodkey);
2847
2848 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2849 lstrcatA(keypath, usersid);
2850 lstrcatA(keypath, "\\Installer\\Products\\");
2851 lstrcatA(keypath, prod_squashed);
2852
2853 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2854 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2855
2856 state = MAGIC_ERROR;
2857 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2858 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2859 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2860
2861 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2862 RegCloseKey(prodkey);
2863
2864 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2865 lstrcatA(keypath, usersid);
2866 lstrcatA(keypath, "\\Products\\");
2867 lstrcatA(keypath, prod_squashed);
2868 lstrcatA(keypath, "\\InstallProperties");
2869
2870 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2871 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2872
2873 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2875
2876 state = MAGIC_ERROR;
2877 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2878 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2879 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2880
2881 RegDeleteValueA(prodkey, "LocalPackage");
2882 RegDeleteValueA(prodkey, "ManagedLocalPackage");
2883 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2884 RegDeleteValueA(compkey, prod_squashed);
2885 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2886 RegCloseKey(prodkey);
2887 RegCloseKey(compkey);
2888 LocalFree(usersid);
2889 }
2890
2891 static void test_MsiGetComponentPath(void)
2892 {
2893 HKEY compkey, prodkey, installprop;
2894 CHAR prodcode[MAX_PATH];
2895 CHAR prod_squashed[MAX_PATH];
2896 CHAR component[MAX_PATH];
2897 CHAR comp_base85[MAX_PATH];
2898 CHAR comp_squashed[MAX_PATH];
2899 CHAR keypath[MAX_PATH];
2900 CHAR path[MAX_PATH];
2901 INSTALLSTATE state;
2902 LPSTR usersid;
2903 DWORD size, val;
2904 REGSAM access = KEY_ALL_ACCESS;
2905 LONG res;
2906
2907 create_test_guid(prodcode, prod_squashed);
2908 compose_base85_guid(component, comp_base85, comp_squashed);
2909 usersid = get_user_sid();
2910
2911 if (is_wow64)
2912 access |= KEY_WOW64_64KEY;
2913
2914 /* NULL szProduct */
2915 size = MAX_PATH;
2916 state = MsiGetComponentPathA(NULL, component, path, &size);
2917 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2918 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2919
2920 /* NULL szComponent */
2921 size = MAX_PATH;
2922 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
2923 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2924 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2925
2926 size = MAX_PATH;
2927 state = MsiLocateComponentA(NULL, path, &size);
2928 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2929 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2930
2931 /* NULL lpPathBuf */
2932 size = MAX_PATH;
2933 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
2934 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2935 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2936
2937 size = MAX_PATH;
2938 state = MsiLocateComponentA(component, NULL, &size);
2939 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2940 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2941
2942 /* NULL pcchBuf */
2943 size = MAX_PATH;
2944 state = MsiGetComponentPathA(prodcode, component, path, NULL);
2945 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2946 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2947
2948 size = MAX_PATH;
2949 state = MsiLocateComponentA(component, path, NULL);
2950 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2951 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2952
2953 /* all params valid */
2954 size = MAX_PATH;
2955 state = MsiGetComponentPathA(prodcode, component, path, &size);
2956 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2957 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2958
2959 size = MAX_PATH;
2960 state = MsiLocateComponentA(component, path, &size);
2961 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2962 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2963
2964 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2965 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2966 lstrcatA(keypath, comp_squashed);
2967
2968 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2969 if (res == ERROR_ACCESS_DENIED)
2970 {
2971 skip("Not enough rights to perform tests\n");
2972 LocalFree(usersid);
2973 return;
2974 }
2975 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2976
2977 /* local system component key exists */
2978 size = MAX_PATH;
2979 state = MsiGetComponentPathA(prodcode, component, path, &size);
2980 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2981 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2982
2983 size = MAX_PATH;
2984 state = MsiLocateComponentA(component, path, &size);
2985 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2986 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2987
2988 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2989 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2990
2991 /* product value exists */
2992 path[0] = 0;
2993 size = MAX_PATH;
2994 state = MsiGetComponentPathA(prodcode, component, path, &size);
2995 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2996 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2997 ok(size == 10, "Expected 10, got %d\n", size);
2998
2999 path[0] = 0;
3000 size = MAX_PATH;
3001 state = MsiLocateComponentA(component, path, &size);
3002 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3003 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3004 ok(size == 10, "Expected 10, got %d\n", size);
3005
3006 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3007 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3008 lstrcatA(keypath, prod_squashed);
3009 lstrcatA(keypath, "\\InstallProperties");
3010
3011 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3012 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3013
3014 val = 1;
3015 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3016 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3017
3018 /* install properties key exists */
3019 path[0] = 0;
3020 size = MAX_PATH;
3021 state = MsiGetComponentPathA(prodcode, component, path, &size);
3022 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3023 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3024 ok(size == 10, "Expected 10, got %d\n", size);
3025
3026 path[0] = 0;
3027 size = MAX_PATH;
3028 state = MsiLocateComponentA(component, path, &size);
3029 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3030 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3031 ok(size == 10, "Expected 10, got %d\n", size);
3032
3033 create_file("C:\\imapath", "C:\\imapath", 11);
3034
3035 /* file exists */
3036 path[0] = 'a';
3037 size = 0;
3038 state = MsiGetComponentPathA(prodcode, component, path, &size);
3039 ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
3040 ok(path[0] == 'a', "got %s\n", path);
3041 ok(size == 10, "Expected 10, got %d\n", size);
3042
3043 path[0] = 0;
3044 size = MAX_PATH;
3045 state = MsiGetComponentPathA(prodcode, component, path, &size);
3046 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3047 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3048 ok(size == 10, "Expected 10, got %d\n", size);
3049
3050 size = 0;
3051 path[0] = 'a';
3052 state = MsiLocateComponentA(component, path, &size);
3053 ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
3054 ok(path[0] == 'a', "got %s\n", path);
3055 ok(size == 10, "Expected 10, got %d\n", size);
3056
3057 path[0] = 0;
3058 size = MAX_PATH;
3059 state = MsiLocateComponentA(component, path, &size);
3060 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3061 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3062 ok(size == 10, "Expected 10, got %d\n", size);
3063
3064 RegDeleteValueA(compkey, prod_squashed);
3065 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3066 RegDeleteValueA(installprop, "WindowsInstaller");
3067 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3068 RegCloseKey(compkey);
3069 RegCloseKey(installprop);
3070 DeleteFileA("C:\\imapath");
3071
3072 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3073 lstrcatA(keypath, "Installer\\UserData\\");
3074 lstrcatA(keypath, usersid);
3075 lstrcatA(keypath, "\\Components\\");
3076 lstrcatA(keypath, comp_squashed);
3077
3078 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3079 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3080
3081 /* user managed component key exists */
3082 size = MAX_PATH;
3083 state = MsiGetComponentPathA(prodcode, component, path, &size);
3084 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3085 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3086
3087 size = MAX_PATH;
3088 state = MsiLocateComponentA(component, path, &size);
3089 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3090 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3091
3092 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3093 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3094
3095 /* product value exists */
3096 path[0] = 0;
3097 size = MAX_PATH;
3098 state = MsiGetComponentPathA(prodcode, component, path, &size);
3099 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3100 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3101 ok(size == 10, "Expected 10, got %d\n", size);
3102
3103 path[0] = 0;
3104 size = MAX_PATH;
3105 state = MsiLocateComponentA(component, path, &size);
3106 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3107 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3108 ok(size == 10, "Expected 10, got %d\n", size);
3109
3110 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3111 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3112 lstrcatA(keypath, prod_squashed);
3113 lstrcatA(keypath, "\\InstallProperties");
3114
3115 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3116 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3117
3118 val = 1;
3119 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3120 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3121
3122 /* install properties key exists */
3123 path[0] = 0;
3124 size = MAX_PATH;
3125 state = MsiGetComponentPathA(prodcode, component, path, &size);
3126 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3127 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3128 ok(size == 10, "Expected 10, got %d\n", size);
3129
3130 path[0] = 0;
3131 size = MAX_PATH;
3132 state = MsiLocateComponentA(component, path, &size);
3133 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3134 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3135 ok(size == 10, "Expected 10, got %d\n", size);
3136
3137 create_file("C:\\imapath", "C:\\imapath", 11);
3138
3139 /* file exists */
3140 path[0] = 0;
3141 size = MAX_PATH;
3142 state = MsiGetComponentPathA(prodcode, component, path, &size);
3143 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3144 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3145 ok(size == 10, "Expected 10, got %d\n", size);
3146
3147 path[0] = 0;
3148 size = MAX_PATH;
3149 state = MsiLocateComponentA(component, path, &size);
3150 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3151 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3152 ok(size == 10, "Expected 10, got %d\n", size);
3153
3154 RegDeleteValueA(compkey, prod_squashed);
3155 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3156 RegDeleteValueA(installprop, "WindowsInstaller");
3157 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3158 RegCloseKey(compkey);
3159 RegCloseKey(installprop);
3160 DeleteFileA("C:\\imapath");
3161
3162 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3163 lstrcatA(keypath, "Installer\\Managed\\");
3164 lstrcatA(keypath, usersid);
3165 lstrcatA(keypath, "\\Installer\\Products\\");
3166 lstrcatA(keypath, prod_squashed);
3167
3168 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3169 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3170
3171 /* user managed product key exists */
3172 size = MAX_PATH;
3173 state = MsiGetComponentPathA(prodcode, component, path, &size);
3174 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3175 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3176
3177 size = MAX_PATH;
3178 state = MsiLocateComponentA(component, path, &size);
3179 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3180 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3181
3182 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3183 lstrcatA(keypath, "Installer\\UserData\\");
3184 lstrcatA(keypath, usersid);
3185 lstrcatA(keypath, "\\Components\\");
3186 lstrcatA(keypath, comp_squashed);
3187
3188 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3190
3191 /* user managed component key exists */
3192 size = MAX_PATH;
3193 state = MsiGetComponentPathA(prodcode, component, path, &size);
3194 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3195 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3196
3197 size = MAX_PATH;
3198 state = MsiLocateComponentA(component, path, &size);
3199 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3200 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3201
3202 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3203 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3204
3205 /* product value exists */
3206 path[0] = 0;
3207 size = MAX_PATH;
3208 state = MsiGetComponentPathA(prodcode, component, path, &size);
3209 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3210 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3211 ok(size == 10, "Expected 10, got %d\n", size);
3212
3213 path[0] = 0;
3214 size = MAX_PATH;
3215 state = MsiLocateComponentA(component, path, &size);
3216 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3217 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3218 ok(size == 10, "Expected 10, got %d\n", size);
3219
3220 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3221 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3222 lstrcatA(keypath, prod_squashed);
3223 lstrcatA(keypath, "\\InstallProperties");
3224
3225 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3226 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3227
3228 val = 1;
3229 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3230 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3231
3232 /* install properties key exists */
3233 path[0] = 0;
3234 size = MAX_PATH;
3235 state = MsiGetComponentPathA(prodcode, component, path, &size);
3236 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3237 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3238 ok(size == 10, "Expected 10, got %d\n", size);
3239
3240 path[0] = 0;
3241 size = MAX_PATH;
3242 state = MsiLocateComponentA(component, path, &size);
3243 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3244 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3245 ok(size == 10, "Expected 10, got %d\n", size);
3246
3247 create_file("C:\\imapath", "C:\\imapath", 11);
3248
3249 /* file exists */
3250 path[0] = 0;
3251 size = MAX_PATH;
3252 state = MsiGetComponentPathA(prodcode, component, path, &size);
3253 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3254 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3255 ok(size == 10, "Expected 10, got %d\n", size);
3256
3257 path[0] = 0;
3258 size = MAX_PATH;
3259 state = MsiLocateComponentA(component, path, &size);
3260 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3261 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3262 ok(size == 10, "Expected 10, got %d\n", size);
3263
3264 RegDeleteValueA(compkey, prod_squashed);
3265 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3266 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3267 RegDeleteValueA(installprop, "WindowsInstaller");
3268 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3269 RegCloseKey(prodkey);
3270 RegCloseKey(compkey);
3271 RegCloseKey(installprop);
3272 DeleteFileA("C:\\imapath");
3273
3274 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3275 lstrcatA(keypath, prod_squashed);
3276
3277 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3279
3280 /* user unmanaged product key exists */
3281 size = MAX_PATH;
3282 state = MsiGetComponentPathA(prodcode, component, path, &size);
3283 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3284 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3285
3286 size = MAX_PATH;
3287 state = MsiLocateComponentA(component, path, &size);
3288 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3289 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3290
3291 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3292 lstrcatA(keypath, "Installer\\UserData\\");
3293 lstrcatA(keypath, usersid);
3294 lstrcatA(keypath, "\\Components\\");
3295 lstrcatA(keypath, comp_squashed);
3296
3297 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3298 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3299
3300 /* user unmanaged component key exists */
3301 size = MAX_PATH;
3302 state = MsiGetComponentPathA(prodcode, component, path, &size);
3303 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3304 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3305
3306 size = MAX_PATH;
3307 state = MsiLocateComponentA(component, path, &size);
3308 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3309 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3310
3311 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3312 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3313
3314 /* product value exists */
3315 path[0] = 0;
3316 size = MAX_PATH;
3317 state = MsiGetComponentPathA(prodcode, component, path, &size);
3318 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3319 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3320 ok(size == 10, "Expected 10, got %d\n", size);
3321
3322 path[0] = 0;
3323 size = MAX_PATH;
3324 state = MsiLocateComponentA(component, path, &size);
3325 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3326 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3327 ok(size == 10, "Expected 10, got %d\n", size);
3328
3329 create_file("C:\\imapath", "C:\\imapath", 11);
3330
3331 /* file exists */
3332 path[0] = 0;
3333 size = MAX_PATH;
3334 state = MsiGetComponentPathA(prodcode, component, path, &size);
3335 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3336 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3337 ok(size == 10, "Expected 10, got %d\n", size);
3338
3339 path[0] = 0;
3340 size = MAX_PATH;
3341 state = MsiLocateComponentA(component, path, &size);
3342 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3343 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3344 ok(size == 10, "Expected 10, got %d\n", size);
3345
3346 RegDeleteValueA(compkey, prod_squashed);
3347 RegDeleteKeyA(prodkey, "");
3348 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3349 RegCloseKey(prodkey);
3350 RegCloseKey(compkey);
3351 DeleteFileA("C:\\imapath");
3352
3353 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3354 lstrcatA(keypath, prod_squashed);
3355
3356 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3357 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3358
3359 /* local classes product 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 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3371 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3372 lstrcatA(keypath, comp_squashed);
3373
3374 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3375 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3376
3377 /* local user component key exists */
3378 size = MAX_PATH;
3379 state = MsiGetComponentPathA(prodcode, component, path, &size);
3380 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3381 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3382
3383 size = MAX_PATH;
3384 state = MsiLocateComponentA(component, path, &size);
3385 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3386 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3387
3388 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3390
3391 /* product value exists */
3392 path[0] = 0;
3393 size = MAX_PATH;
3394 state = MsiGetComponentPathA(prodcode, component, path, &size);
3395 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3396 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3397 ok(size == 10, "Expected 10, got %d\n", size);
3398
3399 path[0] = 0;
3400 size = MAX_PATH;
3401 state = MsiLocateComponentA(component, path, &size);
3402 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3403 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3404 ok(size == 10, "Expected 10, got %d\n", size);
3405
3406 create_file("C:\\imapath", "C:\\imapath", 11);
3407
3408 /* file exists */
3409 path[0] = 0;
3410 size = MAX_PATH;
3411 state = MsiGetComponentPathA(prodcode, component, path, &size);
3412 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3413 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3414 ok(size == 10, "Expected 10, got %d\n", size);
3415
3416 path[0] = 0;
3417 size = MAX_PATH;
3418 state = MsiLocateComponentA(component, path, &size);
3419 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3420 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3421 ok(size == 10, "Expected 10, got %d\n", size);
3422
3423 RegDeleteValueA(compkey, prod_squashed);
3424 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3425 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3426 RegCloseKey(prodkey);
3427 RegCloseKey(compkey);
3428 DeleteFileA("C:\\imapath");
3429 LocalFree(usersid);
3430 }
3431
3432 static void test_MsiGetComponentPathEx(void)
3433 {
3434 HKEY key_comp, key_installprop, key_prod;
3435 char prod[MAX_PATH], prod_squashed[MAX_PATH];
3436 char comp[MAX_PATH], comp_base85[MAX_PATH], comp_squashed[MAX_PATH];
3437 char path[MAX_PATH], path_key[MAX_PATH], *usersid;
3438 INSTALLSTATE state;
3439 DWORD size, val;
3440 REGSAM access = KEY_ALL_ACCESS;
3441 LONG res;
3442
3443 if (!pMsiGetComponentPathExA)
3444 {
3445 win_skip( "MsiGetComponentPathExA not present\n" );
3446 return;
3447 }
3448
3449 if (is_wow64) access |= KEY_WOW64_64KEY;
3450
3451 create_test_guid( prod, prod_squashed );
3452 compose_base85_guid( comp, comp_base85, comp_squashed );
3453 usersid = get_user_sid();
3454
3455 /* NULL product */
3456 size = MAX_PATH;
3457 state = pMsiGetComponentPathExA( NULL, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
3458 ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
3459 todo_wine ok( !size, "got %u\n", size );
3460
3461 /* NULL component */
3462 size = MAX_PATH;
3463 state = pMsiGetComponentPathExA( prod, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
3464 ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
3465 todo_wine ok( !size, "got %u\n", size );
3466
3467 /* non-NULL usersid, MSIINSTALLCONTEXT_MACHINE */
3468 size = MAX_PATH;
3469 state = pMsiGetComponentPathExA( prod, comp, usersid, MSIINSTALLCONTEXT_MACHINE, path, &size);
3470 ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
3471 todo_wine ok( !size, "got %u\n", size );
3472
3473 /* NULL buf */
3474 size = MAX_PATH;
3475 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &size );
3476 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3477 todo_wine ok( size == MAX_PATH * 2, "got %u\n", size );
3478
3479 /* NULL buflen */
3480 size = MAX_PATH;
3481 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, NULL );
3482 ok( state == INSTALLSTATE_INVALIDARG, "got %d\n", state );
3483 ok( size == MAX_PATH, "got %u\n", size );
3484
3485 /* all params valid */
3486 size = MAX_PATH;
3487 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3488 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3489 todo_wine ok( !size, "got %u\n", size );
3490
3491 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3492 lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Components\\" );
3493 lstrcatA( path_key, comp_squashed );
3494
3495 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
3496 if (res == ERROR_ACCESS_DENIED)
3497 {
3498 skip( "insufficient rights\n" );
3499 LocalFree( usersid );
3500 return;
3501 }
3502 ok( res == ERROR_SUCCESS, "got %d\n", res );
3503
3504 /* local system component key exists */
3505 size = MAX_PATH;
3506 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3507 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3508
3509 res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
3510 ok( res == ERROR_SUCCESS, "got %d\n", res );
3511
3512 /* product value exists */
3513 path[0] = 0;
3514 size = MAX_PATH;
3515 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3516 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3517 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3518 ok( size == 20, "got %u\n", size );
3519
3520 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3521 lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Products\\" );
3522 lstrcatA( path_key, prod_squashed );
3523 lstrcatA( path_key, "\\InstallProperties" );
3524
3525 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_installprop, NULL );
3526 ok( res == ERROR_SUCCESS, "got %d\n", res );
3527
3528 val = 1;
3529 res = RegSetValueExA( key_installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(val) );
3530 ok( res == ERROR_SUCCESS, "got %d\n", res );
3531
3532 /* install properties key exists */
3533 path[0] = 0;
3534 size = MAX_PATH;
3535 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3536 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3537 ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
3538 ok( size == 20, "got %u\n", size );
3539
3540 create_file( "c:\\testcomponentpath", "c:\\testcomponentpath", 21 );
3541
3542 /* file exists */
3543 path[0] = 0;
3544 size = 0;
3545 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3546 ok( state == INSTALLSTATE_MOREDATA, "got %d\n", state );
3547 ok( !path[0], "got %s\n", path );
3548 todo_wine ok( size == 40, "got %u\n", size );
3549
3550 path[0] = 0;
3551 size = MAX_PATH;
3552 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3553 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3554 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3555 ok( size == 20, "got %d\n", size );
3556
3557 RegDeleteValueA( key_comp, prod_squashed );
3558 delete_key( key_comp, "", access & KEY_WOW64_64KEY );
3559 RegDeleteValueA( key_installprop, "WindowsInstaller" );
3560 delete_key( key_installprop, "", access & KEY_WOW64_64KEY );
3561 RegCloseKey( key_comp );
3562 RegCloseKey( key_installprop );
3563 DeleteFileA( "c:\\testcomponentpath" );
3564
3565 lstrcpyA( path_key, "Software\\Microsoft\\Installer\\Products\\" );
3566 lstrcatA( path_key, prod_squashed );
3567
3568 res = RegCreateKeyA( HKEY_CURRENT_USER, path_key, &key_prod );
3569 ok( res == ERROR_SUCCESS, "got %d\n", res );
3570
3571 /* user unmanaged product key exists */
3572 size = MAX_PATH;
3573 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, path, &size );
3574 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3575 todo_wine ok(!size, "got %u\n", size);
3576
3577 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3578 lstrcatA( path_key, "Installer\\UserData\\" );
3579 lstrcatA( path_key, usersid );
3580 lstrcatA( path_key, "\\Components\\" );
3581 lstrcatA( path_key, comp_squashed );
3582
3583 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
3584 ok( res == ERROR_SUCCESS, "got %d\n", res );
3585
3586 /* user unmanaged component key exists */
3587 size = MAX_PATH;
3588 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, path, &size );
3589 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3590 todo_wine ok(!size, "got %u\n", size);
3591
3592 res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
3593 ok( res == ERROR_SUCCESS, "got %d\n", res );
3594
3595 /* product value exists */
3596 path[0] = 0;
3597 size = MAX_PATH;
3598 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, path, &size );
3599 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3600 ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
3601 ok( size == 20, "got %u\n", size );
3602
3603 create_file( "c:\\testcomponentpath", "c:\\testcomponentpath", 21 );
3604
3605 /* file exists */
3606 path[0] = 0;
3607 size = MAX_PATH;
3608 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, path, &size );
3609 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3610 ok( !lstrcmpA( path, "c:\\testcomponentpath"), "got %s\n", path );
3611 ok( size == 20, "got %u\n", size );
3612
3613 RegDeleteValueA( key_comp, prod_squashed );
3614 RegDeleteKeyA( key_prod, "" );
3615 delete_key( key_comp, "", access & KEY_WOW64_64KEY );
3616 RegCloseKey( key_prod );
3617 RegCloseKey( key_comp );
3618 DeleteFileA( "c:\\testcomponentpath" );
3619
3620 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3621 lstrcatA( path_key, "Installer\\Managed\\" );
3622 lstrcatA( path_key, usersid );
3623 lstrcatA( path_key, "\\Installer\\Products\\" );
3624 lstrcatA( path_key, prod_squashed );
3625
3626 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_prod, NULL );
3627 ok( res == ERROR_SUCCESS, "got %d\n", res );
3628
3629 /* user managed product key exists */
3630 size = MAX_PATH;
3631 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
3632 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3633
3634 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3635 lstrcatA( path_key, "Installer\\UserData\\" );
3636 lstrcatA( path_key, usersid );
3637 lstrcatA( path_key, "\\Components\\" );
3638 lstrcatA( path_key, comp_squashed );
3639
3640 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
3641 ok( res == ERROR_SUCCESS, "got %d\n", res );
3642
3643 /* user managed component key exists */
3644 size = MAX_PATH;
3645 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
3646 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3647
3648 res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
3649 ok( res == ERROR_SUCCESS, "got %d\n", res );
3650
3651 /* product value exists */
3652 path[0] = 0;
3653 size = MAX_PATH;
3654 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
3655 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3656 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3657 ok( size == 20, "got %u\n", size );
3658
3659 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3660 lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Products\\" );
3661 lstrcatA( path_key, prod_squashed );
3662 lstrcatA( path_key, "\\InstallProperties" );
3663
3664 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_installprop, NULL );
3665 ok( res == ERROR_SUCCESS, "got %d\n", res );
3666
3667 val = 1;
3668 res = RegSetValueExA( key_installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(val) );
3669 ok( res == ERROR_SUCCESS, "got %d\n", res );
3670
3671 /* install properties key exists */
3672 path[0] = 0;
3673 size = MAX_PATH;
3674 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
3675 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3676 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3677 ok( size == 20, "got %u\n", size );
3678
3679 create_file( "c:\\testcomponentpath", "C:\\testcomponentpath", 21 );
3680
3681 /* file exists */
3682 path[0] = 0;
3683 size = MAX_PATH;
3684 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_USERMANAGED, path, &size );
3685 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3686 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3687 ok( size == 20, "got %u\n", size );
3688
3689 RegDeleteValueA( key_comp, prod_squashed );
3690 delete_key( key_prod, "", access & KEY_WOW64_64KEY );
3691 delete_key( key_comp, "", access & KEY_WOW64_64KEY );
3692 RegDeleteValueA( key_installprop, "WindowsInstaller" );
3693 delete_key( key_installprop, "", access & KEY_WOW64_64KEY );
3694 RegCloseKey( key_prod );
3695 RegCloseKey( key_comp );
3696 RegCloseKey( key_installprop );
3697 DeleteFileA( "c:\\testcomponentpath" );
3698 lstrcpyA( path_key, "Software\\Classes\\Installer\\Products\\" );
3699 lstrcatA( path_key, prod_squashed );
3700
3701 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_prod, NULL );
3702 ok( res == ERROR_SUCCESS, "got %d\n", res );
3703
3704 /* local classes product key exists */
3705 size = MAX_PATH;
3706 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3707 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3708 todo_wine ok(!size, "got %u\n", size);
3709
3710 lstrcpyA( path_key, "Software\\Microsoft\\Windows\\CurrentVersion\\" );
3711 lstrcatA( path_key, "Installer\\UserData\\S-1-5-18\\Components\\" );
3712 lstrcatA( path_key, comp_squashed );
3713
3714 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, path_key, 0, NULL, 0, access, NULL, &key_comp, NULL );
3715 ok( res == ERROR_SUCCESS, "got %d\n", res );
3716
3717 /* local user component key exists */
3718 size = MAX_PATH;
3719 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3720 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3721 todo_wine ok(!size, "got %u\n", size);
3722
3723 res = RegSetValueExA( key_comp, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\testcomponentpath", 20 );
3724 ok( res == ERROR_SUCCESS, "got %d\n", res );
3725
3726 /* product value exists */
3727 path[0] = 0;
3728 size = MAX_PATH;
3729 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3730 ok( state == INSTALLSTATE_ABSENT, "got %d\n", state );
3731 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3732 ok( size == 20, "got %u\n", size );
3733
3734 create_file( "c:\\testcomponentpath", "c:\\testcomponentpath", 21 );
3735
3736 /* file exists */
3737 path[0] = 0;
3738 size = MAX_PATH;
3739 state = pMsiGetComponentPathExA( prod, comp, NULL, MSIINSTALLCONTEXT_MACHINE, path, &size );
3740 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3741 ok( !lstrcmpA( path, "c:\\testcomponentpath" ), "got %s\n", path );
3742 ok( size == 20, "got %u\n", size );
3743
3744 RegDeleteValueA( key_comp, prod_squashed );
3745 delete_key( key_prod, "", access & KEY_WOW64_64KEY );
3746 delete_key( key_comp, "", access & KEY_WOW64_64KEY );
3747 RegCloseKey( key_prod );
3748 RegCloseKey( key_comp );
3749 DeleteFileA( "c:\\testcomponentpath" );
3750 LocalFree( usersid );
3751 }
3752
3753 static void test_MsiProvideComponent(void)
3754 {
3755 static const WCHAR sourcedirW[] =
3756 {'s','o','u','r','c','e','d','i','r',0};
3757 static const WCHAR productW[] =
3758 {'{','3','8','8','4','7','3','3','8','-','1','B','B','C','-','4','1','0','4','-',
3759 '8','1','A','C','-','2','F','A','A','C','7','E','C','D','D','C','D','}',0};
3760 static const WCHAR componentW[] =
3761 {'{','D','D','4','2','2','F','9','2','-','3','E','D','8','-','4','9','B','5','-',
3762 'A','0','B','7','-','F','2','6','6','F','9','8','3','5','7','D','F','}',0};
3763 INSTALLSTATE state;
3764 char buf[0x100];
3765 WCHAR bufW[0x100];
3766 DWORD len, len2;
3767 UINT r;
3768
3769 if (is_process_limited())
3770 {
3771 skip("process is limited\n");
3772 return;
3773 }
3774
3775 create_test_files();
3776 create_file("msitest\\sourcedir.txt", "msitest\\sourcedir.txt", 1000);
3777 create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
3778
3779 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3780
3781 buf[0] = 0;
3782 len = sizeof(buf);
3783 r = pMsiProvideComponentA("{90120000-0070-0000-0000-4000000FF1CE}",
3784 "{17961602-C4E2-482E-800A-DF6E627549CF}",
3785 "ProductFiles", INSTALLMODE_NODETECTION, buf, &len);
3786 ok(r == ERROR_INVALID_PARAMETER, "got %u\n", r);
3787
3788 r = MsiInstallProductA(msifile, NULL);
3789 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3790
3791 state = MsiQueryFeatureStateA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir");
3792 ok(state == INSTALLSTATE_LOCAL, "got %d\n", state);
3793
3794 buf[0] = 0;
3795 len = sizeof(buf);
3796 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3797 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3798 INSTALLMODE_NODETECTION, buf, &len);
3799 ok(r == ERROR_SUCCESS, "got %u\n", r);
3800 ok(buf[0], "empty path\n");
3801 ok(len == lstrlenA(buf), "got %u\n", len);
3802
3803 len2 = 0;
3804 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3805 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3806 INSTALLMODE_NODETECTION, NULL, &len2);
3807 ok(r == ERROR_SUCCESS, "got %u\n", r);
3808 ok(len2 == len, "got %u\n", len2);
3809
3810 len2 = 0;
3811 r = pMsiProvideComponentA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", "sourcedir",
3812 "{DD422F92-3ED8-49B5-A0B7-F266F98357DF}",
3813 INSTALLMODE_NODETECTION, buf, &len2);
3814 ok(r == ERROR_MORE_DATA, "got %u\n", r);
3815 ok(len2 == len, "got %u\n", len2);
3816
3817 /* wide version */
3818
3819 bufW[0] = 0;
3820 len = sizeof(buf);
3821 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3822 INSTALLMODE_NODETECTION, bufW, &len);
3823 ok(r == ERROR_SUCCESS, "got %u\n", r);
3824 ok(bufW[0], "empty path\n");
3825 ok(len == lstrlenW(bufW), "got %u\n", len);
3826
3827 len2 = 0;
3828 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3829 INSTALLMODE_NODETECTION, NULL, &len2);
3830 ok(r == ERROR_SUCCESS, "got %u\n", r);
3831 ok(len2 == len, "got %u\n", len2);
3832
3833 len2 = 0;
3834 r = pMsiProvideComponentW(productW, sourcedirW, componentW,
3835 INSTALLMODE_NODETECTION, bufW, &len2);
3836 ok(r == ERROR_MORE_DATA, "got %u\n", r);
3837 ok(len2 == len, "got %u\n", len2);
3838
3839 r = MsiInstallProductA(msifile, "REMOVE=ALL");
3840 ok(r == ERROR_SUCCESS, "got %u\n", r);
3841
3842 DeleteFileA("msitest\\sourcedir.txt");
3843 delete_test_files();
3844 DeleteFileA(msifile);
3845 }
3846
3847 static void test_MsiProvideQualifiedComponentEx(void)
3848 {
3849 UINT r;
3850 INSTALLSTATE state;
3851 char comp[39], comp_squashed[33], comp2[39], comp2_base85[21], comp2_squashed[33];
3852 char prod[39], prod_base85[21], prod_squashed[33];
3853 char desc[MAX_PATH], buf[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH];
3854 DWORD len = sizeof(buf);
3855 REGSAM access = KEY_ALL_ACCESS;
3856 HKEY hkey, hkey2, hkey3, hkey4, hkey5;
3857 LONG res;
3858
3859 if (is_process_limited())
3860 {
3861 skip( "process is limited\n" );
3862 return;
3863 }
3864
3865 create_test_guid( comp, comp_squashed );
3866 compose_base85_guid( comp2, comp2_base85, comp2_squashed );
3867 compose_base85_guid( prod, prod_base85, prod_squashed );
3868
3869 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3870 ok( r == ERROR_UNKNOWN_COMPONENT, "got %u\n", r );
3871
3872 lstrcpyA( keypath, "Software\\Classes\\Installer\\Components\\" );
3873 lstrcatA( keypath, comp_squashed );
3874
3875 if (is_wow64) access |= KEY_WOW64_64KEY;
3876 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey, NULL );
3877 ok( res == ERROR_SUCCESS, "got %d\n", res );
3878
3879 lstrcpyA( desc, prod_base85 );
3880 memcpy( desc + lstrlenA(desc), "feature<\0", sizeof("feature<\0") );
3881 res = RegSetValueExA( hkey, "qualifier", 0, REG_MULTI_SZ, (const BYTE *)desc,
3882 lstrlenA(prod_base85) + sizeof("feature<\0") );
3883 ok( res == ERROR_SUCCESS, "got %d\n", res );
3884
3885 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3886 ok( r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r );
3887
3888 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, NULL, 0, 0, buf, &len );
3889 ok( r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r );
3890
3891 state = MsiQueryProductStateA( prod );
3892 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3893
3894 lstrcpyA( keypath, "Software\\Classes\\Installer\\Products\\" );
3895 lstrcatA( keypath, prod_squashed );
3896
3897 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey2, NULL );
3898 ok( res == ERROR_SUCCESS, "got %d\n", res );
3899
3900 state = MsiQueryProductStateA( prod );
3901 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3902
3903 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3904 todo_wine ok( r == ERROR_UNKNOWN_FEATURE, "got %u\n", r );
3905
3906 lstrcpyA( keypath, "Software\\Classes\\Installer\\Features\\" );
3907 lstrcatA( keypath, prod_squashed );
3908
3909 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey3, NULL );
3910 ok( res == ERROR_SUCCESS, "got %d\n", res );
3911
3912 state = MsiQueryFeatureStateA( prod, "feature" );
3913 ok( state == INSTALLSTATE_UNKNOWN, "got %d\n", state );
3914
3915 res = RegSetValueExA( hkey3, "feature", 0, REG_SZ, (const BYTE *)"", 1 );
3916 ok( res == ERROR_SUCCESS, "got %d\n", res );
3917
3918 state = MsiQueryFeatureStateA( prod, "feature" );
3919 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3920
3921 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3922 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3923
3924 len = sizeof(buf);
3925 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, NULL, 0, 0, buf, &len );
3926 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3927
3928 lstrcpyA( keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\" );
3929 lstrcatA( keypath, prod_squashed );
3930 lstrcatA( keypath, "\\Features" );
3931
3932 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey4, NULL );
3933 ok( res == ERROR_SUCCESS, "got %d\n", res );
3934
3935 res = RegSetValueExA( hkey4, "feature", 0, REG_SZ, (const BYTE *)comp2_base85, sizeof(comp2_base85) );
3936 ok( res == ERROR_SUCCESS, "got %d\n", res );
3937
3938 state = MsiQueryFeatureStateA( prod, "feature" );
3939 ok( state == INSTALLSTATE_ADVERTISED, "got %d\n", state );
3940
3941 lstrcpyA( keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\" );
3942 lstrcatA( keypath, comp2_squashed );
3943
3944 res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey5, NULL );
3945 ok( res == ERROR_SUCCESS, "got %d\n", res );
3946
3947 res = RegSetValueExA( hkey5, prod_squashed, 0, REG_SZ, (const BYTE *)"c:\\nosuchfile", sizeof("c:\\nosuchfile") );
3948 ok( res == ERROR_SUCCESS, "got %d\n", res );
3949
3950 state = MsiQueryFeatureStateA( prod, "feature" );
3951 ok( state == INSTALLSTATE_LOCAL, "got %d\n", state );
3952
3953 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3954 ok( r == ERROR_FILE_NOT_FOUND, "got %u\n", r );
3955
3956 GetCurrentDirectoryA( MAX_PATH, path );
3957 lstrcatA( path, "\\msitest" );
3958 CreateDirectoryA( path, NULL );
3959 lstrcatA( path, "\\test.txt" );
3960 create_file( path, "test", 100 );
3961
3962 res = RegSetValueExA( hkey5, prod_squashed, 0, REG_SZ, (const BYTE *)path, lstrlenA(path) + 1 );
3963 ok( res == ERROR_SUCCESS, "got %d\n", res );
3964
3965 buf[0] = 0;
3966 len = sizeof(buf);
3967 r = MsiProvideQualifiedComponentExA( comp, "qualifier", INSTALLMODE_EXISTING, prod, 0, 0, buf, &len );
3968 ok( r == ERROR_SUCCESS, "got %u\n", r );
3969 ok( len == lstrlenA(path), "got %u\n", len );
3970 ok( !lstrcmpA( path, buf ), "got '%s'\n", buf );
3971
3972 DeleteFileA( "msitest\\text.txt" );
3973 RemoveDirectoryA( "msitest" );
3974
3975 delete_key( hkey5, "", access & KEY_WOW64_64KEY );
3976 RegCloseKey( hkey5 );
3977 delete_key( hkey4, "", access & KEY_WOW64_64KEY );
3978 RegCloseKey( hkey4 );
3979 delete_key( hkey3, "", access & KEY_WOW64_64KEY );
3980 RegCloseKey( hkey3 );
3981 delete_key( hkey2, "", access & KEY_WOW64_64KEY );
3982 RegCloseKey( hkey2 );
3983 delete_key( hkey, "", access & KEY_WOW64_64KEY );
3984 RegCloseKey( hkey );
3985 }
3986
3987 static void test_MsiGetProductCode(void)
3988 {
3989 HKEY compkey, prodkey;
3990 CHAR prodcode[MAX_PATH];
3991 CHAR prod_squashed[MAX_PATH];
3992 CHAR prodcode2[MAX_PATH];
3993 CHAR prod2_squashed[MAX_PATH];
3994 CHAR component[MAX_PATH];
3995 CHAR comp_base85[MAX_PATH];
3996 CHAR comp_squashed[MAX_PATH];
3997 CHAR keypath[MAX_PATH];
3998 CHAR product[MAX_PATH];
3999 LPSTR usersid;
4000 LONG res;
4001 UINT r;
4002 REGSAM access = KEY_ALL_ACCESS;
4003
4004 create_test_guid(prodcode, prod_squashed);
4005 create_test_guid(prodcode2, prod2_squashed);
4006 compose_base85_guid(component, comp_base85, comp_squashed);
4007 usersid = get_user_sid();
4008
4009 if (is_wow64)
4010 access |= KEY_WOW64_64KEY;
4011
4012 /* szComponent is NULL */
4013 lstrcpyA(product, "prod");
4014 r = MsiGetProductCodeA(NULL, product);
4015 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4016 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4017
4018 /* szComponent is empty */
4019 lstrcpyA(product, "prod");
4020 r = MsiGetProductCodeA("", product);
4021 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4022 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4023
4024 /* garbage szComponent */
4025 lstrcpyA(product, "prod");
4026 r = MsiGetProductCodeA("garbage", product);
4027 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4028 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4029
4030 /* guid without brackets */
4031 lstrcpyA(product, "prod");
4032 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
4033 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4034 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4035
4036 /* guid with brackets */
4037 lstrcpyA(product, "prod");
4038 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
4039 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4040 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4041
4042 /* same length as guid, but random */
4043 lstrcpyA(product, "prod");
4044 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
4045 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4046 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4047
4048 /* all params correct, szComponent not published */
4049 lstrcpyA(product, "prod");
4050 r = MsiGetProductCodeA(component, product);
4051 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4052 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4053
4054 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4055 lstrcatA(keypath, "Installer\\UserData\\");
4056 lstrcatA(keypath, usersid);
4057 lstrcatA(keypath, "\\Components\\");
4058 lstrcatA(keypath, comp_squashed);
4059
4060 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
4061 if (res == ERROR_ACCESS_DENIED)
4062 {
4063 skip("Not enough rights to perform tests\n");
4064 LocalFree(usersid);
4065 return;
4066 }
4067 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4068
4069 /* user unmanaged component key exists */
4070 lstrcpyA(product, "prod");
4071 r = MsiGetProductCodeA(component, product);
4072 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4073 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4074
4075 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
4076 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4077
4078 /* product value exists */
4079 lstrcpyA(product, "prod");
4080 r = MsiGetProductCodeA(component, product);
4081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4082 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4083
4084 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
4085 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4086
4087 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4088 lstrcatA(keypath, "Installer\\Managed\\");
4089 lstrcatA(keypath, usersid);
4090 lstrcatA(keypath, "\\Installer\\Products\\");
4091 lstrcatA(keypath, prod_squashed);
4092
4093 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4094 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4095
4096 /* user managed product key of first product exists */
4097 lstrcpyA(product, "prod");
4098 r = MsiGetProductCodeA(component, product);
4099 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4100 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4101
4102 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4103 RegCloseKey(prodkey);
4104
4105 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4106 lstrcatA(keypath, prod_squashed);
4107
4108 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4109 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4110
4111 /* user unmanaged product key exists */
4112 lstrcpyA(product, "prod");
4113 r = MsiGetProductCodeA(component, product);
4114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4115 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4116
4117 RegDeleteKeyA(prodkey, "");
4118 RegCloseKey(prodkey);
4119
4120 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
4121 lstrcatA(keypath, prod_squashed);
4122
4123 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4124 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4125
4126 /* local classes product key exists */
4127 lstrcpyA(product, "prod");
4128 r = MsiGetProductCodeA(component, product);
4129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4130 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4131
4132 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4133 RegCloseKey(prodkey);
4134
4135 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4136 lstrcatA(keypath, "Installer\\Managed\\");
4137 lstrcatA(keypath, usersid);
4138 lstrcatA(keypath, "\\Installer\\Products\\");
4139 lstrcatA(keypath, prod2_squashed);
4140
4141 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4142 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4143
4144 /* user managed product key of second product exists */
4145 lstrcpyA(product, "prod");
4146 r = MsiGetProductCodeA(component, product);
4147 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4148 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
4149
4150 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4151 RegCloseKey(prodkey);
4152 RegDeleteValueA(compkey, prod_squashed);
4153 RegDeleteValueA(compkey, prod2_squashed);
4154 delete_key(compkey, "", access & KEY_WOW64_64KEY);
4155 RegCloseKey(compkey);
4156
4157 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4158 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
4159 lstrcatA(keypath, comp_squashed);
4160
4161 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
4162 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4163
4164 /* local user component key exists */
4165 lstrcpyA(product, "prod");
4166 r = MsiGetProductCodeA(component, product);
4167 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4168 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
4169
4170 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
4171 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4172
4173 /* product value exists */
4174 lstrcpyA(product, "prod");
4175 r = MsiGetProductCodeA(component, product);
4176 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4177 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4178
4179 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
4180 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4181
4182 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4183 lstrcatA(keypath, "Installer\\Managed\\");
4184 lstrcatA(keypath, usersid);
4185 lstrcatA(keypath, "\\Installer\\Products\\");
4186 lstrcatA(keypath, prod_squashed);
4187
4188 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4190
4191 /* user managed product key of first product exists */
4192 lstrcpyA(product, "prod");
4193 r = MsiGetProductCodeA(component, product);
4194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4195 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4196
4197 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4198 RegCloseKey(prodkey);
4199
4200 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4201 lstrcatA(keypath, prod_squashed);
4202
4203 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4204 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4205
4206 /* user unmanaged product key exists */
4207 lstrcpyA(product, "prod");
4208 r = MsiGetProductCodeA(component, product);
4209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4210 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4211
4212 RegDeleteKeyA(prodkey, "");
4213 RegCloseKey(prodkey);
4214
4215 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
4216 lstrcatA(keypath, prod_squashed);
4217
4218 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4219 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4220
4221 /* local classes product key exists */
4222 lstrcpyA(product, "prod");
4223 r = MsiGetProductCodeA(component, product);
4224 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4225 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4226
4227 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4228 RegCloseKey(prodkey);
4229
4230 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4231 lstrcatA(keypath, "Installer\\Managed\\");
4232 lstrcatA(keypath, usersid);
4233 lstrcatA(keypath, "\\Installer\\Products\\");
4234 lstrcatA(keypath, prod2_squashed);
4235
4236 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4238
4239 /* user managed product key of second product exists */
4240 lstrcpyA(product, "prod");
4241 r = MsiGetProductCodeA(component, product);
4242 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4243 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
4244
4245 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4246 RegCloseKey(prodkey);
4247 RegDeleteValueA(compkey, prod_squashed);
4248 RegDeleteValueA(compkey, prod2_squashed);
4249 delete_key(compkey, "", access & KEY_WOW64_64KEY);
4250 RegCloseKey(compkey);
4251 LocalFree(usersid);
4252 }
4253
4254 static void test_MsiEnumClients(void)
4255 {
4256 HKEY compkey;
4257 CHAR prodcode[MAX_PATH];
4258 CHAR prod_squashed[MAX_PATH];
4259 CHAR prodcode2[MAX_PATH];
4260 CHAR prod2_squashed[MAX_PATH];
4261 CHAR component[MAX_PATH];
4262 CHAR comp_base85[MAX_PATH];
4263 CHAR comp_squashed[MAX_PATH];
4264 CHAR product[MAX_PATH];
4265 CHAR keypath[MAX_PATH];
4266 LPSTR usersid;
4267 LONG res;
4268 UINT r;
4269 REGSAM access = KEY_ALL_ACCESS;
4270
4271 create_test_guid(prodcode, prod_squashed);
4272 create_test_guid(prodcode2, prod2_squashed);
4273 compose_base85_guid(component, comp_base85, comp_squashed);
4274 usersid = get_user_sid();
4275
4276 if (is_wow64)
4277 access |= KEY_WOW64_64KEY;
4278
4279 /* NULL szComponent */
4280 product[0] = '\0';
4281 r = MsiEnumClientsA(NULL, 0, product);
4282 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4283 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4284
4285 /* empty szComponent */
4286 product[0] = '\0';
4287 r = MsiEnumClientsA("", 0, product);
4288 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4289 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4290
4291 /* NULL lpProductBuf */
4292 r = MsiEnumClientsA(component, 0, NULL);
4293 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4294
4295 /* all params correct, component missing */
4296 product[0] = '\0';
4297 r = MsiEnumClientsA(component, 0, product);
4298 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4299 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4300
4301 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4302 lstrcatA(keypath, "Installer\\UserData\\");
4303 lstrcatA(keypath, usersid);
4304 lstrcatA(keypath, "\\Components\\");
4305 lstrcatA(keypath, comp_squashed);
4306
4307 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
4308 if (res == ERROR_ACCESS_DENIED)
4309 {
4310 skip("Not enough rights to perform tests\n");
4311 LocalFree(usersid);
4312 return;
4313 }
4314 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4315
4316 /* user unmanaged component key exists */
4317 product[0] = '\0';
4318 r = MsiEnumClientsA(component, 0, product);
4319 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4320 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4321
4322 /* index > 0, no products exist */
4323 product[0] = '\0';
4324 r = MsiEnumClientsA(component, 1, product);
4325 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4326 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4327
4328 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
4329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4330
4331 /* product value exists */
4332 r = MsiEnumClientsA(component, 0, product);
4333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4334 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4335
4336 /* try index 0 again */
4337 product[0] = '\0';
4338 r = MsiEnumClientsA(component, 0, product);
4339 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4340 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4341
4342 /* try index 1, second product value does not exist */
4343 product[0] = '\0';
4344 r = MsiEnumClientsA(component, 1, product);
4345 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4346 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4347
4348 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
4349 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4350
4351 /* try index 1, second product value does exist */
4352 product[0] = '\0';
4353 r = MsiEnumClientsA(component, 1, product);
4354 todo_wine
4355 {
4356 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4357 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4358 }
4359
4360 /* start the enumeration over */
4361 product[0] = '\0';
4362 r = MsiEnumClientsA(component, 0, product);
4363 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4364 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4365 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4366
4367 /* correctly query second product */
4368 product[0] = '\0';
4369 r = MsiEnumClientsA(component, 1, product);
4370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4371 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4372 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4373
4374 RegDeleteValueA(compkey, prod_squashed);
4375 RegDeleteValueA(compkey, prod2_squashed);
4376 delete_key(compkey, "", access & KEY_WOW64_64KEY);
4377 RegCloseKey(compkey);
4378
4379 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4380 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
4381 lstrcatA(keypath, comp_squashed);
4382
4383 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
4384 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4385
4386 /* user local component key exists */
4387 product[0] = '\0';
4388 r = MsiEnumClientsA(component, 0, product);
4389 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4390 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4391
4392 /* index > 0, no products exist */
4393 product[0] = '\0';
4394 r = MsiEnumClientsA(component, 1, product);
4395 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4396 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4397
4398 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
4399 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4400
4401 /* product value exists */
4402 product[0] = '\0';
4403 r = MsiEnumClientsA(component, 0, product);
4404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4405 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4406
4407 /* try index 0 again */
4408 product[0] = '\0';
4409 r = MsiEnumClientsA(component, 0, product);
4410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4411
4412 /* try index 1, second product value does not exist */
4413 product[0] = '\0';
4414 r = MsiEnumClientsA(component, 1, product);
4415 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4416 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4417
4418 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
4419 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4420
4421 /* try index 1, second product value does exist */
4422 product[0] = '\0';
4423 r = MsiEnumClientsA(component, 1, product);
4424 todo_wine
4425 {
4426 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4427 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4428 }
4429
4430 /* start the enumeration over */
4431 product[0] = '\0';
4432 r = MsiEnumClientsA(component, 0, product);
4433 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4434 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4435 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4436
4437 /* correctly query second product */
4438 product[0] = '\0';
4439 r = MsiEnumClientsA(component, 1, product);
4440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4441 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4442 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4443
4444 RegDeleteValueA(compkey, prod_squashed);
4445 RegDeleteValueA(compkey, prod2_squashed);
4446 delete_key(compkey, "", access & KEY_WOW64_64KEY);
4447 RegCloseKey(compkey);
4448 LocalFree(usersid);
4449 }
4450
4451 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
4452 LPSTR *langcheck, LPDWORD langchecksz)
4453 {
4454 LPSTR version;
4455 VS_FIXEDFILEINFO *ffi;
4456 DWORD size = GetFileVersionInfoSizeA(path, NULL);
4457 USHORT *lang;
4458
4459 version = HeapAlloc(GetProcessHeap(), 0, size);
4460 GetFileVersionInfoA(path, 0, size, version);
4461
4462 VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
4463 *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
4464 sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
4465 LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
4466 LOWORD(ffi->dwFileVersionLS));
4467 *verchecksz = lstrlenA(*vercheck);
4468
4469 VerQueryValueA(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
4470 *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
4471 sprintf(*langcheck, "%d", *lang);
4472 *langchecksz = lstrlenA(*langcheck);
4473
4474 HeapFree(GetProcessHeap(), 0, version);
4475 }
4476
4477 static void test_MsiGetFileVersion(void)
4478 {
4479 UINT r;
4480 DWORD versz, langsz;
4481 char version[MAX_PATH];
4482 char lang[MAX_PATH];
4483 char path[MAX_PATH];
4484 LPSTR vercheck, langcheck;
4485 DWORD verchecksz, langchecksz;
4486
4487 /* NULL szFilePath */
4488 r = MsiGetFileVersionA(NULL, NULL, NULL, NULL, NULL);
4489 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4490
4491 versz = MAX_PATH;
4492 langsz = MAX_PATH;
4493 lstrcpyA(version, "version");
4494 lstrcpyA(lang, "lang");
4495 r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
4496 ok(r == ERROR_INVALID_PARAMETER,
4497 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4498 ok(!lstrcmpA(version, "version"),
4499 "Expected version to be unchanged, got %s\n", version);
4500 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4501 ok(!lstrcmpA(lang, "lang"),
4502 "Expected lang to be unchanged, got %s\n", lang);
4503 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4504
4505 /* empty szFilePath */
4506 r = MsiGetFileVersionA("", NULL, NULL, NULL, NULL);
4507 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4508
4509 versz = MAX_PATH;
4510 langsz = MAX_PATH;
4511 lstrcpyA(version, "version");
4512 lstrcpyA(lang, "lang");
4513 r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
4514 ok(r == ERROR_FILE_NOT_FOUND,
4515 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4516 ok(!lstrcmpA(version, "version"),
4517 "Expected version to be unchanged, got %s\n", version);
4518 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4519 ok(!lstrcmpA(lang, "lang"),
4520 "Expected lang to be unchanged, got %s\n", lang);
4521 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4522
4523 /* nonexistent szFilePath */
4524 versz = MAX_PATH;
4525 langsz = MAX_PATH;
4526 lstrcpyA(version, "version");
4527 lstrcpyA(lang, "lang");
4528 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4529 ok(r == ERROR_FILE_NOT_FOUND,
4530 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4531 ok(!lstrcmpA(version, "version"),
4532 "Expected version to be unchanged, got %s\n", version);
4533 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4534 ok(!lstrcmpA(lang, "lang"),
4535 "Expected lang to be unchanged, got %s\n", lang);
4536 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4537
4538 /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
4539 versz = MAX_PATH;
4540 langsz = MAX_PATH;
4541 lstrcpyA(version, "version");
4542 lstrcpyA(lang, "lang");
4543 r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
4544 ok(r == ERROR_INVALID_PARAMETER,
4545 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4546 ok(!lstrcmpA(version, "version"),
4547 "Expected version to be unchanged, got %s\n", version);
4548 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4549 ok(!lstrcmpA(lang, "lang"),
4550 "Expected lang to be unchanged, got %s\n", lang);
4551 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4552
4553 /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
4554 versz = MAX_PATH;
4555 langsz = MAX_PATH;
4556 lstrcpyA(version, "version");
4557 lstrcpyA(lang, "lang");
4558 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
4559 ok(r == ERROR_INVALID_PARAMETER,
4560 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4561 ok(!lstrcmpA(version, "version"),
4562 "Expected version to be unchanged, got %s\n", version);
4563 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4564 ok(!lstrcmpA(lang, "lang"),
4565 "Expected lang to be unchanged, got %s\n", lang);
4566 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4567
4568 /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
4569 versz = 0;
4570 langsz = MAX_PATH;
4571 lstrcpyA(version, "version");
4572 lstrcpyA(lang, "lang");
4573 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4574 ok(r == ERROR_FILE_NOT_FOUND,
4575 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4576 ok(!lstrcmpA(version, "version"),
4577 "Expected version to be unchanged, got %s\n", version);
4578 ok(versz == 0, "Expected 0, got %d\n", versz);
4579 ok(!lstrcmpA(lang, "lang"),
4580 "Expected lang to be unchanged, got %s\n", lang);
4581 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4582
4583 /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
4584 versz = MAX_PATH;
4585 langsz = 0;
4586 lstrcpyA(version, "version");
4587 lstrcpyA(lang, "lang");
4588 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
4589 ok(r == ERROR_FILE_NOT_FOUND,
4590 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4591 ok(!lstrcmpA(version, "version"),
4592 "Expected version to be unchanged, got %s\n", version);
4593 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4594 ok(!lstrcmpA(lang, "lang"),
4595 "Expected lang to be unchanged, got %s\n", lang);
4596 ok(langsz == 0, "Expected 0, got %d\n", langsz);
4597
4598 /* nonexistent szFilePath, rest NULL */
4599 r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
4600 ok(r == ERROR_FILE_NOT_FOUND,
4601 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4602
4603 create_file("ver.txt", "ver.txt", 20);
4604
4605 /* file exists, no version information */
4606 r = MsiGetFileVersionA("ver.txt", NULL, NULL, NULL, NULL);
4607 ok(r == ERROR_FILE_INVALID, "Expected ERROR_FILE_INVALID, got %d\n", r);
4608
4609 versz = MAX_PATH;
4610 langsz = MAX_PATH;
4611 lstrcpyA(version, "version");
4612 lstrcpyA(lang, "lang");
4613 r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
4614 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4615 ok(!lstrcmpA(version, "version"),
4616 "Expected version to be unchanged, got %s\n", version);
4617 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4618 ok(!lstrcmpA(lang, "lang"),
4619 "Expected lang to be unchanged, got %s\n", lang);
4620 ok(r == ERROR_FILE_INVALID,
4621 "Expected ERROR_FILE_INVALID, got %d\n", r);
4622
4623 DeleteFileA("ver.txt");
4624
4625 /* relative path, has version information */
4626 versz = MAX_PATH;
4627 langsz = MAX_PATH;
4628 lstrcpyA(version, "version");
4629 lstrcpyA(lang, "lang");
4630 r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
4631 todo_wine
4632 {
4633 ok(r == ERROR_FILE_NOT_FOUND,
4634 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
4635 ok(!lstrcmpA(version, "version"),
4636 "Expected version to be unchanged, got %s\n", version);
4637 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
4638 ok(!lstrcmpA(lang, "lang"),
4639 "Expected lang to be unchanged, got %s\n", lang);
4640 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
4641 }
4642
4643 GetSystemDirectoryA(path, MAX_PATH);
4644 lstrcatA(path, "\\kernel32.dll");
4645
4646 get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
4647
4648 /* absolute path, has version information */
4649 versz = MAX_PATH;
4650 langsz = MAX_PATH;
4651 lstrcpyA(version, "version");
4652 lstrcpyA(lang, "lang");
4653 r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
4654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4655 if (langchecksz && !langsz)
4656 {
4657 win_skip("broken MsiGetFileVersionA detected\n");
4658 HeapFree(GetProcessHeap(), 0, vercheck);
4659 HeapFree(GetProcessHeap(), 0, langcheck);
4660 return;
4661 }
4662 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4663 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4664 ok(!lstrcmpA(version, vercheck),
4665 "Expected %s, got %s\n", vercheck, version);
4666
4667 /* only check version */
4668 versz = MAX_PATH;
4669 lstrcpyA(version, "version");
4670 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4672 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4673 ok(!lstrcmpA(version, vercheck),
4674 "Expected %s, got %s\n", vercheck, version);
4675
4676 /* only check language */
4677 langsz = MAX_PATH;
4678 lstrcpyA(lang, "lang");
4679 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4680 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4681 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4682
4683 /* check neither version nor language */
4684 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4685 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4686
4687 /* get pcchVersionBuf */
4688 versz = MAX_PATH;
4689 r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
4690 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4691 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4692
4693 /* get pcchLangBuf */
4694 langsz = MAX_PATH;
4695 r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
4696 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4697 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4698
4699 /* pcchVersionBuf not big enough */
4700 versz = 5;
4701 lstrcpyA(version, "version");
4702 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4703 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4704 ok(!strncmp(version, vercheck, 4),
4705 "Expected first 4 characters of \"%s\", got \"%s\"\n", vercheck, version);
4706 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4707
4708 /* pcchLangBuf not big enough */
4709 langsz = 4;
4710 lstrcpyA(lang, "lang");
4711 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4712 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4713 ok(lstrcmpA(lang, "lang"), "lang not set\n");
4714 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4715
4716 /* pcchVersionBuf big enough, pcchLangBuf not big enough */
4717 versz = MAX_PATH;
4718 langsz = 0;
4719 lstrcpyA(version, "version");
4720 r = MsiGetFileVersionA(path, version, &versz, NULL, &langsz);
4721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4722 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4723 ok(!lstrcmpA(version, vercheck), "Expected \"%s\", got \"%s\"\n", vercheck, version);
4724 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4725
4726 /* pcchVersionBuf not big enough, pcchLangBuf big enough */
4727 versz = 5;
4728 langsz = MAX_PATH;
4729 lstrcpyA(lang, "lang");
4730 r = MsiGetFileVersionA(path, NULL, &versz, lang, &langsz);
4731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4732 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4733 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4734 ok(strstr(lang, langcheck) != NULL, "expected %s in %s\n", langcheck, lang);
4735
4736 /* NULL pcchVersionBuf and pcchLangBuf */
4737 r = MsiGetFileVersionA(path, version, NULL, lang, NULL);
4738 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4739
4740 /* All NULL except szFilePath */
4741 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4743
4744 HeapFree(GetProcessHeap(), 0, vercheck);
4745 HeapFree(GetProcessHeap(), 0, langcheck);
4746 }
4747
4748 static void test_MsiGetProductInfo(void)
4749 {
4750 UINT r;
4751 LONG res;
4752 HKEY propkey, source;
4753 HKEY prodkey, localkey;
4754 CHAR prodcode[MAX_PATH];
4755 CHAR prod_squashed[MAX_PATH];
4756 CHAR packcode[MAX_PATH];
4757 CHAR pack_squashed[MAX_PATH];
4758 CHAR buf[MAX_PATH];
4759 CHAR keypath[MAX_PATH];
4760 LPSTR usersid;
4761 DWORD sz, val = 42;
4762 REGSAM access = KEY_ALL_ACCESS;
4763
4764 create_test_guid(prodcode, prod_squashed);
4765 create_test_guid(packcode, pack_squashed);
4766 usersid = get_user_sid();
4767
4768 if (is_wow64)
4769 access |= KEY_WOW64_64KEY;
4770
4771 /* NULL szProduct */
4772 sz = MAX_PATH;
4773 lstrcpyA(buf, "apple");
4774 r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4775 ok(r == ERROR_INVALID_PARAMETER,
4776 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4777 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4778 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4779
4780 /* empty szProduct */
4781 sz = MAX_PATH;
4782 lstrcpyA(buf, "apple");
4783 r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4784 ok(r == ERROR_INVALID_PARAMETER,
4785 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4786 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4787 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4788
4789 /* garbage szProduct */
4790 sz = MAX_PATH;
4791 lstrcpyA(buf, "apple");
4792 r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINKA, buf, &sz);
4793 ok(r == ERROR_INVALID_PARAMETER,
4794 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4795 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4796 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4797
4798 /* guid without brackets */
4799 sz = MAX_PATH;
4800 lstrcpyA(buf, "apple");
4801 r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
4802 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4803 ok(r == ERROR_INVALID_PARAMETER,
4804 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4805 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4806 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4807
4808 /* guid with brackets */
4809 sz = MAX_PATH;
4810 lstrcpyA(buf, "apple");
4811 r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
4812 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4813 ok(r == ERROR_UNKNOWN_PRODUCT,
4814 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4815 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4816 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4817
4818 /* same length as guid, but random */
4819 sz = MAX_PATH;
4820 lstrcpyA(buf, "apple");
4821 r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
4822 INSTALLPROPERTY_HELPLINKA, buf, &sz);
4823 ok(r == ERROR_INVALID_PARAMETER,
4824 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4825 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4826 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4827
4828 /* not installed, NULL szAttribute */
4829 sz = MAX_PATH;
4830 lstrcpyA(buf, "apple");
4831 r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
4832 ok(r == ERROR_INVALID_PARAMETER,
4833 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4834 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4835 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4836
4837 /* not installed, NULL lpValueBuf */
4838 sz = MAX_PATH;
4839 lstrcpyA(buf, "apple");
4840 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4841 ok(r == ERROR_UNKNOWN_PRODUCT,
4842 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4843 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4844 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4845
4846 /* not installed, NULL pcchValueBuf */
4847 sz = MAX_PATH;
4848 lstrcpyA(buf, "apple");
4849 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, NULL);
4850 ok(r == ERROR_INVALID_PARAMETER,
4851 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4852 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4853 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4854
4855 /* created guid cannot possibly be an installed product code */
4856 sz = MAX_PATH;
4857 lstrcpyA(buf, "apple");
4858 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4859 ok(r == ERROR_UNKNOWN_PRODUCT,
4860 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4861 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4862 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4863
4864 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4865 lstrcatA(keypath, usersid);
4866 lstrcatA(keypath, "\\Installer\\Products\\");
4867 lstrcatA(keypath, prod_squashed);
4868
4869 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4870 if (res == ERROR_ACCESS_DENIED)
4871 {
4872 skip("Not enough rights to perform tests\n");
4873 LocalFree(usersid);
4874 return;
4875 }
4876 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4877
4878 /* managed product code exists */
4879 sz = MAX_PATH;
4880 lstrcpyA(buf, "apple");
4881 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4882 ok(r == ERROR_UNKNOWN_PROPERTY,
4883 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4884 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4885 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4886
4887 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4888 RegCloseKey(prodkey);
4889
4890 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4891 lstrcatA(keypath, usersid);
4892 lstrcatA(keypath, "\\Products\\");
4893 lstrcatA(keypath, prod_squashed);
4894
4895 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4896 if (res == ERROR_ACCESS_DENIED)
4897 {
4898 skip("Not enough rights to perform tests\n");
4899 LocalFree(usersid);
4900 return;
4901 }
4902 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4903
4904 /* local user product code exists */
4905 sz = MAX_PATH;
4906 lstrcpyA(buf, "apple");
4907 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4908 ok(r == ERROR_UNKNOWN_PRODUCT,
4909 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4910 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4911 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4912
4913 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4914 lstrcatA(keypath, usersid);
4915 lstrcatA(keypath, "\\Installer\\Products\\");
4916 lstrcatA(keypath, prod_squashed);
4917
4918 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4919 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4920
4921 /* both local and managed product code exist */
4922 sz = MAX_PATH;
4923 lstrcpyA(buf, "apple");
4924 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4925 ok(r == ERROR_UNKNOWN_PROPERTY,
4926 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4927 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4928 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4929
4930 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4931 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4932
4933 /* InstallProperties key exists */
4934 sz = MAX_PATH;
4935 lstrcpyA(buf, "apple");
4936 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4937 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4938 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4939 ok(sz == 0, "Expected 0, got %d\n", sz);
4940
4941 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4942 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4943
4944 /* HelpLink value exists */
4945 sz = MAX_PATH;
4946 lstrcpyA(buf, "apple");
4947 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4949 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4950 ok(sz == 4, "Expected 4, got %d\n", sz);
4951
4952 /* pcchBuf is NULL */
4953 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, NULL);
4954 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4955
4956 /* lpValueBuf is NULL */
4957 sz = MAX_PATH;
4958 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4960 ok(sz == 4, "Expected 4, got %d\n", sz);
4961
4962 /* lpValueBuf is NULL, pcchValueBuf is too small */
4963 sz = 2;
4964 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, NULL, &sz);
4965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4966 ok(sz == 4, "Expected 4, got %d\n", sz);
4967
4968 /* lpValueBuf is non-NULL, pcchValueBuf is too small */
4969 sz = 2;
4970 lstrcpyA(buf, "apple");
4971 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4972 ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
4973 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4974 ok(sz == 4, "Expected 4, got %d\n", sz);
4975
4976 /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
4977 sz = 4;
4978 lstrcpyA(buf, "apple");
4979 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
4980 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4981 ok(!lstrcmpA(buf, "apple"),
4982 "Expected buf to remain unchanged, got \"%s\"\n", buf);
4983 ok(sz == 4, "Expected 4, got %d\n", sz);
4984
4985 res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
4986 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4987
4988 /* random property not supported by MSI, value exists */
4989 sz = MAX_PATH;
4990 lstrcpyA(buf, "apple");
4991 r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
4992 ok(r == ERROR_UNKNOWN_PROPERTY,
4993 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4994 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4995 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4996
4997 RegDeleteValueA(propkey, "IMadeThis");
4998 RegDeleteValueA(propkey, "HelpLink");
4999 delete_key(propkey, "", access & KEY_WOW64_64KEY);
5000 delete_key(localkey, "", access & KEY_WOW64_64KEY);
5001 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5002 RegCloseKey(propkey);
5003 RegCloseKey(localkey);
5004 RegCloseKey(prodkey);
5005
5006 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5007 lstrcatA(keypath, prod_squashed);
5008
5009 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5010 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5011
5012 /* user product key exists */
5013 sz = MAX_PATH;
5014 lstrcpyA(buf, "apple");
5015 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5016 ok(r == ERROR_UNKNOWN_PROPERTY,
5017 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5018 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5019 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5020
5021 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5022 lstrcatA(keypath, usersid);
5023 lstrcatA(keypath, "\\Products\\");
5024 lstrcatA(keypath, prod_squashed);
5025
5026 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5028
5029 /* local user product key exists */
5030 sz = MAX_PATH;
5031 lstrcpyA(buf, "apple");
5032 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5033 ok(r == ERROR_UNKNOWN_PROPERTY,
5034 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5035 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5036 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5037
5038 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5039 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5040
5041 /* InstallProperties key exists */
5042 sz = MAX_PATH;
5043 lstrcpyA(buf, "apple");
5044 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5045 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5046 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5047 ok(sz == 0, "Expected 0, got %d\n", sz);
5048
5049 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5050 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5051
5052 /* HelpLink value exists */
5053 sz = MAX_PATH;
5054 lstrcpyA(buf, "apple");
5055 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5056 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5057 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5058 ok(sz == 4, "Expected 4, got %d\n", sz);
5059
5060 RegDeleteValueA(propkey, "HelpLink");
5061 delete_key(propkey, "", access & KEY_WOW64_64KEY);
5062 delete_key(localkey, "", access & KEY_WOW64_64KEY);
5063 RegDeleteKeyA(prodkey, "");
5064 RegCloseKey(propkey);
5065 RegCloseKey(localkey);
5066 RegCloseKey(prodkey);
5067
5068 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
5069 lstrcatA(keypath, prod_squashed);
5070
5071 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
5072 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5073
5074 /* classes product key exists */
5075 sz = MAX_PATH;
5076 lstrcpyA(buf, "apple");
5077 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5078 ok(r == ERROR_UNKNOWN_PROPERTY,
5079 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5080 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5081 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5082
5083 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5084 lstrcatA(keypath, usersid);
5085 lstrcatA(keypath, "\\Products\\");
5086 lstrcatA(keypath, prod_squashed);
5087
5088 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5089 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5090
5091 /* local user product key exists */
5092 sz = MAX_PATH;
5093 lstrcpyA(buf, "apple");
5094 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5095 ok(r == ERROR_UNKNOWN_PROPERTY,
5096 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5097 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5098 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5099
5100 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5101 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5102
5103 /* InstallProperties key exists */
5104 sz = MAX_PATH;
5105 lstrcpyA(buf, "apple");
5106 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5107 ok(r == ERROR_UNKNOWN_PROPERTY,
5108 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5109 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5110 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5111
5112 delete_key(propkey, "", access & KEY_WOW64_64KEY);
5113 delete_key(localkey, "", access & KEY_WOW64_64KEY);
5114 RegCloseKey(propkey);
5115 RegCloseKey(localkey);
5116
5117 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5118 lstrcatA(keypath, "S-1-5-18\\\\Products\\");
5119 lstrcatA(keypath, prod_squashed);
5120
5121 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5122 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5123
5124 /* Local System product key exists */
5125 sz = MAX_PATH;
5126 lstrcpyA(buf, "apple");
5127 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5128 ok(r == ERROR_UNKNOWN_PROPERTY,
5129 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5130 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5131 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5132
5133 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5134 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5135
5136 /* InstallProperties key exists */
5137 sz = MAX_PATH;
5138 lstrcpyA(buf, "apple");
5139 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5140 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5141 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5142 ok(sz == 0, "Expected 0, got %d\n", sz);
5143
5144 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5145 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5146
5147 /* HelpLink value exists */
5148 sz = MAX_PATH;
5149 lstrcpyA(buf, "apple");
5150 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5151 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5152 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5153 ok(sz == 4, "Expected 4, got %d\n", sz);
5154
5155 res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
5156 (const BYTE *)&val, sizeof(DWORD));
5157 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5158
5159 /* HelpLink type is REG_DWORD */
5160 sz = MAX_PATH;
5161 lstrcpyA(buf, "apple");
5162 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINKA, buf, &sz);
5163 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5164 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5165 ok(sz == 2, "Expected 2, got %d\n", sz);
5166
5167 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5168 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5169
5170 /* DisplayName value exists */
5171 sz = MAX_PATH;
5172 lstrcpyA(buf, "apple");
5173 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
5174 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5175 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5176 ok(sz == 4, "Expected 4, got %d\n", sz);
5177
5178 res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
5179 (const BYTE *)&val, sizeof(DWORD));
5180 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5181
5182 /* DisplayName type is REG_DWORD */
5183 sz = MAX_PATH;
5184 lstrcpyA(buf, "apple");
5185 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
5186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5187 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5188 ok(sz == 2, "Expected 2, got %d\n", sz);
5189
5190 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
5191 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5192
5193 /* DisplayVersion value exists */
5194 sz = MAX_PATH;
5195 lstrcpyA(buf, "apple");
5196 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
5197 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5198 ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
5199 ok(sz == 5, "Expected 5, got %d\n", sz);
5200
5201 res = RegSetValueExA(propkey, "DisplayVersion", 0,
5202 REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
5203 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5204
5205 /* DisplayVersion type is REG_DWORD */
5206 sz = MAX_PATH;
5207 lstrcpyA(buf, "apple");
5208 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
5209 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5210 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5211 ok(sz == 2, "Expected 2, got %d\n", sz);
5212
5213 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
5214 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5215
5216 /* HelpTelephone value exists */
5217 sz = MAX_PATH;
5218 lstrcpyA(buf, "apple");
5219 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5221 ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
5222 ok(sz == 4, "Expected 4, got %d\n", sz);
5223
5224 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
5225 (const BYTE *)&val, sizeof(DWORD));
5226 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5227
5228 /* HelpTelephone type is REG_DWORD */
5229 sz = MAX_PATH;
5230 lstrcpyA(buf, "apple");
5231 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
5232 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5233 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5234 ok(sz == 2, "Expected 2, got %d\n", sz);
5235
5236 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5237 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5238
5239 /* InstallLocation value exists */
5240 sz = MAX_PATH;
5241 lstrcpyA(buf, "apple");
5242 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
5243 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5244 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5245 ok(sz == 3, "Expected 3, got %d\n", sz);
5246
5247 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
5248 (const BYTE *)&val, sizeof(DWORD));
5249 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5250
5251 /* InstallLocation type is REG_DWORD */
5252 sz = MAX_PATH;
5253 lstrcpyA(buf, "apple");
5254 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
5255 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5256 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5257 ok(sz == 2, "Expected 2, got %d\n", sz);
5258
5259 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5260 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5261
5262 /* InstallSource value exists */
5263 sz = MAX_PATH;
5264 lstrcpyA(buf, "apple");
5265 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
5266 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5267 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5268 ok(sz == 6, "Expected 6, got %d\n", sz);
5269
5270 res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
5271 (const BYTE *)&val, sizeof(DWORD));
5272 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5273
5274 /* InstallSource type is REG_DWORD */
5275 sz = MAX_PATH;
5276 lstrcpyA(buf, "apple");
5277 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
5278 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5279 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5280 ok(sz == 2, "Expected 2, got %d\n", sz);
5281
5282 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5283 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5284
5285 /* InstallDate value exists */
5286 sz = MAX_PATH;
5287 lstrcpyA(buf, "apple");
5288 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
5289 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5290 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5291 ok(sz == 4, "Expected 4, got %d\n", sz);
5292
5293 res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
5294 (const BYTE *)&val, sizeof(DWORD));
5295 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5296
5297 /* InstallDate type is REG_DWORD */
5298 sz = MAX_PATH;
5299 lstrcpyA(buf, "apple");
5300 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
5301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5302 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5303 ok(sz == 2, "Expected 2, got %d\n", sz);
5304
5305 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5306 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5307
5308 /* Publisher value exists */
5309 sz = MAX_PATH;
5310 lstrcpyA(buf, "apple");
5311 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHERA, buf, &sz);
5312 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5313 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5314 ok(sz == 3, "Expected 3, got %d\n", sz);
5315
5316 res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
5317 (const BYTE *)&val, sizeof(DWORD));
5318 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5319
5320 /* Publisher type is REG_DWORD */
5321 sz = MAX_PATH;
5322 lstrcpyA(buf, "apple");
5323 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHERA, buf, &sz);
5324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5325 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5326 ok(sz == 2, "Expected 2, got %d\n", sz);
5327
5328 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
5329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5330
5331 /* LocalPackage value exists */
5332 sz = MAX_PATH;
5333 lstrcpyA(buf, "apple");
5334 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
5335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5336 ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
5337 ok(sz == 4, "Expected 4, got %d\n", sz);
5338
5339 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
5340 (const BYTE *)&val, sizeof(DWORD));
5341 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5342
5343 /* LocalPackage type is REG_DWORD */
5344 sz = MAX_PATH;
5345 lstrcpyA(buf, "apple");
5346 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
5347 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5348 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5349 ok(sz == 2, "Expected 2, got %d\n", sz);
5350
5351 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5352 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5353
5354 /* UrlInfoAbout value exists */
5355 sz = MAX_PATH;
5356 lstrcpyA(buf, "apple");
5357 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
5358 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5359 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5360 ok(sz == 5, "Expected 5, got %d\n", sz);
5361
5362 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
5363 (const BYTE *)&val, sizeof(DWORD));
5364 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5365
5366 /* UrlInfoAbout type is REG_DWORD */
5367 sz = MAX_PATH;
5368 lstrcpyA(buf, "apple");
5369 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
5370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5371 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5372 ok(sz == 2, "Expected 2, got %d\n", sz);
5373
5374 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
5375 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5376
5377 /* UrlUpdateInfo value exists */
5378 sz = MAX_PATH;
5379 lstrcpyA(buf, "apple");
5380 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
5381 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5382 ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
5383 ok(sz == 4, "Expected 4, got %d\n", sz);
5384
5385 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
5386 (const BYTE *)&val, sizeof(DWORD));
5387 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5388
5389 /* UrlUpdateInfo type is REG_DWORD */
5390 sz = MAX_PATH;
5391 lstrcpyA(buf, "apple");
5392 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
5393 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5394 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5395 ok(sz == 2, "Expected 2, got %d\n", sz);
5396
5397 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
5398 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5399
5400 /* VersionMinor value exists */
5401 sz = MAX_PATH;
5402 lstrcpyA(buf, "apple");
5403 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
5404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5405 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5406 ok(sz == 1, "Expected 1, got %d\n", sz);
5407
5408 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
5409 (const BYTE *)&val, sizeof(DWORD));
5410 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5411
5412 /* VersionMinor type is REG_DWORD */
5413 sz = MAX_PATH;
5414 lstrcpyA(buf, "apple");
5415 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
5416 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5417 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5418 ok(sz == 2, "Expected 2, got %d\n", sz);
5419
5420 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
5421 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5422
5423 /* VersionMajor value exists */
5424 sz = MAX_PATH;
5425 lstrcpyA(buf, "apple");
5426 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
5427 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5428 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5429 ok(sz == 1, "Expected 1, got %d\n", sz);
5430
5431 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
5432 (const BYTE *)&val, sizeof(DWORD));
5433 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5434
5435 /* VersionMajor type is REG_DWORD */
5436 sz = MAX_PATH;
5437 lstrcpyA(buf, "apple");
5438 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
5439 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5440 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5441 ok(sz == 2, "Expected 2, got %d\n", sz);
5442
5443 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5444 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5445
5446 /* ProductID value exists */
5447 sz = MAX_PATH;
5448 lstrcpyA(buf, "apple");
5449 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
5450 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5451 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5452 ok(sz == 2, "Expected 2, got %d\n", sz);
5453
5454 res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
5455 (const BYTE *)&val, sizeof(DWORD));
5456 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5457
5458 /* ProductID type is REG_DWORD */
5459 sz = MAX_PATH;
5460 lstrcpyA(buf, "apple");
5461 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
5462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5463 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5464 ok(sz == 2, "Expected 2, got %d\n", sz);
5465
5466 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5467 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5468
5469 /* RegCompany value exists */
5470 sz = MAX_PATH;
5471 lstrcpyA(buf, "apple");
5472 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
5473 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5474 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5475 ok(sz == 4, "Expected 4, got %d\n", sz);
5476
5477 res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
5478 (const BYTE *)&val, sizeof(DWORD));
5479 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5480
5481 /* RegCompany type is REG_DWORD */
5482 sz = MAX_PATH;
5483 lstrcpyA(buf, "apple");
5484 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
5485 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5486 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5487 ok(sz == 2, "Expected 2, got %d\n", sz);
5488
5489 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
5490 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5491
5492 /* RegOwner value exists */
5493 sz = MAX_PATH;
5494 lstrcpyA(buf, "apple");
5495 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNERA, buf, &sz);
5496 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5497 ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
5498 ok(sz == 3, "Expected 3, got %d\n", sz);
5499
5500 res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
5501 (const BYTE *)&val, sizeof(DWORD));
5502 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5503
5504 /* RegOwner type is REG_DWORD */
5505 sz = MAX_PATH;
5506 lstrcpyA(buf, "apple");
5507 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNERA, buf, &sz);
5508 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5509 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5510 ok(sz == 2, "Expected 2, got %d\n", sz);
5511
5512 res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
5513 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5514
5515 /* InstanceType value exists */
5516 sz = MAX_PATH;
5517 lstrcpyA(buf, "apple");
5518 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5520 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5521 ok(sz == 0, "Expected 0, got %d\n", sz);
5522
5523 res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
5524 (const BYTE *)&val, sizeof(DWORD));
5525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5526
5527 /* InstanceType type is REG_DWORD */
5528 sz = MAX_PATH;
5529 lstrcpyA(buf, "apple");
5530 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5531 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5532 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5533 ok(sz == 0, "Expected 0, got %d\n", sz);
5534
5535 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
5536 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5537
5538 /* InstanceType value exists */
5539 sz = MAX_PATH;
5540 lstrcpyA(buf, "apple");
5541 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5542 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5543 ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
5544 ok(sz == 4, "Expected 4, got %d\n", sz);
5545
5546 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
5547 (const BYTE *)&val, sizeof(DWORD));
5548 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5549
5550 /* InstanceType type is REG_DWORD */
5551 sz = MAX_PATH;
5552 lstrcpyA(buf, "apple");
5553 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPEA, buf, &sz);
5554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5555 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5556 ok(sz == 2, "Expected 2, got %d\n", sz);
5557
5558 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
5559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5560
5561 /* Transforms value exists */
5562 sz = MAX_PATH;
5563 lstrcpyA(buf, "apple");
5564 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5565 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5566 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5567 ok(sz == 0, "Expected 0, got %d\n", sz);
5568
5569 res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
5570 (const BYTE *)&val, sizeof(DWORD));
5571 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5572
5573 /* Transforms type is REG_DWORD */
5574 sz = MAX_PATH;
5575 lstrcpyA(buf, "apple");
5576 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5577 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5578 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5579 ok(sz == 0, "Expected 0, got %d\n", sz);
5580
5581 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
5582 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5583
5584 /* Transforms value exists */
5585 sz = MAX_PATH;
5586 lstrcpyA(buf, "apple");
5587 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5588 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5589 ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
5590 ok(sz == 6, "Expected 6, got %d\n", sz);
5591
5592 res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
5593 (const BYTE *)&val, sizeof(DWORD));
5594 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5595
5596 /* Transforms type is REG_DWORD */
5597 sz = MAX_PATH;
5598 lstrcpyA(buf, "apple");
5599 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
5600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5601 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5602 ok(sz == 2, "Expected 2, got %d\n", sz);
5603
5604 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5605 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5606
5607 /* Language value exists */
5608 sz = MAX_PATH;
5609 lstrcpyA(buf, "apple");
5610 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5612 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5613 ok(sz == 0, "Expected 0, got %d\n", sz);
5614
5615 res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
5616 (const BYTE *)&val, sizeof(DWORD));
5617 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5618
5619 /* Language type is REG_DWORD */
5620 sz = MAX_PATH;
5621 lstrcpyA(buf, "apple");
5622 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5624 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5625 ok(sz == 0, "Expected 0, got %d\n", sz);
5626
5627 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5628 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5629
5630 /* Language value exists */
5631 sz = MAX_PATH;
5632 lstrcpyA(buf, "apple");
5633 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5635 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5636 ok(sz == 4, "Expected 4, got %d\n", sz);
5637
5638 res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
5639 (const BYTE *)&val, sizeof(DWORD));
5640 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5641
5642 /* Language type is REG_DWORD */
5643 sz = MAX_PATH;
5644 lstrcpyA(buf, "apple");
5645 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGEA, buf, &sz);
5646 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5647 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5648 ok(sz == 2, "Expected 2, got %d\n", sz);
5649
5650 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5651 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5652
5653 /* ProductName value exists */
5654 sz = MAX_PATH;
5655 lstrcpyA(buf, "apple");
5656 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5657 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5658 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5659 ok(sz == 0, "Expected 0, got %d\n", sz);
5660
5661 res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
5662 (const BYTE *)&val, sizeof(DWORD));
5663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5664
5665 /* ProductName type is REG_DWORD */
5666 sz = MAX_PATH;
5667 lstrcpyA(buf, "apple");
5668 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5669 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5670 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5671 ok(sz == 0, "Expected 0, got %d\n", sz);
5672
5673 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5674 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5675
5676 /* ProductName value exists */
5677 sz = MAX_PATH;
5678 lstrcpyA(buf, "apple");
5679 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5680 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5681 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5682 ok(sz == 4, "Expected 4, got %d\n", sz);
5683
5684 res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
5685 (const BYTE *)&val, sizeof(DWORD));
5686 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5687
5688 /* ProductName type is REG_DWORD */
5689 sz = MAX_PATH;
5690 lstrcpyA(buf, "apple");
5691 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
5692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5693 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5694 ok(sz == 2, "Expected 2, got %d\n", sz);
5695
5696 res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5698
5699 /* Assignment value exists */
5700 sz = MAX_PATH;
5701 lstrcpyA(buf, "apple");
5702 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5703 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5704 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5705 ok(sz == 0, "Expected 0, got %d\n", sz);
5706
5707 res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
5708 (const BYTE *)&val, sizeof(DWORD));
5709 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5710
5711 /* Assignment type is REG_DWORD */
5712 sz = MAX_PATH;
5713 lstrcpyA(buf, "apple");
5714 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5716 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5717 ok(sz == 0, "Expected 0, got %d\n", sz);
5718
5719 res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5720 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5721
5722 /* Assignment value exists */
5723 sz = MAX_PATH;
5724 lstrcpyA(buf, "apple");
5725 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5726 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5727 ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
5728 ok(sz == 2, "Expected 2, got %d\n", sz);
5729
5730 res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
5731 (const BYTE *)&val, sizeof(DWORD));
5732 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5733
5734 /* Assignment type is REG_DWORD */
5735 sz = MAX_PATH;
5736 lstrcpyA(buf, "apple");
5737 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
5738 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5739 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5740 ok(sz == 2, "Expected 2, got %d\n", sz);
5741
5742 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5743 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5744
5745 /* PackageCode value exists */
5746 sz = MAX_PATH;
5747 lstrcpyA(buf, "apple");
5748 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5749 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5750 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5751 ok(sz == 0, "Expected 0, got %d\n", sz);
5752
5753 res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
5754 (const BYTE *)&val, sizeof(DWORD));
5755 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5756
5757 /* PackageCode type is REG_DWORD */
5758 sz = MAX_PATH;
5759 lstrcpyA(buf, "apple");
5760 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5761 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5762 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5763 ok(sz == 0, "Expected 0, got %d\n", sz);
5764
5765 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5766 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5767
5768 /* PackageCode value exists */
5769 sz = MAX_PATH;
5770 lstrcpyA(buf, "apple");
5771 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5772 ok(r == ERROR_BAD_CONFIGURATION,
5773 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5774 ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
5775 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5776
5777 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
5778 (const BYTE *)&val, sizeof(DWORD));
5779 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5780
5781 /* PackageCode type is REG_DWORD */
5782 sz = MAX_PATH;
5783 lstrcpyA(buf, "apple");
5784 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5786 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5787 ok(sz == 2, "Expected 2, got %d\n", sz);
5788
5789 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
5790 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5791
5792 /* PackageCode value exists */
5793 sz = MAX_PATH;
5794 lstrcpyA(buf, "apple");
5795 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
5796 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5797 ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
5798 ok(sz == 38, "Expected 38, got %d\n", sz);
5799
5800 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5802
5803 /* Version value exists */
5804 sz = MAX_PATH;
5805 lstrcpyA(buf, "apple");
5806 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5807 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5808 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5809 ok(sz == 0, "Expected 0, got %d\n", sz);
5810
5811 res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
5812 (const BYTE *)&val, sizeof(DWORD));
5813 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5814
5815 /* Version type is REG_DWORD */
5816 sz = MAX_PATH;
5817 lstrcpyA(buf, "apple");
5818 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5820 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5821 ok(sz == 0, "Expected 0, got %d\n", sz);
5822
5823 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5824 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5825
5826 /* Version value exists */
5827 sz = MAX_PATH;
5828 lstrcpyA(buf, "apple");
5829 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5830 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5831 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5832 ok(sz == 3, "Expected 3, got %d\n", sz);
5833
5834 res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
5835 (const BYTE *)&val, sizeof(DWORD));
5836 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5837
5838 /* Version type is REG_DWORD */
5839 sz = MAX_PATH;
5840 lstrcpyA(buf, "apple");
5841 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONA, buf, &sz);
5842 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5843 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5844 ok(sz == 2, "Expected 2, got %d\n", sz);
5845
5846 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5847 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5848
5849 /* ProductIcon value exists */
5850 sz = MAX_PATH;
5851 lstrcpyA(buf, "apple");
5852 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5853 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5854 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5855 ok(sz == 0, "Expected 0, got %d\n", sz);
5856
5857 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
5858 (const BYTE *)&val, sizeof(DWORD));
5859 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5860
5861 /* ProductIcon type is REG_DWORD */
5862 sz = MAX_PATH;
5863 lstrcpyA(buf, "apple");
5864 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5865 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5866 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5867 ok(sz == 0, "Expected 0, got %d\n", sz);
5868
5869 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5870 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5871
5872 /* ProductIcon value exists */
5873 sz = MAX_PATH;
5874 lstrcpyA(buf, "apple");
5875 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5876 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5877 ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
5878 ok(sz == 3, "Expected 3, got %d\n", sz);
5879
5880 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
5881 (const BYTE *)&val, sizeof(DWORD));
5882 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5883
5884 /* ProductIcon type is REG_DWORD */
5885 sz = MAX_PATH;
5886 lstrcpyA(buf, "apple");
5887 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
5888 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5889 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5890 ok(sz == 2, "Expected 2, got %d\n", sz);
5891
5892 /* SourceList key does not exist */
5893 sz = MAX_PATH;
5894 lstrcpyA(buf, "apple");
5895 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5896 ok(r == ERROR_UNKNOWN_PRODUCT,
5897 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5898 ok(!lstrcmpA(buf, "apple"),
5899 "Expected buf to be unchanged, got \"%s\"\n", buf);
5900 ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
5901
5902 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
5903 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5904
5905 /* SourceList key exists, but PackageName val does not exist */
5906 sz = MAX_PATH;
5907 lstrcpyA(buf, "apple");
5908 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5909 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5910 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5911 ok(sz == 0, "Expected 0, got %d\n", sz);
5912
5913 res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
5914 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5915
5916 /* PackageName val exists */
5917 sz = MAX_PATH;
5918 lstrcpyA(buf, "apple");
5919 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5920 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5921 ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
5922 ok(sz == 8, "Expected 8, got %d\n", sz);
5923
5924 res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
5925 (const BYTE *)&val, sizeof(DWORD));
5926 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5927
5928 /* PackageName type is REG_DWORD */
5929 sz = MAX_PATH;
5930 lstrcpyA(buf, "apple");
5931 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
5932 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5933 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5934 ok(sz == 2, "Expected 2, got %d\n", sz);
5935
5936 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5937 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5938
5939 /* Authorized value exists */
5940 sz = MAX_PATH;
5941 lstrcpyA(buf, "apple");
5942 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5943 if (r != ERROR_UNKNOWN_PROPERTY)
5944 {
5945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5946 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5947 ok(sz == 0, "Expected 0, got %d\n", sz);
5948 }
5949
5950 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
5951 (const BYTE *)&val, sizeof(DWORD));
5952 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5953
5954 /* AuthorizedLUAApp type is REG_DWORD */
5955 sz = MAX_PATH;
5956 lstrcpyA(buf, "apple");
5957 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5958 if (r != ERROR_UNKNOWN_PROPERTY)
5959 {
5960 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5961 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5962 ok(sz == 0, "Expected 0, got %d\n", sz);
5963 }
5964
5965 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5966 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5967
5968 /* Authorized value exists */
5969 sz = MAX_PATH;
5970 lstrcpyA(buf, "apple");
5971 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5972 if (r != ERROR_UNKNOWN_PROPERTY)
5973 {
5974 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5975 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5976 ok(sz == 4, "Expected 4, got %d\n", sz);
5977 }
5978
5979 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
5980 (const BYTE *)&val, sizeof(DWORD));
5981 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5982
5983 /* AuthorizedLUAApp type is REG_DWORD */
5984 sz = MAX_PATH;
5985 lstrcpyA(buf, "apple");
5986 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
5987 if (r != ERROR_UNKNOWN_PROPERTY)
5988 {
5989 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5990 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5991 ok(sz == 2, "Expected 2, got %d\n", sz);
5992 }
5993
5994 RegDeleteValueA(propkey, "HelpLink");
5995 RegDeleteValueA(propkey, "DisplayName");
5996 RegDeleteValueA(propkey, "DisplayVersion");
5997 RegDeleteValueA(propkey, "HelpTelephone");
5998 RegDeleteValueA(propkey, "InstallLocation");
5999 RegDeleteValueA(propkey, "InstallSource");
6000 RegDeleteValueA(propkey, "InstallDate");
6001 RegDeleteValueA(propkey, "Publisher");
6002 RegDeleteValueA(propkey, "LocalPackage");
6003 RegDeleteValueA(propkey, "UrlInfoAbout");
6004 RegDeleteValueA(propkey, "UrlUpdateInfo");
6005 RegDeleteValueA(propkey, "VersionMinor");
6006 RegDeleteValueA(propkey, "VersionMajor");
6007 RegDeleteValueA(propkey, "ProductID");
6008 RegDeleteValueA(propkey, "RegCompany");
6009 RegDeleteValueA(propkey, "RegOwner");
6010 RegDeleteValueA(propkey, "InstanceType");
6011 RegDeleteValueA(propkey, "Transforms");
6012 RegDeleteValueA(propkey, "Language");
6013 RegDeleteValueA(propkey, "ProductName");
6014 RegDeleteValueA(propkey, "Assignment");
6015 RegDeleteValueA(propkey, "PackageCode");
6016 RegDeleteValueA(propkey, "Version");
6017 RegDeleteValueA(propkey, "ProductIcon");
6018 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6019 delete_key(propkey, "", access & KEY_WOW64_64KEY);
6020 delete_key(localkey, "", access & KEY_WOW64_64KEY);
6021 RegDeleteValueA(prodkey, "InstanceType");
6022 RegDeleteValueA(prodkey, "Transforms");
6023 RegDeleteValueA(prodkey, "Language");
6024 RegDeleteValueA(prodkey, "ProductName");
6025 RegDeleteValueA(prodkey, "Assignment");
6026 RegDeleteValueA(prodkey, "PackageCode");
6027 RegDeleteValueA(prodkey, "Version");
6028 RegDeleteValueA(prodkey, "ProductIcon");
6029 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6030 RegDeleteValueA(source, "PackageName");
6031 delete_key(source, "", access & KEY_WOW64_64KEY);
6032 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6033 RegCloseKey(propkey);
6034 RegCloseKey(localkey);
6035 RegCloseKey(source);
6036 RegCloseKey(prodkey);
6037 LocalFree(usersid);
6038 }
6039
6040 static void test_MsiGetProductInfoEx(void)
6041 {
6042 UINT r;
6043 LONG res;
6044 HKEY propkey, userkey;
6045 HKEY prodkey, localkey;
6046 CHAR prodcode[MAX_PATH];
6047 CHAR prod_squashed[MAX_PATH];
6048 CHAR packcode[MAX_PATH];
6049 CHAR pack_squashed[MAX_PATH];
6050 CHAR buf[MAX_PATH];
6051 CHAR keypath[MAX_PATH];
6052 LPSTR usersid;
6053 DWORD sz;
6054 REGSAM access = KEY_ALL_ACCESS;
6055
6056 if (!pMsiGetProductInfoExA)
6057 {
6058 win_skip("MsiGetProductInfoExA is not available\n");
6059 return;
6060 }
6061
6062 create_test_guid(prodcode, prod_squashed);
6063 create_test_guid(packcode, pack_squashed);
6064 usersid = get_user_sid();
6065
6066 if (is_wow64)
6067 access |= KEY_WOW64_64KEY;
6068
6069 /* NULL szProductCode */
6070 sz = MAX_PATH;
6071 lstrcpyA(buf, "apple");
6072 r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
6073 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6074 ok(r == ERROR_INVALID_PARAMETER,
6075 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6076 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6077 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6078
6079 /* empty szProductCode */
6080 sz = MAX_PATH;
6081 lstrcpyA(buf, "apple");
6082 r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
6083 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6084 ok(r == ERROR_INVALID_PARAMETER,
6085 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6086 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6087 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6088
6089 /* garbage szProductCode */
6090 sz = MAX_PATH;
6091 lstrcpyA(buf, "apple");
6092 r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
6093 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6094 ok(r == ERROR_INVALID_PARAMETER,
6095 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6096 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6097 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6098
6099 /* guid without brackets */
6100 sz = MAX_PATH;
6101 lstrcpyA(buf, "apple");
6102 r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
6103 MSIINSTALLCONTEXT_USERUNMANAGED,
6104 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6105 ok(r == ERROR_INVALID_PARAMETER,
6106 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6107 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6108 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6109
6110 /* guid with brackets */
6111 sz = MAX_PATH;
6112 lstrcpyA(buf, "apple");
6113 r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
6114 MSIINSTALLCONTEXT_USERUNMANAGED,
6115 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6116 ok(r == ERROR_UNKNOWN_PRODUCT,
6117 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6118 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6119 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6120
6121 /* szValue is non-NULL while pcchValue is NULL */
6122 lstrcpyA(buf, "apple");
6123 r = pMsiGetProductInfoExA(prodcode, usersid,
6124 MSIINSTALLCONTEXT_USERUNMANAGED,
6125 INSTALLPROPERTY_PRODUCTSTATEA, buf, NULL);
6126 ok(r == ERROR_INVALID_PARAMETER,
6127 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6128 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6129
6130 /* dwContext is out of range */
6131 sz = MAX_PATH;
6132 lstrcpyA(buf, "apple");
6133 r = pMsiGetProductInfoExA(prodcode, usersid, 42,
6134 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6135 ok(r == ERROR_INVALID_PARAMETER,
6136 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6137 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6138 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6139
6140 /* szProperty is NULL */
6141 sz = MAX_PATH;
6142 lstrcpyA(buf, "apple");
6143 r = pMsiGetProductInfoExA(prodcode, usersid,
6144 MSIINSTALLCONTEXT_USERUNMANAGED,
6145 NULL, buf, &sz);
6146 ok(r == ERROR_INVALID_PARAMETER,
6147 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6148 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6149 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6150
6151 /* szProperty is empty */
6152 sz = MAX_PATH;
6153 lstrcpyA(buf, "apple");
6154 r = pMsiGetProductInfoExA(prodcode, usersid,
6155 MSIINSTALLCONTEXT_USERUNMANAGED,
6156 "", buf, &sz);
6157 ok(r == ERROR_INVALID_PARAMETER,
6158 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6159 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6160 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6161
6162 /* szProperty is not a valid property */
6163 sz = MAX_PATH;
6164 lstrcpyA(buf, "apple");
6165 r = pMsiGetProductInfoExA(prodcode, usersid,
6166 MSIINSTALLCONTEXT_USERUNMANAGED,
6167 "notvalid", buf, &sz);
6168 ok(r == ERROR_UNKNOWN_PRODUCT,
6169 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6170 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6171 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6172
6173 /* same length as guid, but random */
6174 sz = MAX_PATH;
6175 lstrcpyA(buf, "apple");
6176 r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
6177 MSIINSTALLCONTEXT_USERUNMANAGED,
6178 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6179 ok(r == ERROR_INVALID_PARAMETER,
6180 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6181 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6182 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6183
6184 /* MSIINSTALLCONTEXT_USERUNMANAGED */
6185
6186 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
6187 lstrcatA(keypath, usersid);
6188 lstrcatA(keypath, "\\Products\\");
6189 lstrcatA(keypath, prod_squashed);
6190
6191 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6192 if (res == ERROR_ACCESS_DENIED)
6193 {
6194 skip("Not enough rights to perform tests\n");
6195 LocalFree(usersid);
6196 return;
6197 }
6198 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6199
6200 /* local user product key exists */
6201 sz = MAX_PATH;
6202 lstrcpyA(buf, "apple");
6203 r = pMsiGetProductInfoExA(prodcode, usersid,
6204 MSIINSTALLCONTEXT_USERUNMANAGED,
6205 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6206 ok(r == ERROR_UNKNOWN_PRODUCT,
6207 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6208 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6209 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6210
6211 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6213
6214 /* InstallProperties key exists */
6215 sz = MAX_PATH;
6216 lstrcpyA(buf, "apple");
6217 r = pMsiGetProductInfoExA(prodcode, usersid,
6218 MSIINSTALLCONTEXT_USERUNMANAGED,
6219 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6220 ok(r == ERROR_UNKNOWN_PRODUCT,
6221 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6222 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6223 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6224
6225 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6226 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6227
6228 /* LocalPackage value exists */
6229 sz = MAX_PATH;
6230 lstrcpyA(buf, "apple");
6231 r = pMsiGetProductInfoExA(prodcode, usersid,
6232 MSIINSTALLCONTEXT_USERUNMANAGED,
6233 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6234 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6235 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6236 ok(sz == 1, "Expected 1, got %d\n", sz);
6237
6238 RegDeleteValueA(propkey, "LocalPackage");
6239
6240 /* LocalPackage value must exist */
6241 sz = MAX_PATH;
6242 lstrcpyA(buf, "apple");
6243 r = pMsiGetProductInfoExA(prodcode, usersid,
6244 MSIINSTALLCONTEXT_USERUNMANAGED,
6245 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6246 ok(r == ERROR_UNKNOWN_PRODUCT,
6247 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6248 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6249 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6250
6251 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6252 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6253
6254 /* LocalPackage exists, but HelpLink does not exist */
6255 sz = MAX_PATH;
6256 lstrcpyA(buf, "apple");
6257 r = pMsiGetProductInfoExA(prodcode, usersid,
6258 MSIINSTALLCONTEXT_USERUNMANAGED,
6259 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6260 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6261 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6262 ok(sz == 0, "Expected 0, got %d\n", sz);
6263
6264 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6265 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6266
6267 /* HelpLink value exists */
6268 sz = MAX_PATH;
6269 lstrcpyA(buf, "apple");
6270 r = pMsiGetProductInfoExA(prodcode, usersid,
6271 MSIINSTALLCONTEXT_USERUNMANAGED,
6272 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6274 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6275 ok(sz == 4, "Expected 4, got %d\n", sz);
6276
6277 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6279
6280 /* HelpTelephone value exists */
6281 sz = MAX_PATH;
6282 lstrcpyA(buf, "apple");
6283 r = pMsiGetProductInfoExA(prodcode, usersid,
6284 MSIINSTALLCONTEXT_USERUNMANAGED,
6285 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6286 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6287 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6288 ok(sz == 5, "Expected 5, got %d\n", sz);
6289
6290 /* szValue and pcchValue are NULL */
6291 r = pMsiGetProductInfoExA(prodcode, usersid,
6292 MSIINSTALLCONTEXT_USERUNMANAGED,
6293 INSTALLPROPERTY_HELPTELEPHONEA, NULL, NULL);
6294 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6295
6296 /* pcchValue is exactly 5 */
6297 sz = 5;
6298 lstrcpyA(buf, "apple");
6299 r = pMsiGetProductInfoExA(prodcode, usersid,
6300 MSIINSTALLCONTEXT_USERUNMANAGED,
6301 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6302 ok(r == ERROR_MORE_DATA,
6303 "Expected ERROR_MORE_DATA, got %d\n", r);
6304 ok(sz == 10, "Expected 10, got %d\n", sz);
6305
6306 /* szValue is NULL, pcchValue is exactly 5 */
6307 sz = 5;
6308 r = pMsiGetProductInfoExA(prodcode, usersid,
6309 MSIINSTALLCONTEXT_USERUNMANAGED,
6310 INSTALLPROPERTY_HELPTELEPHONEA, NULL, &sz);
6311 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6312 ok(sz == 10, "Expected 10, got %d\n", sz);
6313
6314 /* szValue is NULL, pcchValue is MAX_PATH */
6315 sz = MAX_PATH;
6316 r = pMsiGetProductInfoExA(prodcode, usersid,
6317 MSIINSTALLCONTEXT_USERUNMANAGED,
6318 INSTALLPROPERTY_HELPTELEPHONEA, NULL, &sz);
6319 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6320 ok(sz == 10, "Expected 10, got %d\n", sz);
6321
6322 /* pcchValue is exactly 0 */
6323 sz = 0;
6324 lstrcpyA(buf, "apple");
6325 r = pMsiGetProductInfoExA(prodcode, usersid,
6326 MSIINSTALLCONTEXT_USERUNMANAGED,
6327 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6328 ok(r == ERROR_MORE_DATA,
6329 "Expected ERROR_MORE_DATA, got %d\n", r);
6330 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
6331 ok(sz == 10, "Expected 10, got %d\n", sz);
6332
6333 res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
6334 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6335
6336 /* szProperty is not a valid property */
6337 sz = MAX_PATH;
6338 lstrcpyA(buf, "apple");
6339 r = pMsiGetProductInfoExA(prodcode, usersid,
6340 MSIINSTALLCONTEXT_USERUNMANAGED,
6341 "notvalid", buf, &sz);
6342 ok(r == ERROR_UNKNOWN_PROPERTY,
6343 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6344 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6345 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6346
6347 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6348 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6349
6350 /* InstallDate value exists */
6351 sz = MAX_PATH;
6352 lstrcpyA(buf, "apple");
6353 r = pMsiGetProductInfoExA(prodcode, usersid,
6354 MSIINSTALLCONTEXT_USERUNMANAGED,
6355 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6356 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6357 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6358 ok(sz == 4, "Expected 4, got %d\n", sz);
6359
6360 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6361 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6362
6363 /* DisplayName value exists */
6364 sz = MAX_PATH;
6365 lstrcpyA(buf, "apple");
6366 r = pMsiGetProductInfoExA(prodcode, usersid,
6367 MSIINSTALLCONTEXT_USERUNMANAGED,
6368 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6369 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6370 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6371 ok(sz == 4, "Expected 4, got %d\n", sz);
6372
6373 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6374 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6375
6376 /* InstallLocation value exists */
6377 sz = MAX_PATH;
6378 lstrcpyA(buf, "apple");
6379 r = pMsiGetProductInfoExA(prodcode, usersid,
6380 MSIINSTALLCONTEXT_USERUNMANAGED,
6381 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6382 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6383 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6384 ok(sz == 3, "Expected 3, got %d\n", sz);
6385
6386 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6387 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6388
6389 /* InstallSource value exists */
6390 sz = MAX_PATH;
6391 lstrcpyA(buf, "apple");
6392 r = pMsiGetProductInfoExA(prodcode, usersid,
6393 MSIINSTALLCONTEXT_USERUNMANAGED,
6394 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6395 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6396 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6397 ok(sz == 6, "Expected 6, got %d\n", sz);
6398
6399 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6401
6402 /* LocalPackage value exists */
6403 sz = MAX_PATH;
6404 lstrcpyA(buf, "apple");
6405 r = pMsiGetProductInfoExA(prodcode, usersid,
6406 MSIINSTALLCONTEXT_USERUNMANAGED,
6407 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6409 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6410 ok(sz == 5, "Expected 5, got %d\n", sz);
6411
6412 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6414
6415 /* Publisher value exists */
6416 sz = MAX_PATH;
6417 lstrcpyA(buf, "apple");
6418 r = pMsiGetProductInfoExA(prodcode, usersid,
6419 MSIINSTALLCONTEXT_USERUNMANAGED,
6420 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6421 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6422 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6423 ok(sz == 3, "Expected 3, got %d\n", sz);
6424
6425 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6426 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6427
6428 /* URLInfoAbout value exists */
6429 sz = MAX_PATH;
6430 lstrcpyA(buf, "apple");
6431 r = pMsiGetProductInfoExA(prodcode, usersid,
6432 MSIINSTALLCONTEXT_USERUNMANAGED,
6433 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6434 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6435 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6436 ok(sz == 5, "Expected 5, got %d\n", sz);
6437
6438 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6440
6441 /* URLUpdateInfo value exists */
6442 sz = MAX_PATH;
6443 lstrcpyA(buf, "apple");
6444 r = pMsiGetProductInfoExA(prodcode, usersid,
6445 MSIINSTALLCONTEXT_USERUNMANAGED,
6446 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6447 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6448 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6449 ok(sz == 6, "Expected 6, got %d\n", sz);
6450
6451 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6452 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6453
6454 /* VersionMinor value exists */
6455 sz = MAX_PATH;
6456 lstrcpyA(buf, "apple");
6457 r = pMsiGetProductInfoExA(prodcode, usersid,
6458 MSIINSTALLCONTEXT_USERUNMANAGED,
6459 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6460 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6461 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6462 ok(sz == 1, "Expected 1, got %d\n", sz);
6463
6464 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6465 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6466
6467 /* VersionMajor value exists */
6468 sz = MAX_PATH;
6469 lstrcpyA(buf, "apple");
6470 r = pMsiGetProductInfoExA(prodcode, usersid,
6471 MSIINSTALLCONTEXT_USERUNMANAGED,
6472 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6473 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6474 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6475 ok(sz == 1, "Expected 1, got %d\n", sz);
6476
6477 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6478 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6479
6480 /* DisplayVersion value exists */
6481 sz = MAX_PATH;
6482 lstrcpyA(buf, "apple");
6483 r = pMsiGetProductInfoExA(prodcode, usersid,
6484 MSIINSTALLCONTEXT_USERUNMANAGED,
6485 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6487 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6488 ok(sz == 5, "Expected 5, got %d\n", sz);
6489
6490 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6491 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6492
6493 /* ProductID value exists */
6494 sz = MAX_PATH;
6495 lstrcpyA(buf, "apple");
6496 r = pMsiGetProductInfoExA(prodcode, usersid,
6497 MSIINSTALLCONTEXT_USERUNMANAGED,
6498 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6500 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6501 ok(sz == 2, "Expected 2, got %d\n", sz);
6502
6503 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6504 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6505
6506 /* RegCompany value exists */
6507 sz = MAX_PATH;
6508 lstrcpyA(buf, "apple");
6509 r = pMsiGetProductInfoExA(prodcode, usersid,
6510 MSIINSTALLCONTEXT_USERUNMANAGED,
6511 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6512 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6513 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6514 ok(sz == 4, "Expected 4, got %d\n", sz);
6515
6516 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6517 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6518
6519 /* RegOwner value exists */
6520 sz = MAX_PATH;
6521 lstrcpyA(buf, "apple");
6522 r = pMsiGetProductInfoExA(prodcode, usersid,
6523 MSIINSTALLCONTEXT_USERUNMANAGED,
6524 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6525 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6526 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6527 ok(sz == 5, "Expected 5, got %d\n", sz);
6528
6529 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6530 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6531
6532 /* Transforms value exists */
6533 sz = MAX_PATH;
6534 lstrcpyA(buf, "apple");
6535 r = pMsiGetProductInfoExA(prodcode, usersid,
6536 MSIINSTALLCONTEXT_USERUNMANAGED,
6537 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6538 ok(r == ERROR_UNKNOWN_PRODUCT,
6539 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6540 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6541 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6542
6543 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6544 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6545
6546 /* Language value exists */
6547 sz = MAX_PATH;
6548 lstrcpyA(buf, "apple");
6549 r = pMsiGetProductInfoExA(prodcode, usersid,
6550 MSIINSTALLCONTEXT_USERUNMANAGED,
6551 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6552 ok(r == ERROR_UNKNOWN_PRODUCT,
6553 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6554 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6555 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6556
6557 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6558 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6559
6560 /* ProductName value exists */
6561 sz = MAX_PATH;
6562 lstrcpyA(buf, "apple");
6563 r = pMsiGetProductInfoExA(prodcode, usersid,
6564 MSIINSTALLCONTEXT_USERUNMANAGED,
6565 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6566 ok(r == ERROR_UNKNOWN_PRODUCT,
6567 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6568 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6569 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6570
6571 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6572 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6573
6574 /* FIXME */
6575
6576 /* AssignmentType value exists */
6577 sz = MAX_PATH;
6578 lstrcpyA(buf, "apple");
6579 r = pMsiGetProductInfoExA(prodcode, usersid,
6580 MSIINSTALLCONTEXT_USERUNMANAGED,
6581 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
6582 ok(r == ERROR_UNKNOWN_PRODUCT,
6583 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6584 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6585 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6586
6587 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6588 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6589
6590 /* PackageCode value exists */
6591 sz = MAX_PATH;
6592 lstrcpyA(buf, "apple");
6593 r = pMsiGetProductInfoExA(prodcode, usersid,
6594 MSIINSTALLCONTEXT_USERUNMANAGED,
6595 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
6596 ok(r == ERROR_UNKNOWN_PRODUCT,
6597 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6598 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6599 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6600
6601 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6602 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6603
6604 /* Version value exists */
6605 sz = MAX_PATH;
6606 lstrcpyA(buf, "apple");
6607 r = pMsiGetProductInfoExA(prodcode, usersid,
6608 MSIINSTALLCONTEXT_USERUNMANAGED,
6609 INSTALLPROPERTY_VERSIONA, buf, &sz);
6610 ok(r == ERROR_UNKNOWN_PRODUCT,
6611 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6612 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6613 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6614
6615 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6616 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6617
6618 /* ProductIcon value exists */
6619 sz = MAX_PATH;
6620 lstrcpyA(buf, "apple");
6621 r = pMsiGetProductInfoExA(prodcode, usersid,
6622 MSIINSTALLCONTEXT_USERUNMANAGED,
6623 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
6624 ok(r == ERROR_UNKNOWN_PRODUCT,
6625 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6626 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6627 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6628
6629 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6630 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6631
6632 /* PackageName value exists */
6633 sz = MAX_PATH;
6634 lstrcpyA(buf, "apple");
6635 r = pMsiGetProductInfoExA(prodcode, usersid,
6636 MSIINSTALLCONTEXT_USERUNMANAGED,
6637 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
6638 ok(r == ERROR_UNKNOWN_PRODUCT,
6639 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6640 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6641 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6642
6643 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6644 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6645
6646 /* AuthorizedLUAApp value exists */
6647 sz = MAX_PATH;
6648 lstrcpyA(buf, "apple");
6649 r = pMsiGetProductInfoExA(prodcode, usersid,
6650 MSIINSTALLCONTEXT_USERUNMANAGED,
6651 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
6652 ok(r == ERROR_UNKNOWN_PRODUCT,
6653 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6654 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6655 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6656
6657 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6658 RegDeleteValueA(propkey, "PackageName");
6659 RegDeleteValueA(propkey, "ProductIcon");
6660 RegDeleteValueA(propkey, "Version");
6661 RegDeleteValueA(propkey, "PackageCode");
6662 RegDeleteValueA(propkey, "AssignmentType");
6663 RegDeleteValueA(propkey, "ProductName");
6664 RegDeleteValueA(propkey, "Language");
6665 RegDeleteValueA(propkey, "Transforms");
6666 RegDeleteValueA(propkey, "RegOwner");
6667 RegDeleteValueA(propkey, "RegCompany");
6668 RegDeleteValueA(propkey, "ProductID");
6669 RegDeleteValueA(propkey, "DisplayVersion");
6670 RegDeleteValueA(propkey, "VersionMajor");
6671 RegDeleteValueA(propkey, "VersionMinor");
6672 RegDeleteValueA(propkey, "URLUpdateInfo");
6673 RegDeleteValueA(propkey, "URLInfoAbout");
6674 RegDeleteValueA(propkey, "Publisher");
6675 RegDeleteValueA(propkey, "LocalPackage");
6676 RegDeleteValueA(propkey, "InstallSource");
6677 RegDeleteValueA(propkey, "InstallLocation");
6678 RegDeleteValueA(propkey, "DisplayName");
6679 RegDeleteValueA(propkey, "InstallDate");
6680 RegDeleteValueA(propkey, "HelpTelephone");
6681 RegDeleteValueA(propkey, "HelpLink");
6682 RegDeleteValueA(propkey, "LocalPackage");
6683 RegDeleteKeyA(propkey, "");
6684 RegCloseKey(propkey);
6685 RegDeleteKeyA(localkey, "");
6686 RegCloseKey(localkey);
6687
6688 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6689 lstrcatA(keypath, usersid);
6690 lstrcatA(keypath, "\\Installer\\Products\\");
6691 lstrcatA(keypath, prod_squashed);
6692
6693 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6695
6696 /* user product key exists */
6697 sz = MAX_PATH;
6698 lstrcpyA(buf, "apple");
6699 r = pMsiGetProductInfoExA(prodcode, usersid,
6700 MSIINSTALLCONTEXT_USERUNMANAGED,
6701 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6702 ok(r == ERROR_UNKNOWN_PRODUCT,
6703 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6704 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6705 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6706
6707 RegDeleteKeyA(userkey, "");
6708 RegCloseKey(userkey);
6709
6710 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6711 lstrcatA(keypath, prod_squashed);
6712
6713 res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6714 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6715
6716 sz = MAX_PATH;
6717 lstrcpyA(buf, "apple");
6718 r = pMsiGetProductInfoExA(prodcode, usersid,
6719 MSIINSTALLCONTEXT_USERUNMANAGED,
6720 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
6721 ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
6722 if (r == ERROR_UNKNOWN_PRODUCT)
6723 {
6724 win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
6725 delete_key(prodkey, "", access);
6726 RegCloseKey(prodkey);
6727 return;
6728 }
6729 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6730 ok(sz == 1, "Expected 1, got %d\n", sz);
6731
6732 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6733 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6734
6735 /* HelpLink value exists */
6736 sz = MAX_PATH;
6737 lstrcpyA(buf, "apple");
6738 r = pMsiGetProductInfoExA(prodcode, usersid,
6739 MSIINSTALLCONTEXT_USERUNMANAGED,
6740 INSTALLPROPERTY_HELPLINKA, buf, &sz);
6741 ok(r == ERROR_UNKNOWN_PROPERTY,
6742 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6743 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6744 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6745
6746 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6747 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6748
6749 /* HelpTelephone value exists */
6750 sz = MAX_PATH;
6751 lstrcpyA(buf, "apple");
6752 r = pMsiGetProductInfoExA(prodcode, usersid,
6753 MSIINSTALLCONTEXT_USERUNMANAGED,
6754 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
6755 ok(r == ERROR_UNKNOWN_PROPERTY,
6756 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6757 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6758 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6759
6760 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6761 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6762
6763 /* InstallDate value exists */
6764 sz = MAX_PATH;
6765 lstrcpyA(buf, "apple");
6766 r = pMsiGetProductInfoExA(prodcode, usersid,
6767 MSIINSTALLCONTEXT_USERUNMANAGED,
6768 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
6769 ok(r == ERROR_UNKNOWN_PROPERTY,
6770 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6771 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6772 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6773
6774 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6775 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6776
6777 /* DisplayName value exists */
6778 sz = MAX_PATH;
6779 lstrcpyA(buf, "apple");
6780 r = pMsiGetProductInfoExA(prodcode, usersid,
6781 MSIINSTALLCONTEXT_USERUNMANAGED,
6782 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
6783 ok(r == ERROR_UNKNOWN_PROPERTY,
6784 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6785 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6786 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6787
6788 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6789 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6790
6791 /* InstallLocation value exists */
6792 sz = MAX_PATH;
6793 lstrcpyA(buf, "apple");
6794 r = pMsiGetProductInfoExA(prodcode, usersid,
6795 MSIINSTALLCONTEXT_USERUNMANAGED,
6796 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
6797 ok(r == ERROR_UNKNOWN_PROPERTY,
6798 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6799 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6800 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6801
6802 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6803 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6804
6805 /* InstallSource value exists */
6806 sz = MAX_PATH;
6807 lstrcpyA(buf, "apple");
6808 r = pMsiGetProductInfoExA(prodcode, usersid,
6809 MSIINSTALLCONTEXT_USERUNMANAGED,
6810 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
6811 ok(r == ERROR_UNKNOWN_PROPERTY,
6812 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6813 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6814 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6815
6816 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6817 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6818
6819 /* LocalPackage value exists */
6820 sz = MAX_PATH;
6821 lstrcpyA(buf, "apple");
6822 r = pMsiGetProductInfoExA(prodcode, usersid,
6823 MSIINSTALLCONTEXT_USERUNMANAGED,
6824 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
6825 ok(r == ERROR_UNKNOWN_PROPERTY,
6826 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6827 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6828 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6829
6830 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6832
6833 /* Publisher value exists */
6834 sz = MAX_PATH;
6835 lstrcpyA(buf, "apple");
6836 r = pMsiGetProductInfoExA(prodcode, usersid,
6837 MSIINSTALLCONTEXT_USERUNMANAGED,
6838 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
6839 ok(r == ERROR_UNKNOWN_PROPERTY,
6840 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6841 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6842 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6843
6844 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6845 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6846
6847 /* URLInfoAbout value exists */
6848 sz = MAX_PATH;
6849 lstrcpyA(buf, "apple");
6850 r = pMsiGetProductInfoExA(prodcode, usersid,
6851 MSIINSTALLCONTEXT_USERUNMANAGED,
6852 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
6853 ok(r == ERROR_UNKNOWN_PROPERTY,
6854 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6855 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6856 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6857
6858 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6859 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6860
6861 /* URLUpdateInfo value exists */
6862 sz = MAX_PATH;
6863 lstrcpyA(buf, "apple");
6864 r = pMsiGetProductInfoExA(prodcode, usersid,
6865 MSIINSTALLCONTEXT_USERUNMANAGED,
6866 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
6867 ok(r == ERROR_UNKNOWN_PROPERTY,
6868 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6869 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6870 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6871
6872 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6873 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6874
6875 /* VersionMinor value exists */
6876 sz = MAX_PATH;
6877 lstrcpyA(buf, "apple");
6878 r = pMsiGetProductInfoExA(prodcode, usersid,
6879 MSIINSTALLCONTEXT_USERUNMANAGED,
6880 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
6881 ok(r == ERROR_UNKNOWN_PROPERTY,
6882 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6883 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6884 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6885
6886 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6887 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6888
6889 /* VersionMajor value exists */
6890 sz = MAX_PATH;
6891 lstrcpyA(buf, "apple");
6892 r = pMsiGetProductInfoExA(prodcode, usersid,
6893 MSIINSTALLCONTEXT_USERUNMANAGED,
6894 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
6895 ok(r == ERROR_UNKNOWN_PROPERTY,
6896 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6897 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6898 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6899
6900 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6901 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6902
6903 /* DisplayVersion value exists */
6904 sz = MAX_PATH;
6905 lstrcpyA(buf, "apple");
6906 r = pMsiGetProductInfoExA(prodcode, usersid,
6907 MSIINSTALLCONTEXT_USERUNMANAGED,
6908 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
6909 ok(r == ERROR_UNKNOWN_PROPERTY,
6910 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6911 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6912 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6913
6914 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6915 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6916
6917 /* ProductID value exists */
6918 sz = MAX_PATH;
6919 lstrcpyA(buf, "apple");
6920 r = pMsiGetProductInfoExA(prodcode, usersid,
6921 MSIINSTALLCONTEXT_USERUNMANAGED,
6922 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
6923 ok(r == ERROR_UNKNOWN_PROPERTY,
6924 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6925 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6926 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6927
6928 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6929 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6930
6931 /* RegCompany value exists */
6932 sz = MAX_PATH;
6933 lstrcpyA(buf, "apple");
6934 r = pMsiGetProductInfoExA(prodcode, usersid,
6935 MSIINSTALLCONTEXT_USERUNMANAGED,
6936 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
6937 ok(r == ERROR_UNKNOWN_PROPERTY,
6938 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6939 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6940 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6941
6942 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6943 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6944
6945 /* RegOwner value exists */
6946 sz = MAX_PATH;
6947 lstrcpyA(buf, "apple");
6948 r = pMsiGetProductInfoExA(prodcode, usersid,
6949 MSIINSTALLCONTEXT_USERUNMANAGED,
6950 INSTALLPROPERTY_REGOWNERA, buf, &sz);
6951 ok(r == ERROR_UNKNOWN_PROPERTY,
6952 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6953 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6954 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6955
6956 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6958
6959 /* Transforms value exists */
6960 sz = MAX_PATH;
6961 lstrcpyA(buf, "apple");
6962 r = pMsiGetProductInfoExA(prodcode, usersid,
6963 MSIINSTALLCONTEXT_USERUNMANAGED,
6964 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
6965 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6966 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6967 ok(sz == 5, "Expected 5, got %d\n", sz);
6968
6969 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6970 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6971
6972 /* Language value exists */
6973 sz = MAX_PATH;
6974 lstrcpyA(buf, "apple");
6975 r = pMsiGetProductInfoExA(prodcode, usersid,
6976 MSIINSTALLCONTEXT_USERUNMANAGED,
6977 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
6978 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6979 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6980 ok(sz == 4, "Expected 4, got %d\n", sz);
6981
6982 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6983 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6984
6985 /* ProductName value exists */
6986 sz = MAX_PATH;
6987 lstrcpyA(buf, "apple");
6988 r = pMsiGetProductInfoExA(prodcode, usersid,
6989 MSIINSTALLCONTEXT_USERUNMANAGED,
6990 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
6991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6992 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6993 ok(sz == 4, "Expected 4, got %d\n", sz);
6994
6995 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6996 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6997
6998 /* FIXME */
6999
7000 /* AssignmentType value exists */
7001 sz = MAX_PATH;
7002 lstrcpyA(buf, "apple");
7003 r = pMsiGetProductInfoExA(prodcode, usersid,
7004 MSIINSTALLCONTEXT_USERUNMANAGED,
7005 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7006 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7007 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7008 ok(sz == 0, "Expected 0, got %d\n", sz);
7009
7010 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7011 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7012
7013 /* FIXME */
7014
7015 /* PackageCode value exists */
7016 sz = MAX_PATH;
7017 lstrcpyA(buf, "apple");
7018 r = pMsiGetProductInfoExA(prodcode, usersid,
7019 MSIINSTALLCONTEXT_USERUNMANAGED,
7020 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7021 todo_wine
7022 {
7023 ok(r == ERROR_BAD_CONFIGURATION,
7024 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7025 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7026 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7027 }
7028
7029 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7030 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7031
7032 /* Version value exists */
7033 sz = MAX_PATH;
7034 lstrcpyA(buf, "apple");
7035 r = pMsiGetProductInfoExA(prodcode, usersid,
7036 MSIINSTALLCONTEXT_USERUNMANAGED,
7037 INSTALLPROPERTY_VERSIONA, buf, &sz);
7038 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7039 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7040 ok(sz == 3, "Expected 3, got %d\n", sz);
7041
7042 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7043 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7044
7045 /* ProductIcon value exists */
7046 sz = MAX_PATH;
7047 lstrcpyA(buf, "apple");
7048 r = pMsiGetProductInfoExA(prodcode, usersid,
7049 MSIINSTALLCONTEXT_USERUNMANAGED,
7050 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7052 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7053 ok(sz == 4, "Expected 4, got %d\n", sz);
7054
7055 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7056 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7057
7058 /* PackageName value exists */
7059 sz = MAX_PATH;
7060 lstrcpyA(buf, "apple");
7061 r = pMsiGetProductInfoExA(prodcode, usersid,
7062 MSIINSTALLCONTEXT_USERUNMANAGED,
7063 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7064 todo_wine
7065 {
7066 ok(r == ERROR_UNKNOWN_PRODUCT,
7067 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7068 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7069 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7070 }
7071
7072 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7073 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7074
7075 /* AuthorizedLUAApp value exists */
7076 sz = MAX_PATH;
7077 lstrcpyA(buf, "apple");
7078 r = pMsiGetProductInfoExA(prodcode, usersid,
7079 MSIINSTALLCONTEXT_USERUNMANAGED,
7080 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7081 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7082 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7083 ok(sz == 4, "Expected 4, got %d\n", sz);
7084
7085 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
7086 RegDeleteValueA(prodkey, "PackageName");
7087 RegDeleteValueA(prodkey, "ProductIcon");
7088 RegDeleteValueA(prodkey, "Version");
7089 RegDeleteValueA(prodkey, "PackageCode");
7090 RegDeleteValueA(prodkey, "AssignmentType");
7091 RegDeleteValueA(prodkey, "ProductName");
7092 RegDeleteValueA(prodkey, "Language");
7093 RegDeleteValueA(prodkey, "Transforms");
7094 RegDeleteValueA(prodkey, "RegOwner");
7095 RegDeleteValueA(prodkey, "RegCompany");
7096 RegDeleteValueA(prodkey, "ProductID");
7097 RegDeleteValueA(prodkey, "DisplayVersion");
7098 RegDeleteValueA(prodkey, "VersionMajor");
7099 RegDeleteValueA(prodkey, "VersionMinor");
7100 RegDeleteValueA(prodkey, "URLUpdateInfo");
7101 RegDeleteValueA(prodkey, "URLInfoAbout");
7102 RegDeleteValueA(prodkey, "Publisher");
7103 RegDeleteValueA(prodkey, "LocalPackage");
7104 RegDeleteValueA(prodkey, "InstallSource");
7105 RegDeleteValueA(prodkey, "InstallLocation");
7106 RegDeleteValueA(prodkey, "DisplayName");
7107 RegDeleteValueA(prodkey, "InstallDate");
7108 RegDeleteValueA(prodkey, "HelpTelephone");
7109 RegDeleteValueA(prodkey, "HelpLink");
7110 RegDeleteValueA(prodkey, "LocalPackage");
7111 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7112 RegCloseKey(prodkey);
7113
7114 /* MSIINSTALLCONTEXT_USERMANAGED */
7115
7116 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
7117 lstrcatA(keypath, usersid);
7118 lstrcatA(keypath, "\\Products\\");
7119 lstrcatA(keypath, prod_squashed);
7120
7121 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
7122 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7123
7124 /* local user product key exists */
7125 sz = MAX_PATH;
7126 lstrcpyA(buf, "apple");
7127 r = pMsiGetProductInfoExA(prodcode, usersid,
7128 MSIINSTALLCONTEXT_USERMANAGED,
7129 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7130 ok(r == ERROR_UNKNOWN_PRODUCT,
7131 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7132 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7133 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7134
7135 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
7136 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7137
7138 /* InstallProperties key exists */
7139 sz = MAX_PATH;
7140 lstrcpyA(buf, "apple");
7141 r = pMsiGetProductInfoExA(prodcode, usersid,
7142 MSIINSTALLCONTEXT_USERMANAGED,
7143 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7144 ok(r == ERROR_UNKNOWN_PRODUCT,
7145 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7146 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7147 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7148
7149 res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7150 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7151
7152 /* ManagedLocalPackage value exists */
7153 sz = MAX_PATH;
7154 lstrcpyA(buf, "apple");
7155 r = pMsiGetProductInfoExA(prodcode, usersid,
7156 MSIINSTALLCONTEXT_USERMANAGED,
7157 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7158 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7159 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
7160 ok(sz == 1, "Expected 1, got %d\n", sz);
7161
7162 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7163 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7164
7165 /* HelpLink value exists */
7166 sz = MAX_PATH;
7167 lstrcpyA(buf, "apple");
7168 r = pMsiGetProductInfoExA(prodcode, usersid,
7169 MSIINSTALLCONTEXT_USERMANAGED,
7170 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7171 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7172 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
7173 ok(sz == 4, "Expected 4, got %d\n", sz);
7174
7175 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7176 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7177
7178 /* HelpTelephone value exists */
7179 sz = MAX_PATH;
7180 lstrcpyA(buf, "apple");
7181 r = pMsiGetProductInfoExA(prodcode, usersid,
7182 MSIINSTALLCONTEXT_USERMANAGED,
7183 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7184 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7185 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
7186 ok(sz == 5, "Expected 5, got %d\n", sz);
7187
7188 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7190
7191 /* InstallDate value exists */
7192 sz = MAX_PATH;
7193 lstrcpyA(buf, "apple");
7194 r = pMsiGetProductInfoExA(prodcode, usersid,
7195 MSIINSTALLCONTEXT_USERMANAGED,
7196 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7197 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7198 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
7199 ok(sz == 4, "Expected 4, got %d\n", sz);
7200
7201 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7202 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7203
7204 /* DisplayName value exists */
7205 sz = MAX_PATH;
7206 lstrcpyA(buf, "apple");
7207 r = pMsiGetProductInfoExA(prodcode, usersid,
7208 MSIINSTALLCONTEXT_USERMANAGED,
7209 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7210 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7211 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7212 ok(sz == 4, "Expected 4, got %d\n", sz);
7213
7214 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7215 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7216
7217 /* InstallLocation value exists */
7218 sz = MAX_PATH;
7219 lstrcpyA(buf, "apple");
7220 r = pMsiGetProductInfoExA(prodcode, usersid,
7221 MSIINSTALLCONTEXT_USERMANAGED,
7222 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7223 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7224 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
7225 ok(sz == 3, "Expected 3, got %d\n", sz);
7226
7227 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7228 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7229
7230 /* InstallSource value exists */
7231 sz = MAX_PATH;
7232 lstrcpyA(buf, "apple");
7233 r = pMsiGetProductInfoExA(prodcode, usersid,
7234 MSIINSTALLCONTEXT_USERMANAGED,
7235 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7236 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7237 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
7238 ok(sz == 6, "Expected 6, got %d\n", sz);
7239
7240 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7241 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7242
7243 /* LocalPackage value exists */
7244 sz = MAX_PATH;
7245 lstrcpyA(buf, "apple");
7246 r = pMsiGetProductInfoExA(prodcode, usersid,
7247 MSIINSTALLCONTEXT_USERMANAGED,
7248 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7249 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7250 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
7251 ok(sz == 5, "Expected 5, got %d\n", sz);
7252
7253 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7254 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7255
7256 /* Publisher value exists */
7257 sz = MAX_PATH;
7258 lstrcpyA(buf, "apple");
7259 r = pMsiGetProductInfoExA(prodcode, usersid,
7260 MSIINSTALLCONTEXT_USERMANAGED,
7261 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7263 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
7264 ok(sz == 3, "Expected 3, got %d\n", sz);
7265
7266 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7267 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7268
7269 /* URLInfoAbout value exists */
7270 sz = MAX_PATH;
7271 lstrcpyA(buf, "apple");
7272 r = pMsiGetProductInfoExA(prodcode, usersid,
7273 MSIINSTALLCONTEXT_USERMANAGED,
7274 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7275 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7276 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
7277 ok(sz == 5, "Expected 5, got %d\n", sz);
7278
7279 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7280 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7281
7282 /* URLUpdateInfo value exists */
7283 sz = MAX_PATH;
7284 lstrcpyA(buf, "apple");
7285 r = pMsiGetProductInfoExA(prodcode, usersid,
7286 MSIINSTALLCONTEXT_USERMANAGED,
7287 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7288 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7289 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
7290 ok(sz == 6, "Expected 6, got %d\n", sz);
7291
7292 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7293 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7294
7295 /* VersionMinor value exists */
7296 sz = MAX_PATH;
7297 lstrcpyA(buf, "apple");
7298 r = pMsiGetProductInfoExA(prodcode, usersid,
7299 MSIINSTALLCONTEXT_USERMANAGED,
7300 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7301 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7302 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
7303 ok(sz == 1, "Expected 1, got %d\n", sz);
7304
7305 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7306 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7307
7308 /* VersionMajor value exists */
7309 sz = MAX_PATH;
7310 lstrcpyA(buf, "apple");
7311 r = pMsiGetProductInfoExA(prodcode, usersid,
7312 MSIINSTALLCONTEXT_USERMANAGED,
7313 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7314 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7315 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
7316 ok(sz == 1, "Expected 1, got %d\n", sz);
7317
7318 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7319 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7320
7321 /* DisplayVersion value exists */
7322 sz = MAX_PATH;
7323 lstrcpyA(buf, "apple");
7324 r = pMsiGetProductInfoExA(prodcode, usersid,
7325 MSIINSTALLCONTEXT_USERMANAGED,
7326 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7328 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
7329 ok(sz == 5, "Expected 5, got %d\n", sz);
7330
7331 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7332 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7333
7334 /* ProductID value exists */
7335 sz = MAX_PATH;
7336 lstrcpyA(buf, "apple");
7337 r = pMsiGetProductInfoExA(prodcode, usersid,
7338 MSIINSTALLCONTEXT_USERMANAGED,
7339 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7340 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7341 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
7342 ok(sz == 2, "Expected 2, got %d\n", sz);
7343
7344 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7345 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7346
7347 /* RegCompany value exists */
7348 sz = MAX_PATH;
7349 lstrcpyA(buf, "apple");
7350 r = pMsiGetProductInfoExA(prodcode, usersid,
7351 MSIINSTALLCONTEXT_USERMANAGED,
7352 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7353 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7354 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
7355 ok(sz == 4, "Expected 4, got %d\n", sz);
7356
7357 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7358 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7359
7360 /* RegOwner value exists */
7361 sz = MAX_PATH;
7362 lstrcpyA(buf, "apple");
7363 r = pMsiGetProductInfoExA(prodcode, usersid,
7364 MSIINSTALLCONTEXT_USERMANAGED,
7365 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7366 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7367 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
7368 ok(sz == 5, "Expected 5, got %d\n", sz);
7369
7370 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7371 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7372
7373 /* Transforms value exists */
7374 sz = MAX_PATH;
7375 lstrcpyA(buf, "apple");
7376 r = pMsiGetProductInfoExA(prodcode, usersid,
7377 MSIINSTALLCONTEXT_USERMANAGED,
7378 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7379 ok(r == ERROR_UNKNOWN_PRODUCT,
7380 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7381 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7382 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7383
7384 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7385 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7386
7387 /* Language value exists */
7388 sz = MAX_PATH;
7389 lstrcpyA(buf, "apple");
7390 r = pMsiGetProductInfoExA(prodcode, usersid,
7391 MSIINSTALLCONTEXT_USERMANAGED,
7392 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7393 ok(r == ERROR_UNKNOWN_PRODUCT,
7394 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7395 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7396 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7397
7398 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7399 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7400
7401 /* ProductName value exists */
7402 sz = MAX_PATH;
7403 lstrcpyA(buf, "apple");
7404 r = pMsiGetProductInfoExA(prodcode, usersid,
7405 MSIINSTALLCONTEXT_USERMANAGED,
7406 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7407 ok(r == ERROR_UNKNOWN_PRODUCT,
7408 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7409 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7410 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7411
7412 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7414
7415 /* FIXME */
7416
7417 /* AssignmentType value exists */
7418 sz = MAX_PATH;
7419 lstrcpyA(buf, "apple");
7420 r = pMsiGetProductInfoExA(prodcode, usersid,
7421 MSIINSTALLCONTEXT_USERMANAGED,
7422 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7423 ok(r == ERROR_UNKNOWN_PRODUCT,
7424 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7425 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7426 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7427
7428 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7429 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7430
7431 /* PackageCode value exists */
7432 sz = MAX_PATH;
7433 lstrcpyA(buf, "apple");
7434 r = pMsiGetProductInfoExA(prodcode, usersid,
7435 MSIINSTALLCONTEXT_USERMANAGED,
7436 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7437 ok(r == ERROR_UNKNOWN_PRODUCT,
7438 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7439 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7440 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7441
7442 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7443 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7444
7445 /* Version value exists */
7446 sz = MAX_PATH;
7447 lstrcpyA(buf, "apple");
7448 r = pMsiGetProductInfoExA(prodcode, usersid,
7449 MSIINSTALLCONTEXT_USERMANAGED,
7450 INSTALLPROPERTY_VERSIONA, buf, &sz);
7451 ok(r == ERROR_UNKNOWN_PRODUCT,
7452 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7453 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7454 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7455
7456 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7457 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7458
7459 /* ProductIcon value exists */
7460 sz = MAX_PATH;
7461 lstrcpyA(buf, "apple");
7462 r = pMsiGetProductInfoExA(prodcode, usersid,
7463 MSIINSTALLCONTEXT_USERMANAGED,
7464 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7465 ok(r == ERROR_UNKNOWN_PRODUCT,
7466 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7467 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7468 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7469
7470 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7471 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7472
7473 /* PackageName value exists */
7474 sz = MAX_PATH;
7475 lstrcpyA(buf, "apple");
7476 r = pMsiGetProductInfoExA(prodcode, usersid,
7477 MSIINSTALLCONTEXT_USERMANAGED,
7478 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7479 ok(r == ERROR_UNKNOWN_PRODUCT,
7480 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7481 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7482 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7483
7484 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7485 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7486
7487 /* AuthorizedLUAApp value exists */
7488 sz = MAX_PATH;
7489 lstrcpyA(buf, "apple");
7490 r = pMsiGetProductInfoExA(prodcode, usersid,
7491 MSIINSTALLCONTEXT_USERMANAGED,
7492 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7493 ok(r == ERROR_UNKNOWN_PRODUCT,
7494 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7495 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7496 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7497
7498 RegDeleteValueA(propkey, "AuthorizedLUAApp");
7499 RegDeleteValueA(propkey, "PackageName");
7500 RegDeleteValueA(propkey, "ProductIcon");
7501 RegDeleteValueA(propkey, "Version");
7502 RegDeleteValueA(propkey, "PackageCode");
7503 RegDeleteValueA(propkey, "AssignmentType");
7504 RegDeleteValueA(propkey, "ProductName");
7505 RegDeleteValueA(propkey, "Language");
7506 RegDeleteValueA(propkey, "Transforms");
7507 RegDeleteValueA(propkey, "RegOwner");
7508 RegDeleteValueA(propkey, "RegCompany");
7509 RegDeleteValueA(propkey, "ProductID");
7510 RegDeleteValueA(propkey, "DisplayVersion");
7511 RegDeleteValueA(propkey, "VersionMajor");
7512 RegDeleteValueA(propkey, "VersionMinor");
7513 RegDeleteValueA(propkey, "URLUpdateInfo");
7514 RegDeleteValueA(propkey, "URLInfoAbout");
7515 RegDeleteValueA(propkey, "Publisher");
7516 RegDeleteValueA(propkey, "LocalPackage");
7517 RegDeleteValueA(propkey, "InstallSource");
7518 RegDeleteValueA(propkey, "InstallLocation");
7519 RegDeleteValueA(propkey, "DisplayName");
7520 RegDeleteValueA(propkey, "InstallDate");
7521 RegDeleteValueA(propkey, "HelpTelephone");
7522 RegDeleteValueA(propkey, "HelpLink");
7523 RegDeleteValueA(propkey, "ManagedLocalPackage");
7524 delete_key(propkey, "", access & KEY_WOW64_64KEY);
7525 RegCloseKey(propkey);
7526 delete_key(localkey, "", access & KEY_WOW64_64KEY);
7527 RegCloseKey(localkey);
7528
7529 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7530 lstrcatA(keypath, usersid);
7531 lstrcatA(keypath, "\\Installer\\Products\\");
7532 lstrcatA(keypath, prod_squashed);
7533
7534 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7535 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7536
7537 /* user product key exists */
7538 sz = MAX_PATH;
7539 lstrcpyA(buf, "apple");
7540 r = pMsiGetProductInfoExA(prodcode, usersid,
7541 MSIINSTALLCONTEXT_USERMANAGED,
7542 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7544 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
7545 ok(sz == 1, "Expected 1, got %d\n", sz);
7546
7547 delete_key(userkey, "", access & KEY_WOW64_64KEY);
7548 RegCloseKey(userkey);
7549
7550 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7551 lstrcatA(keypath, prod_squashed);
7552
7553 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7554 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7555
7556 /* current user product key exists */
7557 sz = MAX_PATH;
7558 lstrcpyA(buf, "apple");
7559 r = pMsiGetProductInfoExA(prodcode, usersid,
7560 MSIINSTALLCONTEXT_USERMANAGED,
7561 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7562 ok(r == ERROR_UNKNOWN_PRODUCT,
7563 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7564 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7565 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7566
7567 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7568 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7569
7570 /* HelpLink value exists, user product key does not exist */
7571 sz = MAX_PATH;
7572 lstrcpyA(buf, "apple");
7573 r = pMsiGetProductInfoExA(prodcode, usersid,
7574 MSIINSTALLCONTEXT_USERMANAGED,
7575 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7576 ok(r == ERROR_UNKNOWN_PRODUCT,
7577 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7578 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7579 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7580
7581 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7582 lstrcatA(keypath, usersid);
7583 lstrcatA(keypath, "\\Installer\\Products\\");
7584 lstrcatA(keypath, prod_squashed);
7585
7586 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7587 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7588
7589 res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7590 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7591
7592 /* HelpLink value exists, user product key does exist */
7593 sz = MAX_PATH;
7594 lstrcpyA(buf, "apple");
7595 r = pMsiGetProductInfoExA(prodcode, usersid,
7596 MSIINSTALLCONTEXT_USERMANAGED,
7597 INSTALLPROPERTY_HELPLINKA, buf, &sz);
7598 ok(r == ERROR_UNKNOWN_PROPERTY,
7599 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7600 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7601 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7602
7603 res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7604 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7605
7606 /* HelpTelephone value exists */
7607 sz = MAX_PATH;
7608 lstrcpyA(buf, "apple");
7609 r = pMsiGetProductInfoExA(prodcode, usersid,
7610 MSIINSTALLCONTEXT_USERMANAGED,
7611 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
7612 ok(r == ERROR_UNKNOWN_PROPERTY,
7613 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7614 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7615 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7616
7617 res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7618 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7619
7620 /* InstallDate value exists */
7621 sz = MAX_PATH;
7622 lstrcpyA(buf, "apple");
7623 r = pMsiGetProductInfoExA(prodcode, usersid,
7624 MSIINSTALLCONTEXT_USERMANAGED,
7625 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
7626 ok(r == ERROR_UNKNOWN_PROPERTY,
7627 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7628 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7629 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7630
7631 res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7632 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7633
7634 /* DisplayName value exists */
7635 sz = MAX_PATH;
7636 lstrcpyA(buf, "apple");
7637 r = pMsiGetProductInfoExA(prodcode, usersid,
7638 MSIINSTALLCONTEXT_USERMANAGED,
7639 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
7640 ok(r == ERROR_UNKNOWN_PROPERTY,
7641 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7642 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7643 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7644
7645 res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7646 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7647
7648 /* InstallLocation value exists */
7649 sz = MAX_PATH;
7650 lstrcpyA(buf, "apple");
7651 r = pMsiGetProductInfoExA(prodcode, usersid,
7652 MSIINSTALLCONTEXT_USERMANAGED,
7653 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
7654 ok(r == ERROR_UNKNOWN_PROPERTY,
7655 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7656 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7657 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7658
7659 res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7660 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7661
7662 /* InstallSource value exists */
7663 sz = MAX_PATH;
7664 lstrcpyA(buf, "apple");
7665 r = pMsiGetProductInfoExA(prodcode, usersid,
7666 MSIINSTALLCONTEXT_USERMANAGED,
7667 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
7668 ok(r == ERROR_UNKNOWN_PROPERTY,
7669 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7670 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7671 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7672
7673 res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7674 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7675
7676 /* LocalPackage value exists */
7677 sz = MAX_PATH;
7678 lstrcpyA(buf, "apple");
7679 r = pMsiGetProductInfoExA(prodcode, usersid,
7680 MSIINSTALLCONTEXT_USERMANAGED,
7681 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
7682 ok(r == ERROR_UNKNOWN_PROPERTY,
7683 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7684 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7685 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7686
7687 res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7688 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7689
7690 /* Publisher value exists */
7691 sz = MAX_PATH;
7692 lstrcpyA(buf, "apple");
7693 r = pMsiGetProductInfoExA(prodcode, usersid,
7694 MSIINSTALLCONTEXT_USERMANAGED,
7695 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
7696 ok(r == ERROR_UNKNOWN_PROPERTY,
7697 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7698 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7699 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7700
7701 res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7702 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7703
7704 /* URLInfoAbout value exists */
7705 sz = MAX_PATH;
7706 lstrcpyA(buf, "apple");
7707 r = pMsiGetProductInfoExA(prodcode, usersid,
7708 MSIINSTALLCONTEXT_USERMANAGED,
7709 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
7710 ok(r == ERROR_UNKNOWN_PROPERTY,
7711 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7712 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7713 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7714
7715 res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7716 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7717
7718 /* URLUpdateInfo value exists */
7719 sz = MAX_PATH;
7720 lstrcpyA(buf, "apple");
7721 r = pMsiGetProductInfoExA(prodcode, usersid,
7722 MSIINSTALLCONTEXT_USERMANAGED,
7723 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
7724 ok(r == ERROR_UNKNOWN_PROPERTY,
7725 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7726 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7727 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7728
7729 res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7730 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7731
7732 /* VersionMinor value exists */
7733 sz = MAX_PATH;
7734 lstrcpyA(buf, "apple");
7735 r = pMsiGetProductInfoExA(prodcode, usersid,
7736 MSIINSTALLCONTEXT_USERMANAGED,
7737 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
7738 ok(r == ERROR_UNKNOWN_PROPERTY,
7739 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7740 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7741 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7742
7743 res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7744 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7745
7746 /* VersionMajor value exists */
7747 sz = MAX_PATH;
7748 lstrcpyA(buf, "apple");
7749 r = pMsiGetProductInfoExA(prodcode, usersid,
7750 MSIINSTALLCONTEXT_USERMANAGED,
7751 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
7752 ok(r == ERROR_UNKNOWN_PROPERTY,
7753 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7754 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7755 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7756
7757 res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7758 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7759
7760 /* DisplayVersion value exists */
7761 sz = MAX_PATH;
7762 lstrcpyA(buf, "apple");
7763 r = pMsiGetProductInfoExA(prodcode, usersid,
7764 MSIINSTALLCONTEXT_USERMANAGED,
7765 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
7766 ok(r == ERROR_UNKNOWN_PROPERTY,
7767 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7768 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7769 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7770
7771 res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7772 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7773
7774 /* ProductID value exists */
7775 sz = MAX_PATH;
7776 lstrcpyA(buf, "apple");
7777 r = pMsiGetProductInfoExA(prodcode, usersid,
7778 MSIINSTALLCONTEXT_USERMANAGED,
7779 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
7780 ok(r == ERROR_UNKNOWN_PROPERTY,
7781 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7782 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7783 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7784
7785 res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7787
7788 /* RegCompany value exists */
7789 sz = MAX_PATH;
7790 lstrcpyA(buf, "apple");
7791 r = pMsiGetProductInfoExA(prodcode, usersid,
7792 MSIINSTALLCONTEXT_USERMANAGED,
7793 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
7794 ok(r == ERROR_UNKNOWN_PROPERTY,
7795 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7796 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7797 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7798
7799 res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7800 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7801
7802 /* RegOwner value exists */
7803 sz = MAX_PATH;
7804 lstrcpyA(buf, "apple");
7805 r = pMsiGetProductInfoExA(prodcode, usersid,
7806 MSIINSTALLCONTEXT_USERMANAGED,
7807 INSTALLPROPERTY_REGOWNERA, buf, &sz);
7808 ok(r == ERROR_UNKNOWN_PROPERTY,
7809 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7810 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7811 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7812
7813 res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7814 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7815
7816 /* Transforms value exists */
7817 sz = MAX_PATH;
7818 lstrcpyA(buf, "apple");
7819 r = pMsiGetProductInfoExA(prodcode, usersid,
7820 MSIINSTALLCONTEXT_USERMANAGED,
7821 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
7822 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7823 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
7824 ok(sz == 5, "Expected 5, got %d\n", sz);
7825
7826 res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7827 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7828
7829 /* Language value exists */
7830 sz = MAX_PATH;
7831 lstrcpyA(buf, "apple");
7832 r = pMsiGetProductInfoExA(prodcode, usersid,
7833 MSIINSTALLCONTEXT_USERMANAGED,
7834 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
7835 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7836 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
7837 ok(sz == 4, "Expected 4, got %d\n", sz);
7838
7839 res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7840 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7841
7842 /* ProductName value exists */
7843 sz = MAX_PATH;
7844 lstrcpyA(buf, "apple");
7845 r = pMsiGetProductInfoExA(prodcode, usersid,
7846 MSIINSTALLCONTEXT_USERMANAGED,
7847 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
7848 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7849 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7850 ok(sz == 4, "Expected 4, got %d\n", sz);
7851
7852 res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7853 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7854
7855 /* FIXME */
7856
7857 /* AssignmentType value exists */
7858 sz = MAX_PATH;
7859 lstrcpyA(buf, "apple");
7860 r = pMsiGetProductInfoExA(prodcode, usersid,
7861 MSIINSTALLCONTEXT_USERMANAGED,
7862 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
7863 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7864 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7865 ok(sz == 0, "Expected 0, got %d\n", sz);
7866
7867 res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7869
7870 /* FIXME */
7871
7872 /* PackageCode value exists */
7873 sz = MAX_PATH;
7874 lstrcpyA(buf, "apple");
7875 r = pMsiGetProductInfoExA(prodcode, usersid,
7876 MSIINSTALLCONTEXT_USERMANAGED,
7877 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
7878 todo_wine
7879 {
7880 ok(r == ERROR_BAD_CONFIGURATION,
7881 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7882 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7883 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7884 }
7885
7886 res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7887 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7888
7889 /* Version value exists */
7890 sz = MAX_PATH;
7891 lstrcpyA(buf, "apple");
7892 r = pMsiGetProductInfoExA(prodcode, usersid,
7893 MSIINSTALLCONTEXT_USERMANAGED,
7894 INSTALLPROPERTY_VERSIONA, buf, &sz);
7895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7896 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7897 ok(sz == 3, "Expected 3, got %d\n", sz);
7898
7899 res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7900 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7901
7902 /* ProductIcon value exists */
7903 sz = MAX_PATH;
7904 lstrcpyA(buf, "apple");
7905 r = pMsiGetProductInfoExA(prodcode, usersid,
7906 MSIINSTALLCONTEXT_USERMANAGED,
7907 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
7908 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7909 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7910 ok(sz == 4, "Expected 4, got %d\n", sz);
7911
7912 res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7913 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7914
7915 /* PackageName value exists */
7916 sz = MAX_PATH;
7917 lstrcpyA(buf, "apple");
7918 r = pMsiGetProductInfoExA(prodcode, usersid,
7919 MSIINSTALLCONTEXT_USERMANAGED,
7920 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
7921 todo_wine
7922 {
7923 ok(r == ERROR_UNKNOWN_PRODUCT,
7924 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7925 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7926 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7927 }
7928
7929 res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7930 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7931
7932 /* AuthorizedLUAApp value exists */
7933 sz = MAX_PATH;
7934 lstrcpyA(buf, "apple");
7935 r = pMsiGetProductInfoExA(prodcode, usersid,
7936 MSIINSTALLCONTEXT_USERMANAGED,
7937 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
7938 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7939 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7940 ok(sz == 4, "Expected 4, got %d\n", sz);
7941
7942 RegDeleteValueA(userkey, "AuthorizedLUAApp");
7943 RegDeleteValueA(userkey, "PackageName");
7944 RegDeleteValueA(userkey, "ProductIcon");
7945 RegDeleteValueA(userkey, "Version");
7946 RegDeleteValueA(userkey, "PackageCode");
7947 RegDeleteValueA(userkey, "AssignmentType");
7948 RegDeleteValueA(userkey, "ProductName");
7949 RegDeleteValueA(userkey, "Language");
7950 RegDeleteValueA(userkey, "Transforms");
7951 RegDeleteValueA(userkey, "RegOwner");
7952 RegDeleteValueA(userkey, "RegCompany");
7953 RegDeleteValueA(userkey, "ProductID");
7954 RegDeleteValueA(userkey, "DisplayVersion");
7955 RegDeleteValueA(userkey, "VersionMajor");
7956 RegDeleteValueA(userkey, "VersionMinor");
7957 RegDeleteValueA(userkey, "URLUpdateInfo");
7958 RegDeleteValueA(userkey, "URLInfoAbout");
7959 RegDeleteValueA(userkey, "Publisher");
7960 RegDeleteValueA(userkey, "LocalPackage");
7961 RegDeleteValueA(userkey, "InstallSource");
7962 RegDeleteValueA(userkey, "InstallLocation");
7963 RegDeleteValueA(userkey, "DisplayName");
7964 RegDeleteValueA(userkey, "InstallDate");
7965 RegDeleteValueA(userkey, "HelpTelephone");
7966 RegDeleteValueA(userkey, "HelpLink");
7967 delete_key(userkey, "", access & KEY_WOW64_64KEY);
7968 RegCloseKey(userkey);
7969 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7970 RegCloseKey(prodkey);
7971
7972 /* MSIINSTALLCONTEXT_MACHINE */
7973
7974 /* szUserSid is non-NULL */
7975 sz = MAX_PATH;
7976 lstrcpyA(buf, "apple");
7977 r = pMsiGetProductInfoExA(prodcode, usersid,
7978 MSIINSTALLCONTEXT_MACHINE,
7979 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7980 ok(r == ERROR_INVALID_PARAMETER,
7981 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7982 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7983 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7984
7985 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
7986 lstrcatA(keypath, prod_squashed);
7987
7988 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
7989 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7990
7991 /* local system product key exists */
7992 sz = MAX_PATH;
7993 lstrcpyA(buf, "apple");
7994 r = pMsiGetProductInfoExA(prodcode, NULL,
7995 MSIINSTALLCONTEXT_MACHINE,
7996 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
7997 ok(r == ERROR_UNKNOWN_PRODUCT,
7998 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7999 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8000 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8001
8002 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
8003 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8004
8005 /* InstallProperties key exists */
8006 sz = MAX_PATH;
8007 lstrcpyA(buf, "apple");
8008 r = pMsiGetProductInfoExA(prodcode, NULL,
8009 MSIINSTALLCONTEXT_MACHINE,
8010 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
8011 ok(r == ERROR_UNKNOWN_PRODUCT,
8012 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8013 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8014 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8015
8016 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
8017 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8018
8019 /* LocalPackage value exists */
8020 sz = MAX_PATH;
8021 lstrcpyA(buf, "apple");
8022 r = pMsiGetProductInfoExA(prodcode, NULL,
8023 MSIINSTALLCONTEXT_MACHINE,
8024 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
8025 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8026 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
8027 ok(sz == 1, "Expected 1, got %d\n", sz);
8028
8029 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
8030 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8031
8032 /* HelpLink value exists */
8033 sz = MAX_PATH;
8034 lstrcpyA(buf, "apple");
8035 r = pMsiGetProductInfoExA(prodcode, NULL,
8036 MSIINSTALLCONTEXT_MACHINE,
8037 INSTALLPROPERTY_HELPLINKA, buf, &sz);
8038 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8039 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
8040 ok(sz == 4, "Expected 4, got %d\n", sz);
8041
8042 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
8043 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8044
8045 /* HelpTelephone value exists */
8046 sz = MAX_PATH;
8047 lstrcpyA(buf, "apple");
8048 r = pMsiGetProductInfoExA(prodcode, NULL,
8049 MSIINSTALLCONTEXT_MACHINE,
8050 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
8051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8052 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
8053 ok(sz == 5, "Expected 5, got %d\n", sz);
8054
8055 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
8056 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8057
8058 /* InstallDate value exists */
8059 sz = MAX_PATH;
8060 lstrcpyA(buf, "apple");
8061 r = pMsiGetProductInfoExA(prodcode, NULL,
8062 MSIINSTALLCONTEXT_MACHINE,
8063 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
8064 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8065 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
8066 ok(sz == 4, "Expected 4, got %d\n", sz);
8067
8068 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
8069 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8070
8071 /* DisplayName value exists */
8072 sz = MAX_PATH;
8073 lstrcpyA(buf, "apple");
8074 r = pMsiGetProductInfoExA(prodcode, NULL,
8075 MSIINSTALLCONTEXT_MACHINE,
8076 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
8077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8078 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
8079 ok(sz == 4, "Expected 4, got %d\n", sz);
8080
8081 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
8082 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8083
8084 /* InstallLocation value exists */
8085 sz = MAX_PATH;
8086 lstrcpyA(buf, "apple");
8087 r = pMsiGetProductInfoExA(prodcode, NULL,
8088 MSIINSTALLCONTEXT_MACHINE,
8089 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
8090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8091 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
8092 ok(sz == 3, "Expected 3, got %d\n", sz);
8093
8094 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
8095 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8096
8097 /* InstallSource value exists */
8098 sz = MAX_PATH;
8099 lstrcpyA(buf, "apple");
8100 r = pMsiGetProductInfoExA(prodcode, NULL,
8101 MSIINSTALLCONTEXT_MACHINE,
8102 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
8103 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8104 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
8105 ok(sz == 6, "Expected 6, got %d\n", sz);
8106
8107 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
8108 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8109
8110 /* LocalPackage value exists */
8111 sz = MAX_PATH;
8112 lstrcpyA(buf, "apple");
8113 r = pMsiGetProductInfoExA(prodcode, NULL,
8114 MSIINSTALLCONTEXT_MACHINE,
8115 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
8116 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8117 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
8118 ok(sz == 5, "Expected 5, got %d\n", sz);
8119
8120 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
8121 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8122
8123 /* Publisher value exists */
8124 sz = MAX_PATH;
8125 lstrcpyA(buf, "apple");
8126 r = pMsiGetProductInfoExA(prodcode, NULL,
8127 MSIINSTALLCONTEXT_MACHINE,
8128 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
8129 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8130 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
8131 ok(sz == 3, "Expected 3, got %d\n", sz);
8132
8133 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
8134 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8135
8136 /* URLInfoAbout value exists */
8137 sz = MAX_PATH;
8138 lstrcpyA(buf, "apple");
8139 r = pMsiGetProductInfoExA(prodcode, NULL,
8140 MSIINSTALLCONTEXT_MACHINE,
8141 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
8142 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8143 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
8144 ok(sz == 5, "Expected 5, got %d\n", sz);
8145
8146 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
8147 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8148
8149 /* URLUpdateInfo value exists */
8150 sz = MAX_PATH;
8151 lstrcpyA(buf, "apple");
8152 r = pMsiGetProductInfoExA(prodcode, NULL,
8153 MSIINSTALLCONTEXT_MACHINE,
8154 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
8155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8156 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
8157 ok(sz == 6, "Expected 6, got %d\n", sz);
8158
8159 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
8160 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8161
8162 /* VersionMinor value exists */
8163 sz = MAX_PATH;
8164 lstrcpyA(buf, "apple");
8165 r = pMsiGetProductInfoExA(prodcode, NULL,
8166 MSIINSTALLCONTEXT_MACHINE,
8167 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
8168 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8169 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
8170 ok(sz == 1, "Expected 1, got %d\n", sz);
8171
8172 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
8173 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8174
8175 /* VersionMajor value exists */
8176 sz = MAX_PATH;
8177 lstrcpyA(buf, "apple");
8178 r = pMsiGetProductInfoExA(prodcode, NULL,
8179 MSIINSTALLCONTEXT_MACHINE,
8180 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
8181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8182 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
8183 ok(sz == 1, "Expected 1, got %d\n", sz);
8184
8185 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
8186 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8187
8188 /* DisplayVersion value exists */
8189 sz = MAX_PATH;
8190 lstrcpyA(buf, "apple");
8191 r = pMsiGetProductInfoExA(prodcode, NULL,
8192 MSIINSTALLCONTEXT_MACHINE,
8193 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
8194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8195 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
8196 ok(sz == 5, "Expected 5, got %d\n", sz);
8197
8198 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
8199 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8200
8201 /* ProductID value exists */
8202 sz = MAX_PATH;
8203 lstrcpyA(buf, "apple");
8204 r = pMsiGetProductInfoExA(prodcode, NULL,
8205 MSIINSTALLCONTEXT_MACHINE,
8206 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
8207 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8208 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
8209 ok(sz == 2, "Expected 2, got %d\n", sz);
8210
8211 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
8212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8213
8214 /* RegCompany value exists */
8215 sz = MAX_PATH;
8216 lstrcpyA(buf, "apple");
8217 r = pMsiGetProductInfoExA(prodcode, NULL,
8218 MSIINSTALLCONTEXT_MACHINE,
8219 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
8220 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8221 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
8222 ok(sz == 4, "Expected 4, got %d\n", sz);
8223
8224 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8225 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8226
8227 /* RegOwner value exists */
8228 sz = MAX_PATH;
8229 lstrcpyA(buf, "apple");
8230 r = pMsiGetProductInfoExA(prodcode, NULL,
8231 MSIINSTALLCONTEXT_MACHINE,
8232 INSTALLPROPERTY_REGOWNERA, buf, &sz);
8233 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8234 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
8235 ok(sz == 5, "Expected 5, got %d\n", sz);
8236
8237 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
8238 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8239
8240 /* Transforms value exists */
8241 sz = MAX_PATH;
8242 lstrcpyA(buf, "apple");
8243 r = pMsiGetProductInfoExA(prodcode, NULL,
8244 MSIINSTALLCONTEXT_MACHINE,
8245 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
8246 ok(r == ERROR_UNKNOWN_PRODUCT,
8247 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8248 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8249 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8250
8251 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
8252 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8253
8254 /* Language value exists */
8255 sz = MAX_PATH;
8256 lstrcpyA(buf, "apple");
8257 r = pMsiGetProductInfoExA(prodcode, NULL,
8258 MSIINSTALLCONTEXT_MACHINE,
8259 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
8260 ok(r == ERROR_UNKNOWN_PRODUCT,
8261 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8262 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8263 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8264
8265 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
8266 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8267
8268 /* ProductName value exists */
8269 sz = MAX_PATH;
8270 lstrcpyA(buf, "apple");
8271 r = pMsiGetProductInfoExA(prodcode, NULL,
8272 MSIINSTALLCONTEXT_MACHINE,
8273 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
8274 ok(r == ERROR_UNKNOWN_PRODUCT,
8275 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8276 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8277 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8278
8279 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
8280 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8281
8282 /* FIXME */
8283
8284 /* AssignmentType value exists */
8285 sz = MAX_PATH;
8286 lstrcpyA(buf, "apple");
8287 r = pMsiGetProductInfoExA(prodcode, NULL,
8288 MSIINSTALLCONTEXT_MACHINE,
8289 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
8290 ok(r == ERROR_UNKNOWN_PRODUCT,
8291 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8292 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8293 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8294
8295 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
8296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8297
8298 /* PackageCode value exists */
8299 sz = MAX_PATH;
8300 lstrcpyA(buf, "apple");
8301 r = pMsiGetProductInfoExA(prodcode, NULL,
8302 MSIINSTALLCONTEXT_MACHINE,
8303 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
8304 ok(r == ERROR_UNKNOWN_PRODUCT,
8305 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8306 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8307 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8308
8309 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
8310 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8311
8312 /* Version value exists */
8313 sz = MAX_PATH;
8314 lstrcpyA(buf, "apple");
8315 r = pMsiGetProductInfoExA(prodcode, NULL,
8316 MSIINSTALLCONTEXT_MACHINE,
8317 INSTALLPROPERTY_VERSIONA, buf, &sz);
8318 ok(r == ERROR_UNKNOWN_PRODUCT,
8319 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8320 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8321 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8322
8323 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
8324 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8325
8326 /* ProductIcon value exists */
8327 sz = MAX_PATH;
8328 lstrcpyA(buf, "apple");
8329 r = pMsiGetProductInfoExA(prodcode, NULL,
8330 MSIINSTALLCONTEXT_MACHINE,
8331 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
8332 ok(r == ERROR_UNKNOWN_PRODUCT,
8333 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8334 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8335 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8336
8337 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
8338 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8339
8340 /* PackageName value exists */
8341 sz = MAX_PATH;
8342 lstrcpyA(buf, "apple");
8343 r = pMsiGetProductInfoExA(prodcode, NULL,
8344 MSIINSTALLCONTEXT_MACHINE,
8345 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
8346 ok(r == ERROR_UNKNOWN_PRODUCT,
8347 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8348 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8349 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8350
8351 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
8352 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8353
8354 /* AuthorizedLUAApp value exists */
8355 sz = MAX_PATH;
8356 lstrcpyA(buf, "apple");
8357 r = pMsiGetProductInfoExA(prodcode, NULL,
8358 MSIINSTALLCONTEXT_MACHINE,
8359 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
8360 ok(r == ERROR_UNKNOWN_PRODUCT,
8361 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8362 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8363 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8364
8365 RegDeleteValueA(propkey, "AuthorizedLUAApp");
8366 RegDeleteValueA(propkey, "PackageName");
8367 RegDeleteValueA(propkey, "ProductIcon");
8368 RegDeleteValueA(propkey, "Version");
8369 RegDeleteValueA(propkey, "PackageCode");
8370 RegDeleteValueA(propkey, "AssignmentType");
8371 RegDeleteValueA(propkey, "ProductName");
8372 RegDeleteValueA(propkey, "Language");
8373 RegDeleteValueA(propkey, "Transforms");
8374 RegDeleteValueA(propkey, "RegOwner");
8375 RegDeleteValueA(propkey, "RegCompany");
8376 RegDeleteValueA(propkey, "ProductID");
8377 RegDeleteValueA(propkey, "DisplayVersion");
8378 RegDeleteValueA(propkey, "VersionMajor");
8379 RegDeleteValueA(propkey, "VersionMinor");
8380 RegDeleteValueA(propkey, "URLUpdateInfo");
8381 RegDeleteValueA(propkey, "URLInfoAbout");
8382 RegDeleteValueA(propkey, "Publisher");
8383 RegDeleteValueA(propkey, "LocalPackage");
8384 RegDeleteValueA(propkey, "InstallSource");
8385 RegDeleteValueA(propkey, "InstallLocation");
8386 RegDeleteValueA(propkey, "DisplayName");
8387 RegDeleteValueA(propkey, "InstallDate");
8388 RegDeleteValueA(propkey, "HelpTelephone");
8389 RegDeleteValueA(propkey, "HelpLink");
8390 RegDeleteValueA(propkey, "LocalPackage");
8391 delete_key(propkey, "", access & KEY_WOW64_64KEY);
8392 RegCloseKey(propkey);
8393 delete_key(localkey, "", access & KEY_WOW64_64KEY);
8394 RegCloseKey(localkey);
8395
8396 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8397 lstrcatA(keypath, prod_squashed);
8398
8399 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8400 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8401
8402 /* local classes product key exists */
8403 sz = MAX_PATH;
8404 lstrcpyA(buf, "apple");
8405 r = pMsiGetProductInfoExA(prodcode, NULL,
8406 MSIINSTALLCONTEXT_MACHINE,
8407 INSTALLPROPERTY_PRODUCTSTATEA, buf, &sz);
8408 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8409 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
8410 ok(sz == 1, "Expected 1, got %d\n", sz);
8411
8412 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
8413 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8414
8415 /* HelpLink value exists */
8416 sz = MAX_PATH;
8417 lstrcpyA(buf, "apple");
8418 r = pMsiGetProductInfoExA(prodcode, NULL,
8419 MSIINSTALLCONTEXT_MACHINE,
8420 INSTALLPROPERTY_HELPLINKA, buf, &sz);
8421 ok(r == ERROR_UNKNOWN_PROPERTY,
8422 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8423 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8424 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8425
8426 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
8427 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8428
8429 /* HelpTelephone value exists */
8430 sz = MAX_PATH;
8431 lstrcpyA(buf, "apple");
8432 r = pMsiGetProductInfoExA(prodcode, NULL,
8433 MSIINSTALLCONTEXT_MACHINE,
8434 INSTALLPROPERTY_HELPTELEPHONEA, buf, &sz);
8435 ok(r == ERROR_UNKNOWN_PROPERTY,
8436 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8437 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8438 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8439
8440 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
8441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8442
8443 /* InstallDate value exists */
8444 sz = MAX_PATH;
8445 lstrcpyA(buf, "apple");
8446 r = pMsiGetProductInfoExA(prodcode, NULL,
8447 MSIINSTALLCONTEXT_MACHINE,
8448 INSTALLPROPERTY_INSTALLDATEA, buf, &sz);
8449 ok(r == ERROR_UNKNOWN_PROPERTY,
8450 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8451 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8452 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8453
8454 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
8455 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8456
8457 /* DisplayName value exists */
8458 sz = MAX_PATH;
8459 lstrcpyA(buf, "apple");
8460 r = pMsiGetProductInfoExA(prodcode, NULL,
8461 MSIINSTALLCONTEXT_MACHINE,
8462 INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA, buf, &sz);
8463 ok(r == ERROR_UNKNOWN_PROPERTY,
8464 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8465 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8466 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8467
8468 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
8469 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8470
8471 /* InstallLocation value exists */
8472 sz = MAX_PATH;
8473 lstrcpyA(buf, "apple");
8474 r = pMsiGetProductInfoExA(prodcode, NULL,
8475 MSIINSTALLCONTEXT_MACHINE,
8476 INSTALLPROPERTY_INSTALLLOCATIONA, buf, &sz);
8477 ok(r == ERROR_UNKNOWN_PROPERTY,
8478 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8479 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8480 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8481
8482 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
8483 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8484
8485 /* InstallSource value exists */
8486 sz = MAX_PATH;
8487 lstrcpyA(buf, "apple");
8488 r = pMsiGetProductInfoExA(prodcode, NULL,
8489 MSIINSTALLCONTEXT_MACHINE,
8490 INSTALLPROPERTY_INSTALLSOURCEA, buf, &sz);
8491 ok(r == ERROR_UNKNOWN_PROPERTY,
8492 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8493 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8494 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8495
8496 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
8497 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8498
8499 /* LocalPackage value exists */
8500 sz = MAX_PATH;
8501 lstrcpyA(buf, "apple");
8502 r = pMsiGetProductInfoExA(prodcode, NULL,
8503 MSIINSTALLCONTEXT_MACHINE,
8504 INSTALLPROPERTY_LOCALPACKAGEA, buf, &sz);
8505 ok(r == ERROR_UNKNOWN_PROPERTY,
8506 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8507 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8508 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8509
8510 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
8511 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8512
8513 /* Publisher value exists */
8514 sz = MAX_PATH;
8515 lstrcpyA(buf, "apple");
8516 r = pMsiGetProductInfoExA(prodcode, NULL,
8517 MSIINSTALLCONTEXT_MACHINE,
8518 INSTALLPROPERTY_PUBLISHERA, buf, &sz);
8519 ok(r == ERROR_UNKNOWN_PROPERTY,
8520 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8521 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8522 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8523
8524 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
8525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8526
8527 /* URLInfoAbout value exists */
8528 sz = MAX_PATH;
8529 lstrcpyA(buf, "apple");
8530 r = pMsiGetProductInfoExA(prodcode, NULL,
8531 MSIINSTALLCONTEXT_MACHINE,
8532 INSTALLPROPERTY_URLINFOABOUTA, buf, &sz);
8533 ok(r == ERROR_UNKNOWN_PROPERTY,
8534 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8535 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8536 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8537
8538 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
8539 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8540
8541 /* URLUpdateInfo value exists */
8542 sz = MAX_PATH;
8543 lstrcpyA(buf, "apple");
8544 r = pMsiGetProductInfoExA(prodcode, NULL,
8545 MSIINSTALLCONTEXT_MACHINE,
8546 INSTALLPROPERTY_URLUPDATEINFOA, buf, &sz);
8547 ok(r == ERROR_UNKNOWN_PROPERTY,
8548 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8549 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8550 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8551
8552 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
8553 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8554
8555 /* VersionMinor value exists */
8556 sz = MAX_PATH;
8557 lstrcpyA(buf, "apple");
8558 r = pMsiGetProductInfoExA(prodcode, NULL,
8559 MSIINSTALLCONTEXT_MACHINE,
8560 INSTALLPROPERTY_VERSIONMINORA, buf, &sz);
8561 ok(r == ERROR_UNKNOWN_PROPERTY,
8562 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8563 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8564 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8565
8566 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
8567 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8568
8569 /* VersionMajor value exists */
8570 sz = MAX_PATH;
8571 lstrcpyA(buf, "apple");
8572 r = pMsiGetProductInfoExA(prodcode, NULL,
8573 MSIINSTALLCONTEXT_MACHINE,
8574 INSTALLPROPERTY_VERSIONMAJORA, buf, &sz);
8575 ok(r == ERROR_UNKNOWN_PROPERTY,
8576 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8577 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8578 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8579
8580 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
8581 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8582
8583 /* DisplayVersion value exists */
8584 sz = MAX_PATH;
8585 lstrcpyA(buf, "apple");
8586 r = pMsiGetProductInfoExA(prodcode, NULL,
8587 MSIINSTALLCONTEXT_MACHINE,
8588 INSTALLPROPERTY_VERSIONSTRINGA, buf, &sz);
8589 ok(r == ERROR_UNKNOWN_PROPERTY,
8590 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8591 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8592 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8593
8594 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
8595 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8596
8597 /* ProductID value exists */
8598 sz = MAX_PATH;
8599 lstrcpyA(buf, "apple");
8600 r = pMsiGetProductInfoExA(prodcode, NULL,
8601 MSIINSTALLCONTEXT_MACHINE,
8602 INSTALLPROPERTY_PRODUCTIDA, buf, &sz);
8603 ok(r == ERROR_UNKNOWN_PROPERTY,
8604 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8605 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8606 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8607
8608 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
8609 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8610
8611 /* RegCompany value exists */
8612 sz = MAX_PATH;
8613 lstrcpyA(buf, "apple");
8614 r = pMsiGetProductInfoExA(prodcode, NULL,
8615 MSIINSTALLCONTEXT_MACHINE,
8616 INSTALLPROPERTY_REGCOMPANYA, buf, &sz);
8617 ok(r == ERROR_UNKNOWN_PROPERTY,
8618 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8619 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8620 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8621
8622 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8623 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8624
8625 /* RegOwner value exists */
8626 sz = MAX_PATH;
8627 lstrcpyA(buf, "apple");
8628 r = pMsiGetProductInfoExA(prodcode, NULL,
8629 MSIINSTALLCONTEXT_MACHINE,
8630 INSTALLPROPERTY_REGOWNERA, buf, &sz);
8631 ok(r == ERROR_UNKNOWN_PROPERTY,
8632 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
8633 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8634 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8635
8636 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
8637 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8638
8639 /* Transforms value exists */
8640 sz = MAX_PATH;
8641 lstrcpyA(buf, "apple");
8642 r = pMsiGetProductInfoExA(prodcode, NULL,
8643 MSIINSTALLCONTEXT_MACHINE,
8644 INSTALLPROPERTY_TRANSFORMSA, buf, &sz);
8645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8646 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
8647 ok(sz == 5, "Expected 5, got %d\n", sz);
8648
8649 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
8650 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8651
8652 /* Language value exists */
8653 sz = MAX_PATH;
8654 lstrcpyA(buf, "apple");
8655 r = pMsiGetProductInfoExA(prodcode, NULL,
8656 MSIINSTALLCONTEXT_MACHINE,
8657 INSTALLPROPERTY_LANGUAGEA, buf, &sz);
8658 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8659 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
8660 ok(sz == 4, "Expected 4, got %d\n", sz);
8661
8662 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
8663 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8664
8665 /* ProductName value exists */
8666 sz = MAX_PATH;
8667 lstrcpyA(buf, "apple");
8668 r = pMsiGetProductInfoExA(prodcode, NULL,
8669 MSIINSTALLCONTEXT_MACHINE,
8670 INSTALLPROPERTY_PRODUCTNAMEA, buf, &sz);
8671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8672 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
8673 ok(sz == 4, "Expected 4, got %d\n", sz);
8674
8675 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
8676 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8677
8678 /* FIXME */
8679
8680 /* AssignmentType value exists */
8681 sz = MAX_PATH;
8682 lstrcpyA(buf, "apple");
8683 r = pMsiGetProductInfoExA(prodcode, NULL,
8684 MSIINSTALLCONTEXT_MACHINE,
8685 INSTALLPROPERTY_ASSIGNMENTTYPEA, buf, &sz);
8686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8687 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8688 ok(sz == 0, "Expected 0, got %d\n", sz);
8689
8690 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
8691 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8692
8693 /* FIXME */
8694
8695 /* PackageCode value exists */
8696 sz = MAX_PATH;
8697 lstrcpyA(buf, "apple");
8698 r = pMsiGetProductInfoExA(prodcode, NULL,
8699 MSIINSTALLCONTEXT_MACHINE,
8700 INSTALLPROPERTY_PACKAGECODEA, buf, &sz);
8701 todo_wine
8702 {
8703 ok(r == ERROR_BAD_CONFIGURATION,
8704 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8705 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8706 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8707 }
8708
8709 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
8710 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8711
8712 /* Version value exists */
8713 sz = MAX_PATH;
8714 lstrcpyA(buf, "apple");
8715 r = pMsiGetProductInfoExA(prodcode, NULL,
8716 MSIINSTALLCONTEXT_MACHINE,
8717 INSTALLPROPERTY_VERSIONA, buf, &sz);
8718 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8719 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
8720 ok(sz == 3, "Expected 3, got %d\n", sz);
8721
8722 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
8723 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8724
8725 /* ProductIcon value exists */
8726 sz = MAX_PATH;
8727 lstrcpyA(buf, "apple");
8728 r = pMsiGetProductInfoExA(prodcode, NULL,
8729 MSIINSTALLCONTEXT_MACHINE,
8730 INSTALLPROPERTY_PRODUCTICONA, buf, &sz);
8731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8732 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
8733 ok(sz == 4, "Expected 4, got %d\n", sz);
8734
8735 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
8736 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8737
8738 /* PackageName value exists */
8739 sz = MAX_PATH;
8740 lstrcpyA(buf, "apple");
8741 r = pMsiGetProductInfoExA(prodcode, NULL,
8742 MSIINSTALLCONTEXT_MACHINE,
8743 INSTALLPROPERTY_PACKAGENAMEA, buf, &sz);
8744 todo_wine
8745 {
8746 ok(r == ERROR_UNKNOWN_PRODUCT,
8747 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8748 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8749 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8750 }
8751
8752 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
8753 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8754
8755 /* AuthorizedLUAApp value exists */
8756 sz = MAX_PATH;
8757 lstrcpyA(buf, "apple");
8758 r = pMsiGetProductInfoExA(prodcode, NULL,
8759 MSIINSTALLCONTEXT_MACHINE,
8760 INSTALLPROPERTY_AUTHORIZED_LUA_APPA, buf, &sz);
8761 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8762 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
8763 ok(sz == 4, "Expected 4, got %d\n", sz);
8764
8765 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
8766 RegDeleteValueA(prodkey, "PackageName");
8767 RegDeleteValueA(prodkey, "ProductIcon");
8768 RegDeleteValueA(prodkey, "Version");
8769 RegDeleteValueA(prodkey, "PackageCode");
8770 RegDeleteValueA(prodkey, "AssignmentType");
8771 RegDeleteValueA(prodkey, "ProductName");
8772 RegDeleteValueA(prodkey, "Language");
8773 RegDeleteValueA(prodkey, "Transforms");
8774 RegDeleteValueA(prodkey, "RegOwner");
8775 RegDeleteValueA(prodkey, "RegCompany");
8776 RegDeleteValueA(prodkey, "ProductID");
8777 RegDeleteValueA(prodkey, "DisplayVersion");
8778 RegDeleteValueA(prodkey, "VersionMajor");
8779 RegDeleteValueA(prodkey, "VersionMinor");
8780 RegDeleteValueA(prodkey, "URLUpdateInfo");
8781 RegDeleteValueA(prodkey, "URLInfoAbout");
8782 RegDeleteValueA(prodkey, "Publisher");
8783 RegDeleteValueA(prodkey, "LocalPackage");
8784 RegDeleteValueA(prodkey, "InstallSource");
8785 RegDeleteValueA(prodkey, "InstallLocation");
8786 RegDeleteValueA(prodkey, "DisplayName");
8787 RegDeleteValueA(prodkey, "InstallDate");
8788 RegDeleteValueA(prodkey, "HelpTelephone");
8789 RegDeleteValueA(prodkey, "HelpLink");
8790 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8791 RegCloseKey(prodkey);
8792 LocalFree(usersid);
8793 }
8794
8795 #define INIT_USERINFO() \
8796 lstrcpyA(user, "apple"); \
8797 lstrcpyA(org, "orange"); \
8798 lstrcpyA(serial, "banana"); \
8799 usersz = orgsz = serialsz = MAX_PATH;
8800
8801 static void test_MsiGetUserInfo(void)
8802 {
8803 USERINFOSTATE state;
8804 CHAR user[MAX_PATH];
8805 CHAR org[MAX_PATH];
8806 CHAR serial[MAX_PATH];
8807 DWORD usersz, orgsz, serialsz;
8808 CHAR keypath[MAX_PATH * 2];
8809 CHAR prodcode[MAX_PATH];
8810 CHAR prod_squashed[MAX_PATH];
8811 HKEY prodkey, userprod, props;
8812 LPSTR usersid;
8813 LONG res;
8814 REGSAM access = KEY_ALL_ACCESS;
8815
8816 create_test_guid(prodcode, prod_squashed);
8817 usersid = get_user_sid();
8818
8819 if (is_wow64)
8820 access |= KEY_WOW64_64KEY;
8821
8822 /* NULL szProduct */
8823 INIT_USERINFO();
8824 state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
8825 ok(state == USERINFOSTATE_INVALIDARG,
8826 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8827 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8828 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8829 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8830 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8831 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8832 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8833
8834 /* empty szProductCode */
8835 INIT_USERINFO();
8836 state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
8837 ok(state == USERINFOSTATE_INVALIDARG,
8838 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8839 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8840 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8841 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8842 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8843 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8844 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8845
8846 /* garbage szProductCode */
8847 INIT_USERINFO();
8848 state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
8849 ok(state == USERINFOSTATE_INVALIDARG,
8850 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8851 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8852 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8853 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8854 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8855 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8856 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8857
8858 /* guid without brackets */
8859 INIT_USERINFO();
8860 state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
8861 user, &usersz, org, &orgsz, serial, &serialsz);
8862 ok(state == USERINFOSTATE_INVALIDARG,
8863 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8864 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8865 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8866 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8867 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8868 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8869 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8870
8871 /* guid with brackets */
8872 INIT_USERINFO();
8873 state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
8874 user, &usersz, org, &orgsz, serial, &serialsz);
8875 ok(state == USERINFOSTATE_UNKNOWN,
8876 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8877 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8878 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8879 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8880 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8881 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8882 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8883
8884 /* NULL lpUserNameBuf */
8885 INIT_USERINFO();
8886 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8887 ok(state == USERINFOSTATE_UNKNOWN,
8888 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8889 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8890 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8891 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8892 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8893 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8894
8895 /* NULL pcchUserNameBuf */
8896 INIT_USERINFO();
8897 state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
8898 ok(state == USERINFOSTATE_INVALIDARG,
8899 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8900 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8901 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8902 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8903 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8904 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8905
8906 /* both lpUserNameBuf and pcchUserNameBuf NULL */
8907 INIT_USERINFO();
8908 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8909 ok(state == USERINFOSTATE_UNKNOWN,
8910 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8911 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8912 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8913 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8914 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8915
8916 /* NULL lpOrgNameBuf */
8917 INIT_USERINFO();
8918 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
8919 ok(state == USERINFOSTATE_UNKNOWN,
8920 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8921 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8922 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8923 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8924 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8925 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8926
8927 /* NULL pcchOrgNameBuf */
8928 INIT_USERINFO();
8929 state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
8930 ok(state == USERINFOSTATE_INVALIDARG,
8931 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8932 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8933 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8934 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8935 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8936 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8937
8938 /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
8939 INIT_USERINFO();
8940 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
8941 ok(state == USERINFOSTATE_UNKNOWN,
8942 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8943 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8944 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8945 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8946 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8947
8948 /* NULL lpSerialBuf */
8949 INIT_USERINFO();
8950 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
8951 ok(state == USERINFOSTATE_UNKNOWN,
8952 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8953 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8954 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8955 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8956 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8957 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8958
8959 /* NULL pcchSerialBuf */
8960 INIT_USERINFO();
8961 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
8962 ok(state == USERINFOSTATE_INVALIDARG,
8963 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8964 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8965 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8966 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8967 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8968 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8969
8970 /* both lpSerialBuf and pcchSerialBuf NULL */
8971 INIT_USERINFO();
8972 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
8973 ok(state == USERINFOSTATE_UNKNOWN,
8974 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8975 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8976 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8977 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8978 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8979
8980 /* MSIINSTALLCONTEXT_USERMANAGED */
8981
8982 /* create local system product key */
8983 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8984 lstrcatA(keypath, usersid);
8985 lstrcatA(keypath, "\\Installer\\Products\\");
8986 lstrcatA(keypath, prod_squashed);
8987
8988 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8989 if (res == ERROR_ACCESS_DENIED)
8990 {
8991 skip("Not enough rights to perform tests\n");
8992 LocalFree(usersid);
8993 return;
8994 }
8995 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8996
8997 /* managed product key exists */
8998 INIT_USERINFO();
8999 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9000 ok(state == USERINFOSTATE_ABSENT,
9001 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9002 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9003 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
9004 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9005 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
9006 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
9007 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
9008
9009 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9010 lstrcatA(keypath, "Installer\\UserData\\");
9011 lstrcatA(keypath, usersid);
9012 lstrcatA(keypath, "\\Products\\");
9013 lstrcatA(keypath, prod_squashed);
9014
9015 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
9016 if (res == ERROR_ACCESS_DENIED)
9017 {
9018 skip("Not enough rights to perform tests\n");
9019 LocalFree(usersid);
9020 return;
9021 }
9022 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9023
9024 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9025 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9026
9027 /* InstallProperties key exists */
9028 INIT_USERINFO();
9029 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9030 ok(state == USERINFOSTATE_ABSENT,
9031 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9032 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9033 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
9034 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9035 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
9036 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
9037 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
9038
9039 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
9040 INIT_USERINFO();
9041 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
9042 ok(state == USERINFOSTATE_ABSENT,
9043 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9044 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
9045 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9046 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
9047 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9048
9049 /* RegOwner, RegCompany don't exist, out params are NULL */
9050 INIT_USERINFO();
9051 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
9052 ok(state == USERINFOSTATE_ABSENT,
9053 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9054 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9055 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9056
9057 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
9058 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9059
9060 /* RegOwner value exists */
9061 INIT_USERINFO();
9062 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9063 ok(state == USERINFOSTATE_ABSENT,
9064 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9065 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9066 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
9067 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9068 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9069 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
9070 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9071
9072 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
9073 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9074
9075 /* RegCompany value exists */
9076 INIT_USERINFO();
9077 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9078 ok(state == USERINFOSTATE_ABSENT,
9079 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9080 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9081 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9082 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9083 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9084 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9085 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9086
9087 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
9088 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9089
9090 /* ProductID value exists */
9091 INIT_USERINFO();
9092 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9093 ok(state == USERINFOSTATE_PRESENT,
9094 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
9095 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9096 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9097 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
9098 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9099 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9100 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
9101
9102 /* pcchUserNameBuf is too small */
9103 INIT_USERINFO();
9104 usersz = 0;
9105 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9106 ok(state == USERINFOSTATE_MOREDATA,
9107 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
9108 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9109 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
9110 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9111 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9112 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
9113 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
9114
9115 /* pcchUserNameBuf has no room for NULL terminator */
9116 INIT_USERINFO();
9117 usersz = 5;
9118 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9119 ok(state == USERINFOSTATE_MOREDATA,
9120 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
9121 todo_wine
9122 {
9123 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9124 }
9125 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
9126 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9127 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9128 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
9129 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
9130
9131 /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
9132 INIT_USERINFO();
9133 usersz = 0;
9134 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
9135 ok(state == USERINFOSTATE_PRESENT,
9136 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
9137 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9138 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9139 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
9140 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9141 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9142 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
9143
9144 RegDeleteValueA(props, "ProductID");
9145 RegDeleteValueA(props, "RegCompany");
9146 RegDeleteValueA(props, "RegOwner");
9147 delete_key(props, "", access & KEY_WOW64_64KEY);
9148 RegCloseKey(props);
9149 delete_key(userprod, "", access & KEY_WOW64_64KEY);
9150 RegCloseKey(userprod);
9151 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9152 RegCloseKey(prodkey);
9153
9154 /* MSIINSTALLCONTEXT_USERUNMANAGED */
9155
9156 /* create local system product key */
9157 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9158 lstrcatA(keypath, prod_squashed);
9159
9160 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9161 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9162
9163 /* product key exists */
9164 INIT_USERINFO();
9165 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9166 ok(state == USERINFOSTATE_ABSENT,
9167 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9168 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9169 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
9170 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9171 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
9172 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
9173 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
9174
9175 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9176 lstrcatA(keypath, "Installer\\UserData\\");
9177 lstrcatA(keypath, usersid);
9178 lstrcatA(keypath, "\\Products\\");
9179 lstrcatA(keypath, prod_squashed);
9180
9181 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
9182 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9183
9184 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9185 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9186
9187 /* InstallProperties key exists */
9188 INIT_USERINFO();
9189 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9190 ok(state == USERINFOSTATE_ABSENT,
9191 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9192 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9193 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
9194 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9195 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
9196 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
9197 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
9198
9199 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
9200 INIT_USERINFO();
9201 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
9202 ok(state == USERINFOSTATE_ABSENT,
9203 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9204 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
9205 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9206 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
9207 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9208
9209 /* RegOwner, RegCompany don't exist, out params are NULL */
9210 INIT_USERINFO();
9211 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
9212 ok(state == USERINFOSTATE_ABSENT,
9213 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9214 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9215 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9216
9217 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
9218 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9219
9220 /* RegOwner value exists */
9221 INIT_USERINFO();
9222 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9223 ok(state == USERINFOSTATE_ABSENT,
9224 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9225 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9226 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
9227 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9228 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9229 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
9230 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9231
9232 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
9233 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9234
9235 /* RegCompany value exists */
9236 INIT_USERINFO();
9237 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9238 ok(state == USERINFOSTATE_ABSENT,
9239 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9240 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9241 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9242 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9243 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9244 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9245 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9246
9247 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
9248 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9249
9250 /* ProductID value exists */
9251 INIT_USERINFO();
9252 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9253 ok(state == USERINFOSTATE_PRESENT,
9254 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
9255 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9256 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9257 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
9258 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9259 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9260 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
9261
9262 RegDeleteValueA(props, "ProductID");
9263 RegDeleteValueA(props, "RegCompany");
9264 RegDeleteValueA(props, "RegOwner");
9265 delete_key(props, "", access & KEY_WOW64_64KEY);
9266 RegCloseKey(props);
9267 delete_key(userprod, "", access & KEY_WOW64_64KEY);
9268 RegCloseKey(userprod);
9269 RegDeleteKeyA(prodkey, "");
9270 RegCloseKey(prodkey);
9271
9272 /* MSIINSTALLCONTEXT_MACHINE */
9273
9274 /* create local system product key */
9275 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9276 lstrcatA(keypath, prod_squashed);
9277
9278 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9279 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9280
9281 /* product key exists */
9282 INIT_USERINFO();
9283 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9284 ok(state == USERINFOSTATE_ABSENT,
9285 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9286 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9287 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
9288 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9289 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
9290 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
9291 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
9292
9293 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9294 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
9295 lstrcatA(keypath, "\\Products\\");
9296 lstrcatA(keypath, prod_squashed);
9297
9298 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
9299 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9300
9301 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9302 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9303
9304 /* InstallProperties key exists */
9305 INIT_USERINFO();
9306 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9307 ok(state == USERINFOSTATE_ABSENT,
9308 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9309 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
9310 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
9311 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9312 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
9313 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
9314 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
9315
9316 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
9317 INIT_USERINFO();
9318 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
9319 ok(state == USERINFOSTATE_ABSENT,
9320 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9321 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
9322 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9323 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
9324 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9325
9326 /* RegOwner, RegCompany don't exist, out params are NULL */
9327 INIT_USERINFO();
9328 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
9329 ok(state == USERINFOSTATE_ABSENT,
9330 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9331 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9332 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9333
9334 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
9335 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9336
9337 /* RegOwner value exists */
9338 INIT_USERINFO();
9339 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9340 ok(state == USERINFOSTATE_ABSENT,
9341 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9342 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9343 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
9344 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9345 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9346 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
9347 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9348
9349 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
9350 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9351
9352 /* RegCompany value exists */
9353 INIT_USERINFO();
9354 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9355 ok(state == USERINFOSTATE_ABSENT,
9356 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
9357 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9358 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9359 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
9360 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9361 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9362 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
9363
9364 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
9365 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9366
9367 /* ProductID value exists */
9368 INIT_USERINFO();
9369 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
9370 ok(state == USERINFOSTATE_PRESENT,
9371 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
9372 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
9373 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
9374 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
9375 ok(usersz == 5, "Expected 5, got %d\n", usersz);
9376 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
9377 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
9378
9379 RegDeleteValueA(props, "ProductID");
9380 RegDeleteValueA(props, "RegCompany");
9381 RegDeleteValueA(props, "RegOwner");
9382 delete_key(props, "", access & KEY_WOW64_64KEY);
9383 RegCloseKey(props);
9384 delete_key(userprod, "", access & KEY_WOW64_64KEY);
9385 RegCloseKey(userprod);
9386 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9387 RegCloseKey(prodkey);
9388 LocalFree(usersid);
9389 }
9390
9391 static void test_MsiOpenProduct(void)
9392 {
9393 MSIHANDLE hprod, hdb;
9394 CHAR val[MAX_PATH];
9395 CHAR path[MAX_PATH];
9396 CHAR keypath[MAX_PATH*2];
9397 CHAR prodcode[MAX_PATH];
9398 CHAR prod_squashed[MAX_PATH];
9399 HKEY prodkey, userkey, props;
9400 LPSTR usersid;
9401 DWORD size;
9402 LONG res;
9403 UINT r;
9404 REGSAM access = KEY_ALL_ACCESS;
9405
9406 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
9407
9408 GetCurrentDirectoryA(MAX_PATH, path);
9409 lstrcatA(path, "\\");
9410
9411 create_test_guid(prodcode, prod_squashed);
9412 usersid = get_user_sid();
9413
9414 if (is_wow64)
9415 access |= KEY_WOW64_64KEY;
9416
9417 hdb = create_package_db(prodcode);
9418 MsiCloseHandle(hdb);
9419
9420 /* NULL szProduct */
9421 hprod = 0xdeadbeef;
9422 r = MsiOpenProductA(NULL, &hprod);
9423 ok(r == ERROR_INVALID_PARAMETER,
9424 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9425 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9426
9427 /* empty szProduct */
9428 hprod = 0xdeadbeef;
9429 r = MsiOpenProductA("", &hprod);
9430 ok(r == ERROR_INVALID_PARAMETER,
9431 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9432 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9433
9434 /* garbage szProduct */
9435 hprod = 0xdeadbeef;
9436 r = MsiOpenProductA("garbage", &hprod);
9437 ok(r == ERROR_INVALID_PARAMETER,
9438 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9439 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9440
9441 /* guid without brackets */
9442 hprod = 0xdeadbeef;
9443 r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
9444 ok(r == ERROR_INVALID_PARAMETER,
9445 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9446 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9447
9448 /* guid with brackets */
9449 hprod = 0xdeadbeef;
9450 r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
9451 ok(r == ERROR_UNKNOWN_PRODUCT,
9452 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9453 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9454
9455 /* same length as guid, but random */
9456 hprod = 0xdeadbeef;
9457 r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
9458 ok(r == ERROR_INVALID_PARAMETER,
9459 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9460 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9461
9462 /* hProduct is NULL */
9463 hprod = 0xdeadbeef;
9464 r = MsiOpenProductA(prodcode, NULL);
9465 ok(r == ERROR_INVALID_PARAMETER,
9466 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9467 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9468
9469 /* MSIINSTALLCONTEXT_USERMANAGED */
9470
9471 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9472 lstrcatA(keypath, "Installer\\Managed\\");
9473 lstrcatA(keypath, usersid);
9474 lstrcatA(keypath, "\\Installer\\Products\\");
9475 lstrcatA(keypath, prod_squashed);
9476
9477 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9478 if (res == ERROR_ACCESS_DENIED)
9479 {
9480 skip("Not enough rights to perform tests\n");
9481 LocalFree(usersid);
9482 return;
9483 }
9484 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9485
9486 /* managed product key exists */
9487 hprod = 0xdeadbeef;
9488 r = MsiOpenProductA(prodcode, &hprod);
9489 ok(r == ERROR_UNKNOWN_PRODUCT,
9490 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9491 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9492
9493 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9494 lstrcatA(keypath, "Installer\\UserData\\");
9495 lstrcatA(keypath, usersid);
9496 lstrcatA(keypath, "\\Products\\");
9497 lstrcatA(keypath, prod_squashed);
9498
9499 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9500 if (res == ERROR_ACCESS_DENIED)
9501 {
9502 skip("Not enough rights to perform tests\n");
9503 LocalFree(usersid);
9504 return;
9505 }
9506 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9507
9508 /* user product key exists */
9509 hprod = 0xdeadbeef;
9510 r = MsiOpenProductA(prodcode, &hprod);
9511 ok(r == ERROR_UNKNOWN_PRODUCT,
9512 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9513 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9514
9515 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9516 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9517
9518 /* InstallProperties key exists */
9519 hprod = 0xdeadbeef;
9520 r = MsiOpenProductA(prodcode, &hprod);
9521 ok(r == ERROR_UNKNOWN_PRODUCT,
9522 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9523 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9524
9525 lstrcpyA(val, path);
9526 lstrcatA(val, "\\winetest.msi");
9527 res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
9528 (const BYTE *)val, lstrlenA(val) + 1);
9529 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9530
9531 /* ManagedLocalPackage value exists */
9532 hprod = 0xdeadbeef;
9533 r = MsiOpenProductA(prodcode, &hprod);
9534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9535 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9536
9537 size = MAX_PATH;
9538 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9539 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9540 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9541 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9542
9543 MsiCloseHandle(hprod);
9544
9545 RegDeleteValueA(props, "ManagedLocalPackage");
9546 delete_key(props, "", access & KEY_WOW64_64KEY);
9547 RegCloseKey(props);
9548 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9549 RegCloseKey(userkey);
9550 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9551 RegCloseKey(prodkey);
9552
9553 /* MSIINSTALLCONTEXT_USERUNMANAGED */
9554
9555 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9556 lstrcatA(keypath, prod_squashed);
9557
9558 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9559 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9560
9561 /* unmanaged product key exists */
9562 hprod = 0xdeadbeef;
9563 r = MsiOpenProductA(prodcode, &hprod);
9564 ok(r == ERROR_UNKNOWN_PRODUCT,
9565 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9566 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9567
9568 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9569 lstrcatA(keypath, "Installer\\UserData\\");
9570 lstrcatA(keypath, usersid);
9571 lstrcatA(keypath, "\\Products\\");
9572 lstrcatA(keypath, prod_squashed);
9573
9574 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9575 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9576
9577 /* user product key exists */
9578 hprod = 0xdeadbeef;
9579 r = MsiOpenProductA(prodcode, &hprod);
9580 ok(r == ERROR_UNKNOWN_PRODUCT,
9581 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9582 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9583
9584 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9585 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9586
9587 /* InstallProperties key exists */
9588 hprod = 0xdeadbeef;
9589 r = MsiOpenProductA(prodcode, &hprod);
9590 ok(r == ERROR_UNKNOWN_PRODUCT,
9591 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9592 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9593
9594 lstrcpyA(val, path);
9595 lstrcatA(val, "\\winetest.msi");
9596 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9597 (const BYTE *)val, lstrlenA(val) + 1);
9598 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9599
9600 /* LocalPackage value exists */
9601 hprod = 0xdeadbeef;
9602 r = MsiOpenProductA(prodcode, &hprod);
9603 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9604 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9605
9606 size = MAX_PATH;
9607 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9608 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9609 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9610 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9611
9612 MsiCloseHandle(hprod);
9613
9614 RegDeleteValueA(props, "LocalPackage");
9615 delete_key(props, "", access & KEY_WOW64_64KEY);
9616 RegCloseKey(props);
9617 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9618 RegCloseKey(userkey);
9619 RegDeleteKeyA(prodkey, "");
9620 RegCloseKey(prodkey);
9621
9622 /* MSIINSTALLCONTEXT_MACHINE */
9623
9624 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9625 lstrcatA(keypath, prod_squashed);
9626
9627 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9628 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9629
9630 /* managed product key exists */
9631 hprod = 0xdeadbeef;
9632 r = MsiOpenProductA(prodcode, &hprod);
9633 ok(r == ERROR_UNKNOWN_PRODUCT,
9634 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9635 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9636
9637 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9638 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9639 lstrcatA(keypath, prod_squashed);
9640
9641 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9642 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9643
9644 /* user product key exists */
9645 hprod = 0xdeadbeef;
9646 r = MsiOpenProductA(prodcode, &hprod);
9647 ok(r == ERROR_UNKNOWN_PRODUCT,
9648 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9649 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9650
9651 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9653
9654 /* InstallProperties key exists */
9655 hprod = 0xdeadbeef;
9656 r = MsiOpenProductA(prodcode, &hprod);
9657 ok(r == ERROR_UNKNOWN_PRODUCT,
9658 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9659 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9660
9661 lstrcpyA(val, path);
9662 lstrcatA(val, "\\winetest.msi");
9663 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9664 (const BYTE *)val, lstrlenA(val) + 1);
9665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9666
9667 /* LocalPackage value exists */
9668 hprod = 0xdeadbeef;
9669 r = MsiOpenProductA(prodcode, &hprod);
9670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9671 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9672
9673 size = MAX_PATH;
9674 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9675 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9676 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9677 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9678
9679 MsiCloseHandle(hprod);
9680
9681 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9682 (const BYTE *)"winetest.msi", 13);
9683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9684
9685 lstrcpyA(val, path);
9686 lstrcatA(val, "\\winetest.msi");
9687 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9688 (const BYTE *)val, lstrlenA(val) + 1);
9689 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9690
9691 DeleteFileA(msifile);
9692
9693 /* local package does not exist */
9694 hprod = 0xdeadbeef;
9695 r = MsiOpenProductA(prodcode, &hprod);
9696 ok(r == ERROR_UNKNOWN_PRODUCT,
9697 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9698 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9699
9700 RegDeleteValueA(props, "LocalPackage");
9701 delete_key(props, "", access & KEY_WOW64_64KEY);
9702 RegCloseKey(props);
9703 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9704 RegCloseKey(userkey);
9705 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9706 RegCloseKey(prodkey);
9707
9708 DeleteFileA(msifile);
9709 LocalFree(usersid);
9710 }
9711
9712 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
9713 {
9714 MSIINSTALLCONTEXT context;
9715 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9716 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9717 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9718 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9719 HKEY prodkey, patches, udprod, udpatch, hpatch;
9720 DWORD size, data;
9721 LONG res;
9722 UINT r;
9723 REGSAM access = KEY_ALL_ACCESS;
9724
9725 create_test_guid(prodcode, prod_squashed);
9726 create_test_guid(patch, patch_squashed);
9727
9728 if (is_wow64)
9729 access |= KEY_WOW64_64KEY;
9730
9731 /* MSIPATCHSTATE_APPLIED */
9732
9733 lstrcpyA(patchcode, "apple");
9734 lstrcpyA(targetprod, "banana");
9735 context = 0xdeadbeef;
9736 lstrcpyA(targetsid, "kiwi");
9737 size = MAX_PATH;
9738 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9739 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9740 &context, targetsid, &size);
9741 if (r == ERROR_ACCESS_DENIED)
9742 {
9743 skip("Not enough rights to perform tests\n");
9744 return;
9745 }
9746 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9747 ok(!lstrcmpA(patchcode, "apple"),
9748 "Expected patchcode to be unchanged, got %s\n", patchcode);
9749 ok(!lstrcmpA(targetprod, "banana"),
9750 "Expected targetprod to be unchanged, got %s\n", targetprod);
9751 ok(context == 0xdeadbeef,
9752 "Expected context to be unchanged, got %d\n", context);
9753 ok(!lstrcmpA(targetsid, "kiwi"),
9754 "Expected targetsid to be unchanged, got %s\n", targetsid);
9755 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9756
9757 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9758 lstrcatA(keypath, expectedsid);
9759 lstrcatA(keypath, "\\Installer\\Products\\");
9760 lstrcatA(keypath, prod_squashed);
9761
9762 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9763 if (res == ERROR_ACCESS_DENIED)
9764 {
9765 skip("Not enough rights to perform tests\n");
9766 return;
9767 }
9768 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9769
9770 /* managed product key exists */
9771 lstrcpyA(patchcode, "apple");
9772 lstrcpyA(targetprod, "banana");
9773 context = 0xdeadbeef;
9774 lstrcpyA(targetsid, "kiwi");
9775 size = MAX_PATH;
9776 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9777 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9778 &context, targetsid, &size);
9779 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9780 ok(!lstrcmpA(patchcode, "apple"),
9781 "Expected patchcode to be unchanged, got %s\n", patchcode);
9782 ok(!lstrcmpA(targetprod, "banana"),
9783 "Expected targetprod to be unchanged, got %s\n", targetprod);
9784 ok(context == 0xdeadbeef,
9785 "Expected context to be unchanged, got %d\n", context);
9786 ok(!lstrcmpA(targetsid, "kiwi"),
9787 "Expected targetsid to be unchanged, got %s\n", targetsid);
9788 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9789
9790 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9791 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9792
9793 /* patches key exists */
9794 lstrcpyA(patchcode, "apple");
9795 lstrcpyA(targetprod, "banana");
9796 context = 0xdeadbeef;
9797 lstrcpyA(targetsid, "kiwi");
9798 size = MAX_PATH;
9799 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9800 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9801 &context, targetsid, &size);
9802 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9803 ok(!lstrcmpA(patchcode, "apple"),
9804 "Expected patchcode to be unchanged, got %s\n", patchcode);
9805 ok(!lstrcmpA(targetprod, "banana"),
9806 "Expected targetprod to be unchanged, got %s\n", targetprod);
9807 ok(context == 0xdeadbeef,
9808 "Expected context to be unchanged, got %d\n", context);
9809 ok(!lstrcmpA(targetsid, "kiwi"),
9810 "Expected targetsid to be unchanged, got %s\n", targetsid);
9811 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9812
9813 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9814 (const BYTE *)patch_squashed,
9815 lstrlenA(patch_squashed) + 1);
9816 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9817
9818 /* Patches value exists, is not REG_MULTI_SZ */
9819 lstrcpyA(patchcode, "apple");
9820 lstrcpyA(targetprod, "banana");
9821 context = 0xdeadbeef;
9822 lstrcpyA(targetsid, "kiwi");
9823 size = MAX_PATH;
9824 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9825 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9826 &context, targetsid, &size);
9827 ok(r == ERROR_BAD_CONFIGURATION,
9828 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9829 ok(!lstrcmpA(patchcode, "apple"),
9830 "Expected patchcode to be unchanged, got %s\n", patchcode);
9831 ok(!lstrcmpA(targetprod, "banana"),
9832 "Expected targetprod to be unchanged, got %s\n", targetprod);
9833 ok(context == 0xdeadbeef,
9834 "Expected context to be unchanged, got %d\n", context);
9835 ok(!lstrcmpA(targetsid, "kiwi"),
9836 "Expected targetsid to be unchanged, got %s\n", targetsid);
9837 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9838
9839 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9840 (const BYTE *)"a\0b\0c\0\0", 7);
9841 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9842
9843 /* Patches value exists, is not a squashed guid */
9844 lstrcpyA(patchcode, "apple");
9845 lstrcpyA(targetprod, "banana");
9846 context = 0xdeadbeef;
9847 lstrcpyA(targetsid, "kiwi");
9848 size = MAX_PATH;
9849 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9850 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9851 &context, targetsid, &size);
9852 ok(r == ERROR_BAD_CONFIGURATION,
9853 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9854 ok(!lstrcmpA(patchcode, "apple"),
9855 "Expected patchcode to be unchanged, got %s\n", patchcode);
9856 ok(!lstrcmpA(targetprod, "banana"),
9857 "Expected targetprod to be unchanged, got %s\n", targetprod);
9858 ok(context == 0xdeadbeef,
9859 "Expected context to be unchanged, got %d\n", context);
9860 ok(!lstrcmpA(targetsid, "kiwi"),
9861 "Expected targetsid to be unchanged, got %s\n", targetsid);
9862 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9863
9864 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9865 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9866 (const BYTE *)patch_squashed,
9867 lstrlenA(patch_squashed) + 2);
9868 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9869
9870 /* Patches value exists */
9871 lstrcpyA(patchcode, "apple");
9872 lstrcpyA(targetprod, "banana");
9873 context = 0xdeadbeef;
9874 lstrcpyA(targetsid, "kiwi");
9875 size = MAX_PATH;
9876 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9877 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9878 &context, targetsid, &size);
9879 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9880 ok(!lstrcmpA(patchcode, "apple"),
9881 "Expected patchcode to be unchanged, got %s\n", patchcode);
9882 ok(!lstrcmpA(targetprod, "banana"),
9883 "Expected targetprod to be unchanged, got %s\n", targetprod);
9884 ok(context == 0xdeadbeef,
9885 "Expected context to be unchanged, got %d\n", context);
9886 ok(!lstrcmpA(targetsid, "kiwi"),
9887 "Expected targetsid to be unchanged, got %s\n", targetsid);
9888 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9889
9890 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9891 (const BYTE *)"whatever", 9);
9892 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9893
9894 /* patch squashed value exists */
9895 lstrcpyA(patchcode, "apple");
9896 lstrcpyA(targetprod, "banana");
9897 context = 0xdeadbeef;
9898 lstrcpyA(targetsid, "kiwi");
9899 size = MAX_PATH;
9900 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9901 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9902 &context, targetsid, &size);
9903 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9904 ok(!lstrcmpA(patchcode, patch),
9905 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9906 ok(!lstrcmpA(targetprod, prodcode),
9907 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9908 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9909 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9910 ok(!lstrcmpA(targetsid, expectedsid),
9911 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9912 ok(size == lstrlenA(expectedsid),
9913 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9914
9915 /* increase the index */
9916 lstrcpyA(patchcode, "apple");
9917 lstrcpyA(targetprod, "banana");
9918 context = 0xdeadbeef;
9919 lstrcpyA(targetsid, "kiwi");
9920 size = MAX_PATH;
9921 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9922 MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
9923 &context, targetsid, &size);
9924 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9925 ok(!lstrcmpA(patchcode, "apple"),
9926 "Expected patchcode to be unchanged, got %s\n", patchcode);
9927 ok(!lstrcmpA(targetprod, "banana"),
9928 "Expected targetprod to be unchanged, got %s\n", targetprod);
9929 ok(context == 0xdeadbeef,
9930 "Expected context to be unchanged, got %d\n", context);
9931 ok(!lstrcmpA(targetsid, "kiwi"),
9932 "Expected targetsid to be unchanged, got %s\n", targetsid);
9933 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9934
9935 /* increase again */
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_USERMANAGED,
9942 MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
9943 &context, targetsid, &size);
9944 ok(r == ERROR_INVALID_PARAMETER,
9945 "Expected ERROR_INVALID_PARAMETER, 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 /* szPatchCode is NULL */
9957 lstrcpyA(targetprod, "banana");
9958 context = 0xdeadbeef;
9959 lstrcpyA(targetsid, "kiwi");
9960 size = MAX_PATH;
9961 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9962 MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
9963 &context, targetsid, &size);
9964 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9965 ok(!lstrcmpA(targetprod, prodcode),
9966 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9967 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9968 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9969 ok(!lstrcmpA(targetsid, expectedsid),
9970 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9971 ok(size == lstrlenA(expectedsid),
9972 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9973
9974 /* szTargetProductCode is NULL */
9975 lstrcpyA(patchcode, "apple");
9976 context = 0xdeadbeef;
9977 lstrcpyA(targetsid, "kiwi");
9978 size = MAX_PATH;
9979 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9980 MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
9981 &context, targetsid, &size);
9982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9983 ok(!lstrcmpA(patchcode, patch),
9984 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9985 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9986 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9987 ok(!lstrcmpA(targetsid, expectedsid),
9988 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9989 ok(size == lstrlenA(expectedsid),
9990 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9991
9992 /* pdwTargetProductContext is NULL */
9993 lstrcpyA(patchcode, "apple");
9994 lstrcpyA(targetprod, "banana");
9995 lstrcpyA(targetsid, "kiwi");
9996 size = MAX_PATH;
9997 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9998 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9999 NULL, targetsid, &size);
10000 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10001 ok(!lstrcmpA(patchcode, patch),
10002 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10003 ok(!lstrcmpA(targetprod, prodcode),
10004 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10005 ok(!lstrcmpA(targetsid, expectedsid),
10006 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10007 ok(size == lstrlenA(expectedsid),
10008 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10009
10010 /* szTargetUserSid is NULL */
10011 lstrcpyA(patchcode, "apple");
10012 lstrcpyA(targetprod, "banana");
10013 context = 0xdeadbeef;
10014 size = MAX_PATH;
10015 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10016 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10017 &context, NULL, &size);
10018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10019 ok(!lstrcmpA(patchcode, patch),
10020 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10021 ok(!lstrcmpA(targetprod, prodcode),
10022 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10023 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
10024 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
10025 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
10026 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
10027
10028 /* pcchTargetUserSid is exactly the length of szTargetUserSid */
10029 lstrcpyA(patchcode, "apple");
10030 lstrcpyA(targetprod, "banana");
10031 context = 0xdeadbeef;
10032 lstrcpyA(targetsid, "kiwi");
10033 size = lstrlenA(expectedsid);
10034 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10035 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10036 &context, targetsid, &size);
10037 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10038 ok(!lstrcmpA(patchcode, patch),
10039 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10040 ok(!lstrcmpA(targetprod, prodcode),
10041 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10042 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
10043 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
10044 ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
10045 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10046 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
10047 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
10048
10049 /* pcchTargetUserSid has enough room for NULL terminator */
10050 lstrcpyA(patchcode, "apple");
10051 lstrcpyA(targetprod, "banana");
10052 context = 0xdeadbeef;
10053 lstrcpyA(targetsid, "kiwi");
10054 size = lstrlenA(expectedsid) + 1;
10055 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10056 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10057 &context, targetsid, &size);
10058 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10059 ok(!lstrcmpA(patchcode, patch),
10060 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10061 ok(!lstrcmpA(targetprod, prodcode),
10062 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10063 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
10064 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
10065 ok(!lstrcmpA(targetsid, expectedsid),
10066 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10067 ok(size == lstrlenA(expectedsid),
10068 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10069
10070 /* both szTargetuserSid and pcchTargetUserSid are NULL */
10071 lstrcpyA(patchcode, "apple");
10072 lstrcpyA(targetprod, "banana");
10073 context = 0xdeadbeef;
10074 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10075 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10076 &context, NULL, NULL);
10077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10078 ok(!lstrcmpA(patchcode, patch),
10079 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10080 ok(!lstrcmpA(targetprod, prodcode),
10081 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10082 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
10083 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
10084
10085 /* MSIPATCHSTATE_SUPERSEDED */
10086
10087 lstrcpyA(patchcode, "apple");
10088 lstrcpyA(targetprod, "banana");
10089 context = 0xdeadbeef;
10090 lstrcpyA(targetsid, "kiwi");
10091 size = MAX_PATH;
10092 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10093 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10094 &context, targetsid, &size);
10095 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10096 ok(!lstrcmpA(patchcode, "apple"),
10097 "Expected patchcode to be unchanged, got %s\n", patchcode);
10098 ok(!lstrcmpA(targetprod, "banana"),
10099 "Expected targetprod to be unchanged, got %s\n", targetprod);
10100 ok(context == 0xdeadbeef,
10101 "Expected context to be unchanged, got %d\n", context);
10102 ok(!lstrcmpA(targetsid, "kiwi"),
10103 "Expected targetsid to be unchanged, got %s\n", targetsid);
10104 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10105
10106 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10107 lstrcatA(keypath, expectedsid);
10108 lstrcatA(keypath, "\\Products\\");
10109 lstrcatA(keypath, prod_squashed);
10110
10111 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10112 if (res == ERROR_ACCESS_DENIED)
10113 {
10114 skip("Not enough rights to perform tests\n");
10115 return;
10116 }
10117 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10118
10119 /* UserData product key exists */
10120 lstrcpyA(patchcode, "apple");
10121 lstrcpyA(targetprod, "banana");
10122 context = 0xdeadbeef;
10123 lstrcpyA(targetsid, "kiwi");
10124 size = MAX_PATH;
10125 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10126 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10127 &context, targetsid, &size);
10128 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10129 ok(!lstrcmpA(patchcode, "apple"),
10130 "Expected patchcode to be unchanged, got %s\n", patchcode);
10131 ok(!lstrcmpA(targetprod, "banana"),
10132 "Expected targetprod to be unchanged, got %s\n", targetprod);
10133 ok(context == 0xdeadbeef,
10134 "Expected context to be unchanged, got %d\n", context);
10135 ok(!lstrcmpA(targetsid, "kiwi"),
10136 "Expected targetsid to be unchanged, got %s\n", targetsid);
10137 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10138
10139 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10140 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10141
10142 /* UserData patches key exists */
10143 lstrcpyA(patchcode, "apple");
10144 lstrcpyA(targetprod, "banana");
10145 context = 0xdeadbeef;
10146 lstrcpyA(targetsid, "kiwi");
10147 size = MAX_PATH;
10148 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10149 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10150 &context, targetsid, &size);
10151 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10152 ok(!lstrcmpA(patchcode, "apple"),
10153 "Expected patchcode to be unchanged, got %s\n", patchcode);
10154 ok(!lstrcmpA(targetprod, "banana"),
10155 "Expected targetprod to be unchanged, got %s\n", targetprod);
10156 ok(context == 0xdeadbeef,
10157 "Expected context to be unchanged, got %d\n", context);
10158 ok(!lstrcmpA(targetsid, "kiwi"),
10159 "Expected targetsid to be unchanged, got %s\n", targetsid);
10160 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10161
10162 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10163 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10164
10165 /* specific UserData patch key exists */
10166 lstrcpyA(patchcode, "apple");
10167 lstrcpyA(targetprod, "banana");
10168 context = 0xdeadbeef;
10169 lstrcpyA(targetsid, "kiwi");
10170 size = MAX_PATH;
10171 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10172 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10173 &context, targetsid, &size);
10174 ok(r == ERROR_BAD_CONFIGURATION,
10175 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10176 ok(!lstrcmpA(patchcode, "apple"),
10177 "Expected patchcode to be unchanged, got %s\n", patchcode);
10178 ok(!lstrcmpA(targetprod, "banana"),
10179 "Expected targetprod to be unchanged, got %s\n", targetprod);
10180 ok(context == 0xdeadbeef,
10181 "Expected context to be unchanged, got %d\n", context);
10182 ok(!lstrcmpA(targetsid, "kiwi"),
10183 "Expected targetsid to be unchanged, got %s\n", targetsid);
10184 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10185
10186 data = MSIPATCHSTATE_SUPERSEDED;
10187 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10188 (const BYTE *)&data, sizeof(DWORD));
10189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10190
10191 /* State value exists */
10192 lstrcpyA(patchcode, "apple");
10193 lstrcpyA(targetprod, "banana");
10194 context = 0xdeadbeef;
10195 lstrcpyA(targetsid, "kiwi");
10196 size = MAX_PATH;
10197 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10198 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10199 &context, targetsid, &size);
10200 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10201 ok(!lstrcmpA(patchcode, patch),
10202 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10203 ok(!lstrcmpA(targetprod, prodcode),
10204 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10205 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
10206 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
10207 ok(!lstrcmpA(targetsid, expectedsid),
10208 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10209 ok(size == lstrlenA(expectedsid),
10210 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10211
10212 /* MSIPATCHSTATE_OBSOLETED */
10213
10214 lstrcpyA(patchcode, "apple");
10215 lstrcpyA(targetprod, "banana");
10216 context = 0xdeadbeef;
10217 lstrcpyA(targetsid, "kiwi");
10218 size = MAX_PATH;
10219 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10220 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10221 &context, targetsid, &size);
10222 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10223 ok(!lstrcmpA(patchcode, "apple"),
10224 "Expected patchcode to be unchanged, got %s\n", patchcode);
10225 ok(!lstrcmpA(targetprod, "banana"),
10226 "Expected targetprod to be unchanged, got %s\n", targetprod);
10227 ok(context == 0xdeadbeef,
10228 "Expected context to be unchanged, got %d\n", context);
10229 ok(!lstrcmpA(targetsid, "kiwi"),
10230 "Expected targetsid to be unchanged, got %s\n", targetsid);
10231 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10232
10233 data = MSIPATCHSTATE_OBSOLETED;
10234 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10235 (const BYTE *)&data, sizeof(DWORD));
10236 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10237
10238 /* State value is obsoleted */
10239 lstrcpyA(patchcode, "apple");
10240 lstrcpyA(targetprod, "banana");
10241 context = 0xdeadbeef;
10242 lstrcpyA(targetsid, "kiwi");
10243 size = MAX_PATH;
10244 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10245 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10246 &context, targetsid, &size);
10247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10248 ok(!lstrcmpA(patchcode, patch),
10249 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10250 ok(!lstrcmpA(targetprod, prodcode),
10251 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10252 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
10253 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
10254 ok(!lstrcmpA(targetsid, expectedsid),
10255 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10256 ok(size == lstrlenA(expectedsid),
10257 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10258
10259 /* MSIPATCHSTATE_REGISTERED */
10260 /* FIXME */
10261
10262 /* MSIPATCHSTATE_ALL */
10263
10264 /* 1st */
10265 lstrcpyA(patchcode, "apple");
10266 lstrcpyA(targetprod, "banana");
10267 context = 0xdeadbeef;
10268 lstrcpyA(targetsid, "kiwi");
10269 size = MAX_PATH;
10270 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10271 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10272 &context, targetsid, &size);
10273 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10274 ok(!lstrcmpA(patchcode, patch),
10275 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10276 ok(!lstrcmpA(targetprod, prodcode),
10277 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10278 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
10279 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
10280 ok(!lstrcmpA(targetsid, expectedsid),
10281 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10282 ok(size == lstrlenA(expectedsid),
10283 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10284
10285 /* same patch in multiple places, only one is enumerated */
10286 lstrcpyA(patchcode, "apple");
10287 lstrcpyA(targetprod, "banana");
10288 context = 0xdeadbeef;
10289 lstrcpyA(targetsid, "kiwi");
10290 size = MAX_PATH;
10291 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
10292 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10293 &context, targetsid, &size);
10294 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10295 ok(!lstrcmpA(patchcode, "apple"),
10296 "Expected patchcode to be unchanged, got %s\n", patchcode);
10297 ok(!lstrcmpA(targetprod, "banana"),
10298 "Expected targetprod to be unchanged, got %s\n", targetprod);
10299 ok(context == 0xdeadbeef,
10300 "Expected context to be unchanged, got %d\n", context);
10301 ok(!lstrcmpA(targetsid, "kiwi"),
10302 "Expected targetsid to be unchanged, got %s\n", targetsid);
10303 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10304
10305 RegDeleteValueA(hpatch, "State");
10306 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10307 RegCloseKey(hpatch);
10308 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10309 RegCloseKey(udpatch);
10310 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10311 RegCloseKey(udprod);
10312 RegDeleteValueA(patches, "Patches");
10313 delete_key(patches, "", access & KEY_WOW64_64KEY);
10314 RegCloseKey(patches);
10315 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10316 RegCloseKey(prodkey);
10317 }
10318
10319 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
10320 {
10321 MSIINSTALLCONTEXT context;
10322 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10323 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
10324 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10325 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10326 HKEY prodkey, patches, udprod, udpatch;
10327 HKEY userkey, hpatch;
10328 DWORD size, data;
10329 LONG res;
10330 UINT r;
10331 REGSAM access = KEY_ALL_ACCESS;
10332
10333 create_test_guid(prodcode, prod_squashed);
10334 create_test_guid(patch, patch_squashed);
10335
10336 if (is_wow64)
10337 access |= KEY_WOW64_64KEY;
10338
10339 /* MSIPATCHSTATE_APPLIED */
10340
10341 lstrcpyA(patchcode, "apple");
10342 lstrcpyA(targetprod, "banana");
10343 context = 0xdeadbeef;
10344 lstrcpyA(targetsid, "kiwi");
10345 size = MAX_PATH;
10346 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10347 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10348 &context, targetsid, &size);
10349 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10350 ok(!lstrcmpA(patchcode, "apple"),
10351 "Expected patchcode to be unchanged, got %s\n", patchcode);
10352 ok(!lstrcmpA(targetprod, "banana"),
10353 "Expected targetprod to be unchanged, got %s\n", targetprod);
10354 ok(context == 0xdeadbeef,
10355 "Expected context to be unchanged, got %d\n", context);
10356 ok(!lstrcmpA(targetsid, "kiwi"),
10357 "Expected targetsid to be unchanged, got %s\n", targetsid);
10358 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10359
10360 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10361 lstrcatA(keypath, prod_squashed);
10362
10363 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10364 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10365
10366 /* current user product key exists */
10367 lstrcpyA(patchcode, "apple");
10368 lstrcpyA(targetprod, "banana");
10369 context = 0xdeadbeef;
10370 lstrcpyA(targetsid, "kiwi");
10371 size = MAX_PATH;
10372 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10373 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10374 &context, targetsid, &size);
10375 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10376 ok(!lstrcmpA(patchcode, "apple"),
10377 "Expected patchcode to be unchanged, got %s\n", patchcode);
10378 ok(!lstrcmpA(targetprod, "banana"),
10379 "Expected targetprod to be unchanged, got %s\n", targetprod);
10380 ok(context == 0xdeadbeef,
10381 "Expected context to be unchanged, got %d\n", context);
10382 ok(!lstrcmpA(targetsid, "kiwi"),
10383 "Expected targetsid to be unchanged, got %s\n", targetsid);
10384 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10385
10386 res = RegCreateKeyA(prodkey, "Patches", &patches);
10387 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10388
10389 /* Patches key exists */
10390 lstrcpyA(patchcode, "apple");
10391 lstrcpyA(targetprod, "banana");
10392 context = 0xdeadbeef;
10393 lstrcpyA(targetsid, "kiwi");
10394 size = MAX_PATH;
10395 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10396 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10397 &context, targetsid, &size);
10398 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10399 ok(!lstrcmpA(patchcode, "apple"),
10400 "Expected patchcode to be unchanged, got %s\n", patchcode);
10401 ok(!lstrcmpA(targetprod, "banana"),
10402 "Expected targetprod to be unchanged, got %s\n", targetprod);
10403 ok(context == 0xdeadbeef,
10404 "Expected context to be unchanged, got %d\n", context);
10405 ok(!lstrcmpA(targetsid, "kiwi"),
10406 "Expected targetsid to be unchanged, got %s\n", targetsid);
10407 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10408
10409 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10410 (const BYTE *)patch_squashed,
10411 lstrlenA(patch_squashed) + 1);
10412 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10413
10414 /* Patches value exists, is not REG_MULTI_SZ */
10415 lstrcpyA(patchcode, "apple");
10416 lstrcpyA(targetprod, "banana");
10417 context = 0xdeadbeef;
10418 lstrcpyA(targetsid, "kiwi");
10419 size = MAX_PATH;
10420 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10421 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10422 &context, targetsid, &size);
10423 ok(r == ERROR_BAD_CONFIGURATION,
10424 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10425 ok(!lstrcmpA(patchcode, "apple"),
10426 "Expected patchcode to be unchanged, got %s\n", patchcode);
10427 ok(!lstrcmpA(targetprod, "banana"),
10428 "Expected targetprod to be unchanged, got %s\n", targetprod);
10429 ok(context == 0xdeadbeef,
10430 "Expected context to be unchanged, got %d\n", context);
10431 ok(!lstrcmpA(targetsid, "kiwi"),
10432 "Expected targetsid to be unchanged, got %s\n", targetsid);
10433 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10434
10435 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10436 (const BYTE *)"a\0b\0c\0\0", 7);
10437 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10438
10439 /* Patches value exists, is not a squashed guid */
10440 lstrcpyA(patchcode, "apple");
10441 lstrcpyA(targetprod, "banana");
10442 context = 0xdeadbeef;
10443 lstrcpyA(targetsid, "kiwi");
10444 size = MAX_PATH;
10445 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10446 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10447 &context, targetsid, &size);
10448 ok(r == ERROR_BAD_CONFIGURATION,
10449 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10450 ok(!lstrcmpA(patchcode, "apple"),
10451 "Expected patchcode to be unchanged, got %s\n", patchcode);
10452 ok(!lstrcmpA(targetprod, "banana"),
10453 "Expected targetprod to be unchanged, got %s\n", targetprod);
10454 ok(context == 0xdeadbeef,
10455 "Expected context to be unchanged, got %d\n", context);
10456 ok(!lstrcmpA(targetsid, "kiwi"),
10457 "Expected targetsid to be unchanged, got %s\n", targetsid);
10458 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10459
10460 patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
10461 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10462 (const BYTE *)patch_squashed,
10463 lstrlenA(patch_squashed) + 2);
10464 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10465
10466 /* Patches value exists */
10467 lstrcpyA(patchcode, "apple");
10468 lstrcpyA(targetprod, "banana");
10469 context = 0xdeadbeef;
10470 lstrcpyA(targetsid, "kiwi");
10471 size = MAX_PATH;
10472 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10473 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10474 &context, targetsid, &size);
10475 ok(r == ERROR_NO_MORE_ITEMS ||
10476 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
10477 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10478 ok(!lstrcmpA(patchcode, "apple"),
10479 "Expected patchcode to be unchanged, got %s\n", patchcode);
10480 ok(!lstrcmpA(targetprod, "banana"),
10481 "Expected targetprod to be unchanged, got %s\n", targetprod);
10482 ok(context == 0xdeadbeef,
10483 "Expected context to be unchanged, got %d\n", context);
10484 ok(!lstrcmpA(targetsid, "kiwi"),
10485 "Expected targetsid to be unchanged, got %s\n", targetsid);
10486 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10487
10488 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10489 (const BYTE *)"whatever", 9);
10490 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10491
10492 /* patch code value exists */
10493 lstrcpyA(patchcode, "apple");
10494 lstrcpyA(targetprod, "banana");
10495 context = 0xdeadbeef;
10496 lstrcpyA(targetsid, "kiwi");
10497 size = MAX_PATH;
10498 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10499 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10500 &context, targetsid, &size);
10501 ok(r == ERROR_NO_MORE_ITEMS ||
10502 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
10503 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10504 ok(!lstrcmpA(patchcode, "apple"),
10505 "Expected patchcode to be unchanged, got %s\n", patchcode);
10506 ok(!lstrcmpA(targetprod, "banana"),
10507 "Expected targetprod to be unchanged, got %s\n", targetprod);
10508 ok(context == 0xdeadbeef,
10509 "Expected context to be unchanged, got %d\n", context);
10510 ok(!lstrcmpA(targetsid, "kiwi"),
10511 "Expected targetsid to be unchanged, got %s\n", targetsid);
10512 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10513
10514 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10515 lstrcatA(keypath, expectedsid);
10516 lstrcatA(keypath, "\\Patches\\");
10517 lstrcatA(keypath, patch_squashed);
10518
10519 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10520 if (res == ERROR_ACCESS_DENIED)
10521 {
10522 skip("Not enough rights to perform tests\n");
10523 goto error;
10524 }
10525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10526
10527 /* userdata patch key exists */
10528 lstrcpyA(patchcode, "apple");
10529 lstrcpyA(targetprod, "banana");
10530 context = 0xdeadbeef;
10531 lstrcpyA(targetsid, "kiwi");
10532 size = MAX_PATH;
10533 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10534 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10535 &context, targetsid, &size);
10536 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10537 ok(!lstrcmpA(patchcode, patch),
10538 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10539 ok(!lstrcmpA(targetprod, prodcode),
10540 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10541 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10542 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10543 ok(!lstrcmpA(targetsid, expectedsid),
10544 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10545 ok(size == lstrlenA(expectedsid),
10546 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10547
10548 /* MSIPATCHSTATE_SUPERSEDED */
10549
10550 lstrcpyA(patchcode, "apple");
10551 lstrcpyA(targetprod, "banana");
10552 context = 0xdeadbeef;
10553 lstrcpyA(targetsid, "kiwi");
10554 size = MAX_PATH;
10555 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10556 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10557 &context, targetsid, &size);
10558 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10559 ok(!lstrcmpA(patchcode, "apple"),
10560 "Expected patchcode to be unchanged, got %s\n", patchcode);
10561 ok(!lstrcmpA(targetprod, "banana"),
10562 "Expected targetprod to be unchanged, got %s\n", targetprod);
10563 ok(context == 0xdeadbeef,
10564 "Expected context to be unchanged, got %d\n", context);
10565 ok(!lstrcmpA(targetsid, "kiwi"),
10566 "Expected targetsid to be unchanged, got %s\n", targetsid);
10567 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10568
10569 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10570 lstrcatA(keypath, expectedsid);
10571 lstrcatA(keypath, "\\Products\\");
10572 lstrcatA(keypath, prod_squashed);
10573
10574 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10575 if (res == ERROR_ACCESS_DENIED)
10576 {
10577 skip("Not enough rights to perform tests\n");
10578 goto error;
10579 }
10580 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10581
10582 /* UserData product key exists */
10583 lstrcpyA(patchcode, "apple");
10584 lstrcpyA(targetprod, "banana");
10585 context = 0xdeadbeef;
10586 lstrcpyA(targetsid, "kiwi");
10587 size = MAX_PATH;
10588 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10589 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10590 &context, targetsid, &size);
10591 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10592 ok(!lstrcmpA(patchcode, "apple"),
10593 "Expected patchcode to be unchanged, got %s\n", patchcode);
10594 ok(!lstrcmpA(targetprod, "banana"),
10595 "Expected targetprod to be unchanged, got %s\n", targetprod);
10596 ok(context == 0xdeadbeef,
10597 "Expected context to be unchanged, got %d\n", context);
10598 ok(!lstrcmpA(targetsid, "kiwi"),
10599 "Expected targetsid to be unchanged, got %s\n", targetsid);
10600 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10601
10602 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10603 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10604
10605 /* UserData patches key exists */
10606 lstrcpyA(patchcode, "apple");
10607 lstrcpyA(targetprod, "banana");
10608 context = 0xdeadbeef;
10609 lstrcpyA(targetsid, "kiwi");
10610 size = MAX_PATH;
10611 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10612 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10613 &context, targetsid, &size);
10614 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10615 ok(!lstrcmpA(patchcode, "apple"),
10616 "Expected patchcode to be unchanged, got %s\n", patchcode);
10617 ok(!lstrcmpA(targetprod, "banana"),
10618 "Expected targetprod to be unchanged, got %s\n", targetprod);
10619 ok(context == 0xdeadbeef,
10620 "Expected context to be unchanged, got %d\n", context);
10621 ok(!lstrcmpA(targetsid, "kiwi"),
10622 "Expected targetsid to be unchanged, got %s\n", targetsid);
10623 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10624
10625 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10626 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10627
10628 /* specific UserData patch key exists */
10629 lstrcpyA(patchcode, "apple");
10630 lstrcpyA(targetprod, "banana");
10631 context = 0xdeadbeef;
10632 lstrcpyA(targetsid, "kiwi");
10633 size = MAX_PATH;
10634 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10635 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10636 &context, targetsid, &size);
10637 ok(r == ERROR_BAD_CONFIGURATION,
10638 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10639 ok(!lstrcmpA(patchcode, "apple"),
10640 "Expected patchcode to be unchanged, got %s\n", patchcode);
10641 ok(!lstrcmpA(targetprod, "banana"),
10642 "Expected targetprod to be unchanged, got %s\n", targetprod);
10643 ok(context == 0xdeadbeef,
10644 "Expected context to be unchanged, got %d\n", context);
10645 ok(!lstrcmpA(targetsid, "kiwi"),
10646 "Expected targetsid to be unchanged, got %s\n", targetsid);
10647 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10648
10649 data = MSIPATCHSTATE_SUPERSEDED;
10650 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10651 (const BYTE *)&data, sizeof(DWORD));
10652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10653
10654 /* State value exists */
10655 lstrcpyA(patchcode, "apple");
10656 lstrcpyA(targetprod, "banana");
10657 context = 0xdeadbeef;
10658 lstrcpyA(targetsid, "kiwi");
10659 size = MAX_PATH;
10660 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10661 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10662 &context, targetsid, &size);
10663 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10664 ok(!lstrcmpA(patchcode, patch),
10665 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10666 ok(!lstrcmpA(targetprod, prodcode),
10667 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10668 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10669 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10670 ok(!lstrcmpA(targetsid, expectedsid),
10671 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10672 ok(size == lstrlenA(expectedsid),
10673 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10674
10675 /* MSIPATCHSTATE_OBSOLETED */
10676
10677 lstrcpyA(patchcode, "apple");
10678 lstrcpyA(targetprod, "banana");
10679 context = 0xdeadbeef;
10680 lstrcpyA(targetsid, "kiwi");
10681 size = MAX_PATH;
10682 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10683 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10684 &context, targetsid, &size);
10685 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10686 ok(!lstrcmpA(patchcode, "apple"),
10687 "Expected patchcode to be unchanged, got %s\n", patchcode);
10688 ok(!lstrcmpA(targetprod, "banana"),
10689 "Expected targetprod to be unchanged, got %s\n", targetprod);
10690 ok(context == 0xdeadbeef,
10691 "Expected context to be unchanged, got %d\n", context);
10692 ok(!lstrcmpA(targetsid, "kiwi"),
10693 "Expected targetsid to be unchanged, got %s\n", targetsid);
10694 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10695
10696 data = MSIPATCHSTATE_OBSOLETED;
10697 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10698 (const BYTE *)&data, sizeof(DWORD));
10699 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10700
10701 /* State value is obsoleted */
10702 lstrcpyA(patchcode, "apple");
10703 lstrcpyA(targetprod, "banana");
10704 context = 0xdeadbeef;
10705 lstrcpyA(targetsid, "kiwi");
10706 size = MAX_PATH;
10707 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10708 MSIPATCHSTATE_OBSOLETED, 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_USERUNMANAGED,
10716 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10717 ok(!lstrcmpA(targetsid, expectedsid),
10718 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10719 ok(size == lstrlenA(expectedsid),
10720 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10721
10722 /* MSIPATCHSTATE_REGISTERED */
10723 /* FIXME */
10724
10725 /* MSIPATCHSTATE_ALL */
10726
10727 /* 1st */
10728 lstrcpyA(patchcode, "apple");
10729 lstrcpyA(targetprod, "banana");
10730 context = 0xdeadbeef;
10731 lstrcpyA(targetsid, "kiwi");
10732 size = MAX_PATH;
10733 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10734 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10735 &context, targetsid, &size);
10736 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10737 ok(!lstrcmpA(patchcode, patch),
10738 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10739 ok(!lstrcmpA(targetprod, prodcode),
10740 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10741 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10742 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10743 ok(!lstrcmpA(targetsid, expectedsid),
10744 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10745 ok(size == lstrlenA(expectedsid),
10746 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10747
10748 /* same patch in multiple places, only one is enumerated */
10749 lstrcpyA(patchcode, "apple");
10750 lstrcpyA(targetprod, "banana");
10751 context = 0xdeadbeef;
10752 lstrcpyA(targetsid, "kiwi");
10753 size = MAX_PATH;
10754 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10755 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10756 &context, targetsid, &size);
10757 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10758 ok(!lstrcmpA(patchcode, "apple"),
10759 "Expected patchcode to be unchanged, got %s\n", patchcode);
10760 ok(!lstrcmpA(targetprod, "banana"),
10761 "Expected targetprod to be unchanged, got %s\n", targetprod);
10762 ok(context == 0xdeadbeef,
10763 "Expected context to be unchanged, got %d\n", context);
10764 ok(!lstrcmpA(targetsid, "kiwi"),
10765 "Expected targetsid to be unchanged, got %s\n", targetsid);
10766 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10767
10768 RegDeleteValueA(hpatch, "State");
10769 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10770 RegCloseKey(hpatch);
10771 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10772 RegCloseKey(udpatch);
10773 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10774 RegCloseKey(udprod);
10775 delete_key(userkey, "", access & KEY_WOW64_64KEY);
10776 RegCloseKey(userkey);
10777 RegDeleteValueA(patches, patch_squashed);
10778 RegDeleteValueA(patches, "Patches");
10779
10780 error:
10781 RegDeleteKeyA(patches, "");
10782 RegCloseKey(patches);
10783 RegDeleteKeyA(prodkey, "");
10784 RegCloseKey(prodkey);
10785 }
10786
10787 static void test_MsiEnumPatchesEx_machine(void)
10788 {
10789 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10790 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
10791 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10792 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10793 HKEY prodkey, patches, udprod, udpatch;
10794 HKEY hpatch;
10795 MSIINSTALLCONTEXT context;
10796 DWORD size, data;
10797 LONG res;
10798 UINT r;
10799 REGSAM access = KEY_ALL_ACCESS;
10800
10801 create_test_guid(prodcode, prod_squashed);
10802 create_test_guid(patch, patch_squashed);
10803
10804 if (is_wow64)
10805 access |= KEY_WOW64_64KEY;
10806
10807 /* MSIPATCHSTATE_APPLIED */
10808
10809 lstrcpyA(patchcode, "apple");
10810 lstrcpyA(targetprod, "banana");
10811 context = 0xdeadbeef;
10812 lstrcpyA(targetsid, "kiwi");
10813 size = MAX_PATH;
10814 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10815 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10816 &context, targetsid, &size);
10817 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10818 ok(!lstrcmpA(patchcode, "apple"),
10819 "Expected patchcode to be unchanged, got %s\n", patchcode);
10820 ok(!lstrcmpA(targetprod, "banana"),
10821 "Expected targetprod to be unchanged, got %s\n", targetprod);
10822 ok(context == 0xdeadbeef,
10823 "Expected context to be unchanged, got %d\n", context);
10824 ok(!lstrcmpA(targetsid, "kiwi"),
10825 "Expected targetsid to be unchanged, got %s\n", targetsid);
10826 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10827
10828 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10829 lstrcatA(keypath, prod_squashed);
10830
10831 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10832 if (res == ERROR_ACCESS_DENIED)
10833 {
10834 skip("Not enough rights to perform tests\n");
10835 return;
10836 }
10837 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10838
10839 /* local product key exists */
10840 lstrcpyA(patchcode, "apple");
10841 lstrcpyA(targetprod, "banana");
10842 context = 0xdeadbeef;
10843 lstrcpyA(targetsid, "kiwi");
10844 size = MAX_PATH;
10845 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10846 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10847 &context, targetsid, &size);
10848 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10849 ok(!lstrcmpA(patchcode, "apple"),
10850 "Expected patchcode to be unchanged, got %s\n", patchcode);
10851 ok(!lstrcmpA(targetprod, "banana"),
10852 "Expected targetprod to be unchanged, got %s\n", targetprod);
10853 ok(context == 0xdeadbeef,
10854 "Expected context to be unchanged, got %d\n", context);
10855 ok(!lstrcmpA(targetsid, "kiwi"),
10856 "Expected targetsid to be unchanged, got %s\n", targetsid);
10857 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10858
10859 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10860 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10861
10862 /* Patches key exists */
10863 lstrcpyA(patchcode, "apple");
10864 lstrcpyA(targetprod, "banana");
10865 context = 0xdeadbeef;
10866 lstrcpyA(targetsid, "kiwi");
10867 size = MAX_PATH;
10868 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10869 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10870 &context, targetsid, &size);
10871 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10872 ok(!lstrcmpA(patchcode, "apple"),
10873 "Expected patchcode to be unchanged, got %s\n", patchcode);
10874 ok(!lstrcmpA(targetprod, "banana"),
10875 "Expected targetprod to be unchanged, got %s\n", targetprod);
10876 ok(context == 0xdeadbeef,
10877 "Expected context to be unchanged, got %d\n", context);
10878 ok(!lstrcmpA(targetsid, "kiwi"),
10879 "Expected targetsid to be unchanged, got %s\n", targetsid);
10880 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10881
10882 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10883 (const BYTE *)patch_squashed,
10884 lstrlenA(patch_squashed) + 1);
10885 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10886
10887 /* Patches value exists, is not REG_MULTI_SZ */
10888 lstrcpyA(patchcode, "apple");
10889 lstrcpyA(targetprod, "banana");
10890 context = 0xdeadbeef;
10891 lstrcpyA(targetsid, "kiwi");
10892 size = MAX_PATH;
10893 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10894 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10895 &context, targetsid, &size);
10896 ok(r == ERROR_BAD_CONFIGURATION,
10897 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10898 ok(!lstrcmpA(patchcode, "apple"),
10899 "Expected patchcode to be unchanged, got %s\n", patchcode);
10900 ok(!lstrcmpA(targetprod, "banana"),
10901 "Expected targetprod to be unchanged, got %s\n", targetprod);
10902 ok(context == 0xdeadbeef,
10903 "Expected context to be unchanged, got %d\n", context);
10904 ok(!lstrcmpA(targetsid, "kiwi"),
10905 "Expected targetsid to be unchanged, got %s\n", targetsid);
10906 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10907
10908 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10909 (const BYTE *)"a\0b\0c\0\0", 7);
10910 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10911
10912 /* Patches value exists, is not a squashed guid */
10913 lstrcpyA(patchcode, "apple");
10914 lstrcpyA(targetprod, "banana");
10915 context = 0xdeadbeef;
10916 lstrcpyA(targetsid, "kiwi");
10917 size = MAX_PATH;
10918 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10919 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10920 &context, targetsid, &size);
10921 ok(r == ERROR_BAD_CONFIGURATION,
10922 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10923 ok(!lstrcmpA(patchcode, "apple"),
10924 "Expected patchcode to be unchanged, got %s\n", patchcode);
10925 ok(!lstrcmpA(targetprod, "banana"),
10926 "Expected targetprod to be unchanged, got %s\n", targetprod);
10927 ok(context == 0xdeadbeef,
10928 "Expected context to be unchanged, got %d\n", context);
10929 ok(!lstrcmpA(targetsid, "kiwi"),
10930 "Expected targetsid to be unchanged, got %s\n", targetsid);
10931 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10932
10933 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10934 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10935 (const BYTE *)patch_squashed,
10936 lstrlenA(patch_squashed) + 2);
10937 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10938
10939 /* Patches value exists */
10940 lstrcpyA(patchcode, "apple");
10941 lstrcpyA(targetprod, "banana");
10942 context = 0xdeadbeef;
10943 lstrcpyA(targetsid, "kiwi");
10944 size = MAX_PATH;
10945 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10946 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10947 &context, targetsid, &size);
10948 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10949 ok(!lstrcmpA(patchcode, "apple"),
10950 "Expected patchcode to be unchanged, got %s\n", patchcode);
10951 ok(!lstrcmpA(targetprod, "banana"),
10952 "Expected targetprod to be unchanged, got %s\n", targetprod);
10953 ok(context == 0xdeadbeef,
10954 "Expected context to be unchanged, got %d\n", context);
10955 ok(!lstrcmpA(targetsid, "kiwi"),
10956 "Expected targetsid to be unchanged, got %s\n", targetsid);
10957 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10958
10959 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10960 (const BYTE *)"whatever", 9);
10961 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10962
10963 /* patch code value exists */
10964 lstrcpyA(patchcode, "apple");
10965 lstrcpyA(targetprod, "banana");
10966 context = 0xdeadbeef;
10967 lstrcpyA(targetsid, "kiwi");
10968 size = MAX_PATH;
10969 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10970 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10971 &context, targetsid, &size);
10972 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10973 ok(!lstrcmpA(patchcode, patch),
10974 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10975 ok(!lstrcmpA(targetprod, prodcode),
10976 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10977 ok(context == MSIINSTALLCONTEXT_MACHINE,
10978 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10979 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10980 ok(size == 0, "Expected 0, got %d\n", size);
10981
10982 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10983 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10984 lstrcatA(keypath, prod_squashed);
10985
10986 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10987 if (res == ERROR_ACCESS_DENIED)
10988 {
10989 skip("Not enough rights to perform tests\n");
10990 goto done;
10991 }
10992 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10993
10994 /* local UserData product key exists */
10995 lstrcpyA(patchcode, "apple");
10996 lstrcpyA(targetprod, "banana");
10997 context = 0xdeadbeef;
10998 lstrcpyA(targetsid, "kiwi");
10999 size = MAX_PATH;
11000 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11001 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
11002 &context, targetsid, &size);
11003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11004 ok(!lstrcmpA(patchcode, patch),
11005 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
11006 ok(!lstrcmpA(targetprod, prodcode),
11007 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
11008 ok(context == MSIINSTALLCONTEXT_MACHINE,
11009 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
11010 ok(!lstrcmpA(targetsid, ""),
11011 "Expected \"\", got \"%s\"\n", targetsid);
11012 ok(size == 0, "Expected 0, got %d\n", size);
11013
11014 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
11015 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11016
11017 /* local UserData Patches key exists */
11018 lstrcpyA(patchcode, "apple");
11019 lstrcpyA(targetprod, "banana");
11020 context = 0xdeadbeef;
11021 lstrcpyA(targetsid, "kiwi");
11022 size = MAX_PATH;
11023 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11024 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
11025 &context, targetsid, &size);
11026 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11027 ok(!lstrcmpA(patchcode, patch),
11028 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
11029 ok(!lstrcmpA(targetprod, prodcode),
11030 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
11031 ok(context == MSIINSTALLCONTEXT_MACHINE,
11032 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
11033 ok(!lstrcmpA(targetsid, ""),
11034 "Expected \"\", got \"%s\"\n", targetsid);
11035 ok(size == 0, "Expected 0, got %d\n", size);
11036
11037 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11038 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11039
11040 /* local UserData Product patch key exists */
11041 lstrcpyA(patchcode, "apple");
11042 lstrcpyA(targetprod, "banana");
11043 context = 0xdeadbeef;
11044 lstrcpyA(targetsid, "kiwi");
11045 size = MAX_PATH;
11046 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11047 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
11048 &context, targetsid, &size);
11049 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11050 ok(!lstrcmpA(patchcode, "apple"),
11051 "Expected patchcode to be unchanged, got %s\n", patchcode);
11052 ok(!lstrcmpA(targetprod, "banana"),
11053 "Expected targetprod to be unchanged, got %s\n", targetprod);
11054 ok(context == 0xdeadbeef,
11055 "Expected context to be unchanged, got %d\n", context);
11056 ok(!lstrcmpA(targetsid, "kiwi"),
11057 "Expected targetsid to be unchanged, got %s\n", targetsid);
11058 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11059
11060 data = MSIPATCHSTATE_APPLIED;
11061 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11062 (const BYTE *)&data, sizeof(DWORD));
11063 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11064
11065 /* State value exists */
11066 lstrcpyA(patchcode, "apple");
11067 lstrcpyA(targetprod, "banana");
11068 context = 0xdeadbeef;
11069 lstrcpyA(targetsid, "kiwi");
11070 size = MAX_PATH;
11071 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11072 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
11073 &context, targetsid, &size);
11074 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11075 ok(!lstrcmpA(patchcode, patch),
11076 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
11077 ok(!lstrcmpA(targetprod, prodcode),
11078 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
11079 ok(context == MSIINSTALLCONTEXT_MACHINE,
11080 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
11081 ok(!lstrcmpA(targetsid, ""),
11082 "Expected \"\", got \"%s\"\n", targetsid);
11083 ok(size == 0, "Expected 0, got %d\n", size);
11084
11085 /* MSIPATCHSTATE_SUPERSEDED */
11086
11087 lstrcpyA(patchcode, "apple");
11088 lstrcpyA(targetprod, "banana");
11089 context = 0xdeadbeef;
11090 lstrcpyA(targetsid, "kiwi");
11091 size = MAX_PATH;
11092 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11093 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
11094 &context, targetsid, &size);
11095 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11096 ok(!lstrcmpA(patchcode, "apple"),
11097 "Expected patchcode to be unchanged, got %s\n", patchcode);
11098 ok(!lstrcmpA(targetprod, "banana"),
11099 "Expected targetprod to be unchanged, got %s\n", targetprod);
11100 ok(context == 0xdeadbeef,
11101 "Expected context to be unchanged, got %d\n", context);
11102 ok(!lstrcmpA(targetsid, "kiwi"),
11103 "Expected targetsid to be unchanged, got %s\n", targetsid);
11104 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11105
11106 data = MSIPATCHSTATE_SUPERSEDED;
11107 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11108 (const BYTE *)&data, sizeof(DWORD));
11109 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11110
11111 /* State value is MSIPATCHSTATE_SUPERSEDED */
11112 lstrcpyA(patchcode, "apple");
11113 lstrcpyA(targetprod, "banana");
11114 context = 0xdeadbeef;
11115 lstrcpyA(targetsid, "kiwi");
11116 size = MAX_PATH;
11117 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11118 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
11119 &context, targetsid, &size);
11120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11121 ok(!lstrcmpA(patchcode, patch),
11122 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
11123 ok(!lstrcmpA(targetprod, prodcode),
11124 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
11125 ok(context == MSIINSTALLCONTEXT_MACHINE,
11126 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
11127 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
11128 ok(size == 0, "Expected 0, got %d\n", size);
11129
11130 /* MSIPATCHSTATE_OBSOLETED */
11131
11132 lstrcpyA(patchcode, "apple");
11133 lstrcpyA(targetprod, "banana");
11134 context = 0xdeadbeef;
11135 lstrcpyA(targetsid, "kiwi");
11136 size = MAX_PATH;
11137 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11138 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
11139 &context, targetsid, &size);
11140 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11141 ok(!lstrcmpA(patchcode, "apple"),
11142 "Expected patchcode to be unchanged, got %s\n", patchcode);
11143 ok(!lstrcmpA(targetprod, "banana"),
11144 "Expected targetprod to be unchanged, got %s\n", targetprod);
11145 ok(context == 0xdeadbeef,
11146 "Expected context to be unchanged, got %d\n", context);
11147 ok(!lstrcmpA(targetsid, "kiwi"),
11148 "Expected targetsid to be unchanged, got %s\n", targetsid);
11149 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11150
11151 data = MSIPATCHSTATE_OBSOLETED;
11152 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11153 (const BYTE *)&data, sizeof(DWORD));
11154 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11155
11156 /* State value is obsoleted */
11157 lstrcpyA(patchcode, "apple");
11158 lstrcpyA(targetprod, "banana");
11159 context = 0xdeadbeef;
11160 lstrcpyA(targetsid, "kiwi");
11161 size = MAX_PATH;
11162 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11163 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
11164 &context, targetsid, &size);
11165 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11166 ok(!lstrcmpA(patchcode, patch),
11167 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
11168 ok(!lstrcmpA(targetprod, prodcode),
11169 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
11170 ok(context == MSIINSTALLCONTEXT_MACHINE,
11171 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
11172 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
11173 ok(size == 0, "Expected 0, got %d\n", size);
11174
11175 /* MSIPATCHSTATE_REGISTERED */
11176 /* FIXME */
11177
11178 /* MSIPATCHSTATE_ALL */
11179
11180 /* 1st */
11181 lstrcpyA(patchcode, "apple");
11182 lstrcpyA(targetprod, "banana");
11183 context = 0xdeadbeef;
11184 lstrcpyA(targetsid, "kiwi");
11185 size = MAX_PATH;
11186 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11187 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11188 &context, targetsid, &size);
11189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11190 ok(!lstrcmpA(patchcode, patch),
11191 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
11192 ok(!lstrcmpA(targetprod, prodcode),
11193 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
11194 ok(context == MSIINSTALLCONTEXT_MACHINE,
11195 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
11196 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
11197 ok(size == 0, "Expected 0, got %d\n", size);
11198
11199 /* same patch in multiple places, only one is enumerated */
11200 lstrcpyA(patchcode, "apple");
11201 lstrcpyA(targetprod, "banana");
11202 context = 0xdeadbeef;
11203 lstrcpyA(targetsid, "kiwi");
11204 size = MAX_PATH;
11205 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
11206 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
11207 &context, targetsid, &size);
11208 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11209 ok(!lstrcmpA(patchcode, "apple"),
11210 "Expected patchcode to be unchanged, got %s\n", patchcode);
11211 ok(!lstrcmpA(targetprod, "banana"),
11212 "Expected targetprod to be unchanged, got %s\n", targetprod);
11213 ok(context == 0xdeadbeef,
11214 "Expected context to be unchanged, got %d\n", context);
11215 ok(!lstrcmpA(targetsid, "kiwi"),
11216 "Expected targetsid to be unchanged, got %s\n", targetsid);
11217 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11218
11219 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11220 RegDeleteValueA(hpatch, "State");
11221 RegCloseKey(hpatch);
11222 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11223 RegCloseKey(udpatch);
11224 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11225 RegCloseKey(udprod);
11226
11227 done:
11228 RegDeleteValueA(patches, patch_squashed);
11229 RegDeleteValueA(patches, "Patches");
11230 delete_key(patches, "", access & KEY_WOW64_64KEY);
11231 RegCloseKey(patches);
11232 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11233 RegCloseKey(prodkey);
11234 }
11235
11236 static void test_MsiEnumPatchesEx(void)
11237 {
11238 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
11239 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11240 CHAR patchcode[MAX_PATH];
11241 MSIINSTALLCONTEXT context;
11242 LPSTR usersid;
11243 DWORD size;
11244 UINT r;
11245
11246 if (!pMsiEnumPatchesExA)
11247 {
11248 win_skip("MsiEnumPatchesExA not implemented\n");
11249 return;
11250 }
11251
11252 create_test_guid(prodcode, prod_squashed);
11253 usersid = get_user_sid();
11254
11255 /* empty szProductCode */
11256 lstrcpyA(patchcode, "apple");
11257 lstrcpyA(targetprod, "banana");
11258 context = 0xdeadbeef;
11259 lstrcpyA(targetsid, "kiwi");
11260 size = MAX_PATH;
11261 r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11262 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
11263 targetsid, &size);
11264 ok(r == ERROR_INVALID_PARAMETER,
11265 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11266 ok(!lstrcmpA(patchcode, "apple"),
11267 "Expected patchcode to be unchanged, got %s\n", patchcode);
11268 ok(!lstrcmpA(targetprod, "banana"),
11269 "Expected targetprod to be unchanged, got %s\n", targetprod);
11270 ok(context == 0xdeadbeef,
11271 "Expected context to be unchanged, got %d\n", context);
11272 ok(!lstrcmpA(targetsid, "kiwi"),
11273 "Expected targetsid to be unchanged, got %s\n", targetsid);
11274 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11275
11276 /* garbage szProductCode */
11277 lstrcpyA(patchcode, "apple");
11278 lstrcpyA(targetprod, "banana");
11279 context = 0xdeadbeef;
11280 lstrcpyA(targetsid, "kiwi");
11281 size = MAX_PATH;
11282 r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11283 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
11284 targetsid, &size);
11285 ok(r == ERROR_INVALID_PARAMETER,
11286 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11287 ok(!lstrcmpA(patchcode, "apple"),
11288 "Expected patchcode to be unchanged, got %s\n", patchcode);
11289 ok(!lstrcmpA(targetprod, "banana"),
11290 "Expected targetprod to be unchanged, got %s\n", targetprod);
11291 ok(context == 0xdeadbeef,
11292 "Expected context to be unchanged, got %d\n", context);
11293 ok(!lstrcmpA(targetsid, "kiwi"),
11294 "Expected targetsid to be unchanged, got %s\n", targetsid);
11295 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11296
11297 /* guid without brackets */
11298 lstrcpyA(patchcode, "apple");
11299 lstrcpyA(targetprod, "banana");
11300 context = 0xdeadbeef;
11301 lstrcpyA(targetsid, "kiwi");
11302 size = MAX_PATH;
11303 r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
11304 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
11305 0, patchcode, targetprod, &context,
11306 targetsid, &size);
11307 ok(r == ERROR_INVALID_PARAMETER,
11308 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11309 ok(!lstrcmpA(patchcode, "apple"),
11310 "Expected patchcode to be unchanged, got %s\n", patchcode);
11311 ok(!lstrcmpA(targetprod, "banana"),
11312 "Expected targetprod to be unchanged, got %s\n", targetprod);
11313 ok(context == 0xdeadbeef,
11314 "Expected context to be unchanged, got %d\n", context);
11315 ok(!lstrcmpA(targetsid, "kiwi"),
11316 "Expected targetsid to be unchanged, got %s\n", targetsid);
11317 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11318
11319 /* guid with brackets */
11320 lstrcpyA(patchcode, "apple");
11321 lstrcpyA(targetprod, "banana");
11322 context = 0xdeadbeef;
11323 lstrcpyA(targetsid, "kiwi");
11324 size = MAX_PATH;
11325 r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
11326 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
11327 0, patchcode, targetprod, &context,
11328 targetsid, &size);
11329 ok(r == ERROR_NO_MORE_ITEMS,
11330 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11331 ok(!lstrcmpA(patchcode, "apple"),
11332 "Expected patchcode to be unchanged, got %s\n", patchcode);
11333 ok(!lstrcmpA(targetprod, "banana"),
11334 "Expected targetprod to be unchanged, got %s\n", targetprod);
11335 ok(context == 0xdeadbeef,
11336 "Expected context to be unchanged, got %d\n", context);
11337 ok(!lstrcmpA(targetsid, "kiwi"),
11338 "Expected targetsid to be unchanged, got %s\n", targetsid);
11339 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11340
11341 /* szUserSid is S-1-5-18 */
11342 lstrcpyA(patchcode, "apple");
11343 lstrcpyA(targetprod, "banana");
11344 context = 0xdeadbeef;
11345 lstrcpyA(targetsid, "kiwi");
11346 size = MAX_PATH;
11347 r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
11348 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
11349 0, patchcode, targetprod, &context,
11350 targetsid, &size);
11351 ok(r == ERROR_INVALID_PARAMETER,
11352 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11353 ok(!lstrcmpA(patchcode, "apple"),
11354 "Expected patchcode to be unchanged, got %s\n", patchcode);
11355 ok(!lstrcmpA(targetprod, "banana"),
11356 "Expected targetprod to be unchanged, got %s\n", targetprod);
11357 ok(context == 0xdeadbeef,
11358 "Expected context to be unchanged, got %d\n", context);
11359 ok(!lstrcmpA(targetsid, "kiwi"),
11360 "Expected targetsid to be unchanged, got %s\n", targetsid);
11361 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11362
11363 /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
11364 lstrcpyA(patchcode, "apple");
11365 lstrcpyA(targetprod, "banana");
11366 context = 0xdeadbeef;
11367 lstrcpyA(targetsid, "kiwi");
11368 size = MAX_PATH;
11369 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
11370 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11371 &context, targetsid, &size);
11372 ok(r == ERROR_INVALID_PARAMETER,
11373 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11374 ok(!lstrcmpA(patchcode, "apple"),
11375 "Expected patchcode to be unchanged, got %s\n", patchcode);
11376 ok(!lstrcmpA(targetprod, "banana"),
11377 "Expected targetprod to be unchanged, got %s\n", targetprod);
11378 ok(context == 0xdeadbeef,
11379 "Expected context to be unchanged, got %d\n", context);
11380 ok(!lstrcmpA(targetsid, "kiwi"),
11381 "Expected targetsid to be unchanged, got %s\n", targetsid);
11382 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11383
11384 /* dwContext is out of bounds */
11385 lstrcpyA(patchcode, "apple");
11386 lstrcpyA(targetprod, "banana");
11387 context = 0xdeadbeef;
11388 lstrcpyA(targetsid, "kiwi");
11389 size = MAX_PATH;
11390 r = pMsiEnumPatchesExA(prodcode, usersid, 0,
11391 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11392 &context, targetsid, &size);
11393 ok(r == ERROR_INVALID_PARAMETER,
11394 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11395 ok(!lstrcmpA(patchcode, "apple"),
11396 "Expected patchcode to be unchanged, got %s\n", patchcode);
11397 ok(!lstrcmpA(targetprod, "banana"),
11398 "Expected targetprod to be unchanged, got %s\n", targetprod);
11399 ok(context == 0xdeadbeef,
11400 "Expected context to be unchanged, got %d\n", context);
11401 ok(!lstrcmpA(targetsid, "kiwi"),
11402 "Expected targetsid to be unchanged, got %s\n", targetsid);
11403 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11404
11405 /* dwContext is out of bounds */
11406 lstrcpyA(patchcode, "apple");
11407 lstrcpyA(targetprod, "banana");
11408 context = 0xdeadbeef;
11409 lstrcpyA(targetsid, "kiwi");
11410 size = MAX_PATH;
11411 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
11412 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11413 &context, targetsid, &size);
11414 ok(r == ERROR_INVALID_PARAMETER,
11415 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11416 ok(!lstrcmpA(patchcode, "apple"),
11417 "Expected patchcode to be unchanged, got %s\n", patchcode);
11418 ok(!lstrcmpA(targetprod, "banana"),
11419 "Expected targetprod to be unchanged, got %s\n", targetprod);
11420 ok(context == 0xdeadbeef,
11421 "Expected context to be unchanged, got %d\n", context);
11422 ok(!lstrcmpA(targetsid, "kiwi"),
11423 "Expected targetsid to be unchanged, got %s\n", targetsid);
11424 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11425
11426 /* dwFilter is out of bounds */
11427 lstrcpyA(patchcode, "apple");
11428 lstrcpyA(targetprod, "banana");
11429 context = 0xdeadbeef;
11430 lstrcpyA(targetsid, "kiwi");
11431 size = MAX_PATH;
11432 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11433 MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
11434 &context, targetsid, &size);
11435 ok(r == ERROR_INVALID_PARAMETER,
11436 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11437 ok(!lstrcmpA(patchcode, "apple"),
11438 "Expected patchcode to be unchanged, got %s\n", patchcode);
11439 ok(!lstrcmpA(targetprod, "banana"),
11440 "Expected targetprod to be unchanged, got %s\n", targetprod);
11441 ok(context == 0xdeadbeef,
11442 "Expected context to be unchanged, got %d\n", context);
11443 ok(!lstrcmpA(targetsid, "kiwi"),
11444 "Expected targetsid to be unchanged, got %s\n", targetsid);
11445 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11446
11447 /* dwFilter is out of bounds */
11448 lstrcpyA(patchcode, "apple");
11449 lstrcpyA(targetprod, "banana");
11450 context = 0xdeadbeef;
11451 lstrcpyA(targetsid, "kiwi");
11452 size = MAX_PATH;
11453 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11454 MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
11455 &context, targetsid, &size);
11456 ok(r == ERROR_INVALID_PARAMETER,
11457 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11458 ok(!lstrcmpA(patchcode, "apple"),
11459 "Expected patchcode to be unchanged, got %s\n", patchcode);
11460 ok(!lstrcmpA(targetprod, "banana"),
11461 "Expected targetprod to be unchanged, got %s\n", targetprod);
11462 ok(context == 0xdeadbeef,
11463 "Expected context to be unchanged, got %d\n", context);
11464 ok(!lstrcmpA(targetsid, "kiwi"),
11465 "Expected targetsid to be unchanged, got %s\n", targetsid);
11466 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11467
11468 /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
11469 lstrcpyA(patchcode, "apple");
11470 lstrcpyA(targetprod, "banana");
11471 context = 0xdeadbeef;
11472 lstrcpyA(targetsid, "kiwi");
11473 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11474 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11475 &context, targetsid, NULL);
11476 ok(r == ERROR_INVALID_PARAMETER,
11477 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11478 ok(!lstrcmpA(patchcode, "apple"),
11479 "Expected patchcode to be unchanged, got %s\n", patchcode);
11480 ok(!lstrcmpA(targetprod, "banana"),
11481 "Expected targetprod to be unchanged, got %s\n", targetprod);
11482 ok(context == 0xdeadbeef,
11483 "Expected context to be unchanged, got %d\n", context);
11484 ok(!lstrcmpA(targetsid, "kiwi"),
11485 "Expected targetsid to be unchanged, got %s\n", targetsid);
11486
11487 test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
11488 test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
11489 test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
11490 test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
11491 test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
11492 /* FIXME: Successfully test userunmanaged with a different user */
11493 test_MsiEnumPatchesEx_machine();
11494 LocalFree(usersid);
11495 }
11496
11497 static void test_MsiEnumPatches(void)
11498 {
11499 CHAR keypath[MAX_PATH], patch[MAX_PATH];
11500 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
11501 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11502 CHAR transforms[MAX_PATH];
11503 WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
11504 HKEY prodkey, patches, udprod;
11505 HKEY userkey, hpatch, udpatch;
11506 DWORD size, data;
11507 LPSTR usersid;
11508 LONG res;
11509 UINT r;
11510 REGSAM access = KEY_ALL_ACCESS;
11511
11512 create_test_guid(prodcode, prod_squashed);
11513 create_test_guid(patchcode, patch_squashed);
11514 usersid = get_user_sid();
11515
11516 if (is_wow64)
11517 access |= KEY_WOW64_64KEY;
11518
11519 /* NULL szProduct */
11520 size = MAX_PATH;
11521 lstrcpyA(patch, "apple");
11522 lstrcpyA(transforms, "banana");
11523 r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
11524 ok(r == ERROR_INVALID_PARAMETER,
11525 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11526 ok(!lstrcmpA(patch, "apple"),
11527 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11528 ok(!lstrcmpA(transforms, "banana"),
11529 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11530 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11531
11532 /* empty szProduct */
11533 size = MAX_PATH;
11534 lstrcpyA(patch, "apple");
11535 lstrcpyA(transforms, "banana");
11536 r = MsiEnumPatchesA("", 0, patch, transforms, &size);
11537 ok(r == ERROR_INVALID_PARAMETER,
11538 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11539 ok(!lstrcmpA(patch, "apple"),
11540 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11541 ok(!lstrcmpA(transforms, "banana"),
11542 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11543 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11544
11545 /* garbage szProduct */
11546 size = MAX_PATH;
11547 lstrcpyA(patch, "apple");
11548 lstrcpyA(transforms, "banana");
11549 r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
11550 ok(r == ERROR_INVALID_PARAMETER,
11551 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11552 ok(!lstrcmpA(patch, "apple"),
11553 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11554 ok(!lstrcmpA(transforms, "banana"),
11555 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11556 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11557
11558 /* guid without brackets */
11559 size = MAX_PATH;
11560 lstrcpyA(patch, "apple");
11561 lstrcpyA(transforms, "banana");
11562 r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
11563 transforms, &size);
11564 ok(r == ERROR_INVALID_PARAMETER,
11565 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11566 ok(!lstrcmpA(patch, "apple"),
11567 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11568 ok(!lstrcmpA(transforms, "banana"),
11569 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11570 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11571
11572 /* guid with brackets */
11573 size = MAX_PATH;
11574 lstrcpyA(patch, "apple");
11575 lstrcpyA(transforms, "banana");
11576 r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
11577 transforms, &size);
11578 ok(r == ERROR_UNKNOWN_PRODUCT,
11579 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11580 ok(!lstrcmpA(patch, "apple"),
11581 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11582 ok(!lstrcmpA(transforms, "banana"),
11583 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11584 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11585
11586 /* same length as guid, but random */
11587 size = MAX_PATH;
11588 lstrcpyA(patch, "apple");
11589 lstrcpyA(transforms, "banana");
11590 r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
11591 transforms, &size);
11592 ok(r == ERROR_INVALID_PARAMETER,
11593 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11594 ok(!lstrcmpA(patch, "apple"),
11595 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11596 ok(!lstrcmpA(transforms, "banana"),
11597 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11598 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11599
11600 /* MSIINSTALLCONTEXT_USERMANAGED */
11601
11602 size = MAX_PATH;
11603 lstrcpyA(patch, "apple");
11604 lstrcpyA(transforms, "banana");
11605 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11606 ok(r == ERROR_UNKNOWN_PRODUCT,
11607 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11608 ok(!lstrcmpA(patch, "apple"),
11609 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11610 ok(!lstrcmpA(transforms, "banana"),
11611 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11612 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11613
11614 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11615 lstrcatA(keypath, usersid);
11616 lstrcatA(keypath, "\\Installer\\Products\\");
11617 lstrcatA(keypath, prod_squashed);
11618
11619 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11620 if (res == ERROR_ACCESS_DENIED)
11621 {
11622 skip("Not enough rights to perform tests\n");
11623 LocalFree(usersid);
11624 return;
11625 }
11626 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11627
11628 /* managed product key exists */
11629 size = MAX_PATH;
11630 lstrcpyA(patch, "apple");
11631 lstrcpyA(transforms, "banana");
11632 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11633 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11634 ok(!lstrcmpA(patch, "apple"),
11635 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11636 ok(!lstrcmpA(transforms, "banana"),
11637 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11638 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11639
11640 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11641 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11642
11643 /* patches key exists */
11644 size = MAX_PATH;
11645 lstrcpyA(patch, "apple");
11646 lstrcpyA(transforms, "banana");
11647 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11648 ok(r == ERROR_NO_MORE_ITEMS ||
11649 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11650 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11651 ok(!lstrcmpA(patch, "apple"),
11652 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11653 ok(!lstrcmpA(transforms, "banana"),
11654 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11655 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11656
11657 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11658 (const BYTE *)patch_squashed,
11659 lstrlenA(patch_squashed) + 1);
11660 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11661
11662 /* Patches value exists, is not REG_MULTI_SZ */
11663 size = MAX_PATH;
11664 lstrcpyA(patch, "apple");
11665 lstrcpyA(transforms, "banana");
11666 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11667 ok(r == ERROR_BAD_CONFIGURATION ||
11668 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11669 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11670 ok(!lstrcmpA(patch, "apple"),
11671 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11672 ok(!lstrcmpA(transforms, "banana"),
11673 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11674 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11675
11676 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11677 (const BYTE *)"a\0b\0c\0\0", 7);
11678 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11679
11680 /* Patches value exists, is not a squashed guid */
11681 size = MAX_PATH;
11682 lstrcpyA(patch, "apple");
11683 lstrcpyA(transforms, "banana");
11684 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11685 ok(r == ERROR_BAD_CONFIGURATION,
11686 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11687 ok(!lstrcmpA(patch, "apple"),
11688 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11689 ok(!lstrcmpA(transforms, "banana"),
11690 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11691 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11692
11693 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11694 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11695 (const BYTE *)patch_squashed,
11696 lstrlenA(patch_squashed) + 2);
11697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11698
11699 /* Patches value exists */
11700 size = MAX_PATH;
11701 lstrcpyA(patch, "apple");
11702 lstrcpyA(transforms, "banana");
11703 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11704 ok(r == ERROR_NO_MORE_ITEMS ||
11705 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11706 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11707 ok(!lstrcmpA(patch, "apple") ||
11708 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11709 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11710 ok(!lstrcmpA(transforms, "banana"),
11711 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11712 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11713
11714 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11715 (const BYTE *)"whatever", 9);
11716 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11717
11718 /* patch squashed value exists */
11719 size = MAX_PATH;
11720 lstrcpyA(patch, "apple");
11721 lstrcpyA(transforms, "banana");
11722 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11723 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11724 ok(!lstrcmpA(patch, patchcode),
11725 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11726 ok(!lstrcmpA(transforms, "whatever"),
11727 "Expected \"whatever\", got \"%s\"\n", transforms);
11728 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11729
11730 /* lpPatchBuf is NULL */
11731 size = MAX_PATH;
11732 lstrcpyA(transforms, "banana");
11733 r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
11734 ok(r == ERROR_INVALID_PARAMETER,
11735 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11736 ok(!lstrcmpA(transforms, "banana"),
11737 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11738 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11739
11740 /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
11741 size = MAX_PATH;
11742 lstrcpyA(patch, "apple");
11743 r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
11744 ok(r == ERROR_INVALID_PARAMETER,
11745 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11746 ok(!lstrcmpA(patch, "apple"),
11747 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11748 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11749
11750 /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
11751 lstrcpyA(patch, "apple");
11752 lstrcpyA(transforms, "banana");
11753 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
11754 ok(r == ERROR_INVALID_PARAMETER,
11755 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11756 ok(!lstrcmpA(patch, "apple"),
11757 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11758 ok(!lstrcmpA(transforms, "banana"),
11759 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11760
11761 /* pcchTransformsBuf is too small */
11762 size = 6;
11763 lstrcpyA(patch, "apple");
11764 lstrcpyA(transforms, "banana");
11765 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11766 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11767 ok(!lstrcmpA(patch, patchcode),
11768 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11769 ok(!lstrcmpA(transforms, "whate") ||
11770 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11771 "Expected \"whate\", got \"%s\"\n", transforms);
11772 ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
11773
11774 /* increase the index */
11775 size = MAX_PATH;
11776 lstrcpyA(patch, "apple");
11777 lstrcpyA(transforms, "banana");
11778 r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
11779 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11780 ok(!lstrcmpA(patch, "apple"),
11781 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11782 ok(!lstrcmpA(transforms, "banana"),
11783 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11784 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11785
11786 /* increase again */
11787 size = MAX_PATH;
11788 lstrcpyA(patch, "apple");
11789 lstrcpyA(transforms, "banana");
11790 r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
11791 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11792 ok(!lstrcmpA(patch, "apple"),
11793 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11794 ok(!lstrcmpA(transforms, "banana"),
11795 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11796 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11797
11798 RegDeleteValueA(patches, "Patches");
11799 delete_key(patches, "", access & KEY_WOW64_64KEY);
11800 RegCloseKey(patches);
11801 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11802 RegCloseKey(prodkey);
11803
11804 /* MSIINSTALLCONTEXT_USERUNMANAGED */
11805
11806 size = MAX_PATH;
11807 lstrcpyA(patch, "apple");
11808 lstrcpyA(transforms, "banana");
11809 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11810 ok(r == ERROR_UNKNOWN_PRODUCT,
11811 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11812 ok(!lstrcmpA(patch, "apple"),
11813 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11814 ok(!lstrcmpA(transforms, "banana"),
11815 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11816 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11817
11818 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11819 lstrcatA(keypath, prod_squashed);
11820
11821 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11822 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11823
11824 /* current user product key exists */
11825 size = MAX_PATH;
11826 lstrcpyA(patch, "apple");
11827 lstrcpyA(transforms, "banana");
11828 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11829 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11830 ok(!lstrcmpA(patch, "apple"),
11831 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11832 ok(!lstrcmpA(transforms, "banana"),
11833 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11834 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11835
11836 res = RegCreateKeyA(prodkey, "Patches", &patches);
11837 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11838
11839 /* Patches key exists */
11840 size = MAX_PATH;
11841 lstrcpyA(patch, "apple");
11842 lstrcpyA(transforms, "banana");
11843 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11844 ok(r == ERROR_NO_MORE_ITEMS ||
11845 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11846 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11847 ok(!lstrcmpA(patch, "apple"),
11848 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11849 ok(!lstrcmpA(transforms, "banana"),
11850 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11851 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11852
11853 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11854 (const BYTE *)patch_squashed,
11855 lstrlenA(patch_squashed) + 1);
11856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11857
11858 /* Patches value exists, is not REG_MULTI_SZ */
11859 size = MAX_PATH;
11860 lstrcpyA(patch, "apple");
11861 lstrcpyA(transforms, "banana");
11862 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11863 ok(r == ERROR_BAD_CONFIGURATION ||
11864 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11865 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11866 ok(!lstrcmpA(patch, "apple"),
11867 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11868 ok(!lstrcmpA(transforms, "banana"),
11869 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11870 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11871
11872 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11873 (const BYTE *)"a\0b\0c\0\0", 7);
11874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11875
11876 /* Patches value exists, is not a squashed guid */
11877 size = MAX_PATH;
11878 lstrcpyA(patch, "apple");
11879 lstrcpyA(transforms, "banana");
11880 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11881 ok(r == ERROR_BAD_CONFIGURATION,
11882 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11883 ok(!lstrcmpA(patch, "apple"),
11884 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11885 ok(!lstrcmpA(transforms, "banana"),
11886 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11887 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11888
11889 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11890 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11891 (const BYTE *)patch_squashed,
11892 lstrlenA(patch_squashed) + 2);
11893 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11894
11895 /* Patches value exists */
11896 size = MAX_PATH;
11897 lstrcpyA(patch, "apple");
11898 lstrcpyA(transforms, "banana");
11899 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11900 ok(r == ERROR_NO_MORE_ITEMS ||
11901 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11902 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11903 ok(!lstrcmpA(patch, "apple") ||
11904 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11905 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11906 ok(!lstrcmpA(transforms, "banana"),
11907 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11908 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11909
11910 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11911 (const BYTE *)"whatever", 9);
11912 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11913
11914 /* patch code value exists */
11915 size = MAX_PATH;
11916 lstrcpyA(patch, "apple");
11917 lstrcpyA(transforms, "banana");
11918 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11919 ok(r == ERROR_NO_MORE_ITEMS ||
11920 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11921 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11922 ok(!lstrcmpA(patch, "apple") ||
11923 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11924 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11925 ok(!lstrcmpA(transforms, "banana") ||
11926 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11927 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11928 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11929
11930 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11931 lstrcatA(keypath, usersid);
11932 lstrcatA(keypath, "\\Patches\\");
11933 lstrcatA(keypath, patch_squashed);
11934
11935 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
11936 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11937
11938 /* userdata patch key exists */
11939 size = MAX_PATH;
11940 lstrcpyA(patch, "apple");
11941 lstrcpyA(transforms, "banana");
11942 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11943 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11944 ok(!lstrcmpA(patch, patchcode),
11945 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11946 ok(!lstrcmpA(transforms, "whatever"),
11947 "Expected \"whatever\", got \"%s\"\n", transforms);
11948 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11949
11950 delete_key(userkey, "", access & KEY_WOW64_64KEY);
11951 RegCloseKey(userkey);
11952 RegDeleteValueA(patches, patch_squashed);
11953 RegDeleteValueA(patches, "Patches");
11954 RegDeleteKeyA(patches, "");
11955 RegCloseKey(patches);
11956 RegDeleteKeyA(prodkey, "");
11957 RegCloseKey(prodkey);
11958
11959 /* MSIINSTALLCONTEXT_MACHINE */
11960
11961 size = MAX_PATH;
11962 lstrcpyA(patch, "apple");
11963 lstrcpyA(transforms, "banana");
11964 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11965 ok(r == ERROR_UNKNOWN_PRODUCT,
11966 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11967 ok(!lstrcmpA(patch, "apple"),
11968 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11969 ok(!lstrcmpA(transforms, "banana"),
11970 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11971 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11972
11973 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11974 lstrcatA(keypath, prod_squashed);
11975
11976 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11977 if (res == ERROR_ACCESS_DENIED)
11978 {
11979 skip("Not enough rights to perform tests\n");
11980 LocalFree(usersid);
11981 return;
11982 }
11983 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11984
11985 /* local product key exists */
11986 size = MAX_PATH;
11987 lstrcpyA(patch, "apple");
11988 lstrcpyA(transforms, "banana");
11989 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11990 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11991 ok(!lstrcmpA(patch, "apple"),
11992 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11993 ok(!lstrcmpA(transforms, "banana"),
11994 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11995 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11996
11997 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11998 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11999
12000 /* Patches key exists */
12001 size = MAX_PATH;
12002 lstrcpyA(patch, "apple");
12003 lstrcpyA(transforms, "banana");
12004 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12005 ok(r == ERROR_NO_MORE_ITEMS ||
12006 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
12007 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
12008 ok(!lstrcmpA(patch, "apple"),
12009 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
12010 ok(!lstrcmpA(transforms, "banana"),
12011 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
12012 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12013
12014 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
12015 (const BYTE *)patch_squashed,
12016 lstrlenA(patch_squashed) + 1);
12017 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12018
12019 /* Patches value exists, is not REG_MULTI_SZ */
12020 size = MAX_PATH;
12021 lstrcpyA(patch, "apple");
12022 lstrcpyA(transforms, "banana");
12023 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12024 ok(r == ERROR_BAD_CONFIGURATION ||
12025 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
12026 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
12027 ok(!lstrcmpA(patch, "apple"),
12028 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
12029 ok(!lstrcmpA(transforms, "banana"),
12030 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
12031 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12032
12033 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
12034 (const BYTE *)"a\0b\0c\0\0", 7);
12035 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12036
12037 /* Patches value exists, is not a squashed guid */
12038 size = MAX_PATH;
12039 lstrcpyA(patch, "apple");
12040 lstrcpyA(transforms, "banana");
12041 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12042 ok(r == ERROR_BAD_CONFIGURATION,
12043 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
12044 ok(!lstrcmpA(patch, "apple"),
12045 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
12046 ok(!lstrcmpA(transforms, "banana"),
12047 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
12048 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12049
12050 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
12051 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
12052 (const BYTE *)patch_squashed,
12053 lstrlenA(patch_squashed) + 2);
12054 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12055
12056 /* Patches value exists */
12057 size = MAX_PATH;
12058 lstrcpyA(patch, "apple");
12059 lstrcpyA(transforms, "banana");
12060 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12061 ok(r == ERROR_NO_MORE_ITEMS ||
12062 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
12063 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
12064 ok(!lstrcmpA(patch, "apple") ||
12065 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
12066 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
12067 ok(!lstrcmpA(transforms, "banana"),
12068 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
12069 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12070
12071 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
12072 (const BYTE *)"whatever", 9);
12073 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12074
12075 /* patch code value exists */
12076 size = MAX_PATH;
12077 lstrcpyA(patch, "apple");
12078 lstrcpyA(transforms, "banana");
12079 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12081 ok(!lstrcmpA(patch, patchcode),
12082 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
12083 ok(!lstrcmpA(transforms, "whatever"),
12084 "Expected \"whatever\", got \"%s\"\n", transforms);
12085 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
12086
12087 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
12088 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
12089 lstrcatA(keypath, prod_squashed);
12090
12091 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12092 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12093
12094 /* local UserData product key exists */
12095 size = MAX_PATH;
12096 lstrcpyA(patch, "apple");
12097 lstrcpyA(transforms, "banana");
12098 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12099 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12100 ok(!lstrcmpA(patch, patchcode),
12101 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
12102 ok(!lstrcmpA(transforms, "whatever"),
12103 "Expected \"whatever\", got \"%s\"\n", transforms);
12104 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
12105
12106 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
12107 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12108
12109 /* local UserData Patches key exists */
12110 size = MAX_PATH;
12111 lstrcpyA(patch, "apple");
12112 lstrcpyA(transforms, "banana");
12113 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12114 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12115 ok(!lstrcmpA(patch, patchcode),
12116 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
12117 ok(!lstrcmpA(transforms, "whatever"),
12118 "Expected \"whatever\", got \"%s\"\n", transforms);
12119 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
12120
12121 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12122 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12123
12124 /* local UserData Product patch key exists */
12125 size = MAX_PATH;
12126 lstrcpyA(patch, "apple");
12127 lstrcpyA(transforms, "banana");
12128 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12129 ok(r == ERROR_NO_MORE_ITEMS ||
12130 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
12131 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
12132 ok(!lstrcmpA(patch, "apple") ||
12133 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
12134 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
12135 ok(!lstrcmpA(transforms, "banana") ||
12136 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
12137 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
12138 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12139
12140 data = MSIPATCHSTATE_APPLIED;
12141 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
12142 (const BYTE *)&data, sizeof(DWORD));
12143 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12144
12145 /* State value exists */
12146 size = MAX_PATH;
12147 lstrcpyA(patch, "apple");
12148 lstrcpyA(transforms, "banana");
12149 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
12150 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12151 ok(!lstrcmpA(patch, patchcode),
12152 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
12153 ok(!lstrcmpA(transforms, "whatever"),
12154 "Expected \"whatever\", got \"%s\"\n", transforms);
12155 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
12156
12157 /* now duplicate some of the tests for the W version */
12158
12159 /* pcchTransformsBuf is too small */
12160 size = 6;
12161 MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
12162 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
12163 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
12164 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
12165 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
12166 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
12167 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
12168 ok(!lstrcmpA(patch, patchcode),
12169 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
12170 ok(!lstrcmpA(transforms, "whate") ||
12171 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
12172 "Expected \"whate\", got \"%s\"\n", transforms);
12173 ok(size == 8, "Expected 8, got %d\n", size);
12174
12175 /* patch code value exists */
12176 size = MAX_PATH;
12177 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
12178 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
12179 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
12180 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12181 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
12182 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
12183 ok(!lstrcmpA(patch, patchcode),
12184 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
12185 ok(!lstrcmpA(transforms, "whatever"),
12186 "Expected \"whatever\", got \"%s\"\n", transforms);
12187 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
12188
12189 RegDeleteValueA(patches, patch_squashed);
12190 RegDeleteValueA(patches, "Patches");
12191 delete_key(patches, "", access & KEY_WOW64_64KEY);
12192 RegCloseKey(patches);
12193 RegDeleteValueA(hpatch, "State");
12194 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12195 RegCloseKey(hpatch);
12196 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12197 RegCloseKey(udpatch);
12198 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12199 RegCloseKey(udprod);
12200 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12201 RegCloseKey(prodkey);
12202 LocalFree(usersid);
12203 }
12204
12205 static void test_MsiGetPatchInfoEx(void)
12206 {
12207 CHAR keypath[MAX_PATH], val[MAX_PATH];
12208 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
12209 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
12210 HKEY prodkey, patches, udprod, props;
12211 HKEY hpatch, udpatch, prodpatches;
12212 LPSTR usersid;
12213 DWORD size;
12214 LONG res;
12215 UINT r;
12216 REGSAM access = KEY_ALL_ACCESS;
12217
12218 if (!pMsiGetPatchInfoExA)
12219 {
12220 win_skip("MsiGetPatchInfoEx not implemented\n");
12221 return;
12222 }
12223
12224 create_test_guid(prodcode, prod_squashed);
12225 create_test_guid(patchcode, patch_squashed);
12226 usersid = get_user_sid();
12227
12228 if (is_wow64)
12229 access |= KEY_WOW64_64KEY;
12230
12231 /* NULL szPatchCode */
12232 lstrcpyA(val, "apple");
12233 size = MAX_PATH;
12234 r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
12235 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12236 ok(r == ERROR_INVALID_PARAMETER,
12237 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12238 ok(!lstrcmpA(val, "apple"),
12239 "Expected val to be unchanged, got \"%s\"\n", val);
12240 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12241
12242 /* empty szPatchCode */
12243 size = MAX_PATH;
12244 lstrcpyA(val, "apple");
12245 r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
12246 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12247 ok(r == ERROR_INVALID_PARAMETER,
12248 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12249 ok(!lstrcmpA(val, "apple"),
12250 "Expected val to be unchanged, got \"%s\"\n", val);
12251 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12252
12253 /* garbage szPatchCode */
12254 size = MAX_PATH;
12255 lstrcpyA(val, "apple");
12256 r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
12257 MSIINSTALLCONTEXT_USERMANAGED,
12258 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12259 ok(r == ERROR_INVALID_PARAMETER,
12260 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12261 ok(!lstrcmpA(val, "apple"),
12262 "Expected val to be unchanged, got \"%s\"\n", val);
12263 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12264
12265 /* guid without brackets */
12266 size = MAX_PATH;
12267 lstrcpyA(val, "apple");
12268 r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
12269 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12270 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12271 ok(r == ERROR_INVALID_PARAMETER,
12272 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12273 ok(!lstrcmpA(val, "apple"),
12274 "Expected val to be unchanged, got \"%s\"\n", val);
12275 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12276
12277 /* guid with brackets */
12278 size = MAX_PATH;
12279 lstrcpyA(val, "apple");
12280 r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
12281 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12282 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12283 ok(r == ERROR_UNKNOWN_PRODUCT,
12284 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12285 ok(!lstrcmpA(val, "apple"),
12286 "Expected val to be unchanged, got \"%s\"\n", val);
12287 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12288
12289 /* same length as guid, but random */
12290 size = MAX_PATH;
12291 lstrcpyA(val, "apple");
12292 r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
12293 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12294 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12295 ok(r == ERROR_INVALID_PARAMETER,
12296 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12297 ok(!lstrcmpA(val, "apple"),
12298 "Expected val to be unchanged, got \"%s\"\n", val);
12299 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12300
12301 /* NULL szProductCode */
12302 lstrcpyA(val, "apple");
12303 size = MAX_PATH;
12304 r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
12305 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12306 ok(r == ERROR_INVALID_PARAMETER,
12307 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12308 ok(!lstrcmpA(val, "apple"),
12309 "Expected val to be unchanged, got \"%s\"\n", val);
12310 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12311
12312 /* empty szProductCode */
12313 size = MAX_PATH;
12314 lstrcpyA(val, "apple");
12315 r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
12316 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12317 ok(r == ERROR_INVALID_PARAMETER,
12318 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12319 ok(!lstrcmpA(val, "apple"),
12320 "Expected val to be unchanged, got \"%s\"\n", val);
12321 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12322
12323 /* garbage szProductCode */
12324 size = MAX_PATH;
12325 lstrcpyA(val, "apple");
12326 r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
12327 MSIINSTALLCONTEXT_USERMANAGED,
12328 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12329 ok(r == ERROR_INVALID_PARAMETER,
12330 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12331 ok(!lstrcmpA(val, "apple"),
12332 "Expected val to be unchanged, got \"%s\"\n", val);
12333 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12334
12335 /* guid without brackets */
12336 size = MAX_PATH;
12337 lstrcpyA(val, "apple");
12338 r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
12339 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12340 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12341 ok(r == ERROR_INVALID_PARAMETER,
12342 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12343 ok(!lstrcmpA(val, "apple"),
12344 "Expected val to be unchanged, got \"%s\"\n", val);
12345 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12346
12347 /* guid with brackets */
12348 size = MAX_PATH;
12349 lstrcpyA(val, "apple");
12350 r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
12351 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12352 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12353 ok(r == ERROR_UNKNOWN_PRODUCT,
12354 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12355 ok(!lstrcmpA(val, "apple"),
12356 "Expected val to be unchanged, got \"%s\"\n", val);
12357 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12358
12359 /* same length as guid, but random */
12360 size = MAX_PATH;
12361 lstrcpyA(val, "apple");
12362 r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
12363 NULL, MSIINSTALLCONTEXT_USERMANAGED,
12364 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12365 ok(r == ERROR_INVALID_PARAMETER,
12366 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12367 ok(!lstrcmpA(val, "apple"),
12368 "Expected val to be unchanged, got \"%s\"\n", val);
12369 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12370
12371 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
12372 size = MAX_PATH;
12373 lstrcpyA(val, "apple");
12374 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
12375 MSIINSTALLCONTEXT_USERMANAGED,
12376 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12377 ok(r == ERROR_INVALID_PARAMETER,
12378 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12379 ok(!lstrcmpA(val, "apple"),
12380 "Expected val to be unchanged, got \"%s\"\n", val);
12381 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12382
12383 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
12384 size = MAX_PATH;
12385 lstrcpyA(val, "apple");
12386 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
12387 MSIINSTALLCONTEXT_USERUNMANAGED,
12388 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12389 ok(r == ERROR_INVALID_PARAMETER,
12390 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12391 ok(!lstrcmpA(val, "apple"),
12392 "Expected val to be unchanged, got \"%s\"\n", val);
12393 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12394
12395 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
12396 size = MAX_PATH;
12397 lstrcpyA(val, "apple");
12398 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
12399 MSIINSTALLCONTEXT_MACHINE,
12400 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12401 ok(r == ERROR_INVALID_PARAMETER,
12402 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12403 ok(!lstrcmpA(val, "apple"),
12404 "Expected val to be unchanged, got \"%s\"\n", val);
12405 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12406
12407 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
12408 size = MAX_PATH;
12409 lstrcpyA(val, "apple");
12410 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12411 MSIINSTALLCONTEXT_MACHINE,
12412 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12413 ok(r == ERROR_INVALID_PARAMETER,
12414 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12415 ok(!lstrcmpA(val, "apple"),
12416 "Expected val to be unchanged, got \"%s\"\n", val);
12417 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12418
12419 /* dwContext is out of range */
12420 size = MAX_PATH;
12421 lstrcpyA(val, "apple");
12422 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12423 MSIINSTALLCONTEXT_NONE,
12424 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12425 ok(r == ERROR_INVALID_PARAMETER,
12426 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12427 ok(!lstrcmpA(val, "apple"),
12428 "Expected val to be unchanged, got \"%s\"\n", val);
12429 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12430
12431 /* dwContext is out of range */
12432 size = MAX_PATH;
12433 lstrcpyA(val, "apple");
12434 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12435 MSIINSTALLCONTEXT_ALL,
12436 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12437 ok(r == ERROR_INVALID_PARAMETER,
12438 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12439 ok(!lstrcmpA(val, "apple"),
12440 "Expected val to be unchanged, got \"%s\"\n", val);
12441 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12442
12443 /* dwContext is invalid */
12444 size = MAX_PATH;
12445 lstrcpyA(val, "apple");
12446 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
12447 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12448 ok(r == ERROR_INVALID_PARAMETER,
12449 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12450 ok(!lstrcmpA(val, "apple"),
12451 "Expected val to be unchanged, got \"%s\"\n", val);
12452 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12453
12454 /* MSIINSTALLCONTEXT_USERMANAGED */
12455
12456 size = MAX_PATH;
12457 lstrcpyA(val, "apple");
12458 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12459 MSIINSTALLCONTEXT_USERMANAGED,
12460 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12461 ok(r == ERROR_UNKNOWN_PRODUCT,
12462 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12463 ok(!lstrcmpA(val, "apple"),
12464 "Expected val to be unchanged, got \"%s\"\n", val);
12465 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12466
12467 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12468 lstrcatA(keypath, usersid);
12469 lstrcatA(keypath, "\\Products\\");
12470 lstrcatA(keypath, prod_squashed);
12471
12472 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12473 if (res == ERROR_ACCESS_DENIED)
12474 {
12475 skip("Not enough rights to perform tests\n");
12476 LocalFree(usersid);
12477 return;
12478 }
12479 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12480
12481 /* local UserData product key exists */
12482 size = MAX_PATH;
12483 lstrcpyA(val, "apple");
12484 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12485 MSIINSTALLCONTEXT_USERMANAGED,
12486 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12487 ok(r == ERROR_UNKNOWN_PRODUCT,
12488 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12489 ok(!lstrcmpA(val, "apple"),
12490 "Expected val to be unchanged, got \"%s\"\n", val);
12491 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12492
12493 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12494 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12495
12496 /* InstallProperties key exists */
12497 size = MAX_PATH;
12498 lstrcpyA(val, "apple");
12499 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12500 MSIINSTALLCONTEXT_USERMANAGED,
12501 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12502 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12503 ok(!lstrcmpA(val, "apple"),
12504 "Expected val to be unchanged, got \"%s\"\n", val);
12505 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12506
12507 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12508 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12509
12510 /* Patches key exists */
12511 size = MAX_PATH;
12512 lstrcpyA(val, "apple");
12513 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12514 MSIINSTALLCONTEXT_USERMANAGED,
12515 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12516 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCHA, got %d\n", r);
12517 ok(!lstrcmpA(val, "apple"),
12518 "Expected val to be unchanged, got \"%s\"\n", val);
12519 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12520
12521 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12523
12524 /* Patches key exists */
12525 size = MAX_PATH;
12526 lstrcpyA(val, "apple");
12527 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12528 MSIINSTALLCONTEXT_USERMANAGED,
12529 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12530 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12531 ok(!lstrcmpA(val, "apple"),
12532 "Expected val to be unchanged, got \"%s\"\n", val);
12533 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12534
12535 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
12536 lstrcatA(keypath, usersid);
12537 lstrcatA(keypath, "\\Installer\\Products\\");
12538 lstrcatA(keypath, prod_squashed);
12539
12540 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
12541 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12542
12543 /* managed product key exists */
12544 size = MAX_PATH;
12545 lstrcpyA(val, "apple");
12546 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12547 MSIINSTALLCONTEXT_USERMANAGED,
12548 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12549 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12550 ok(!lstrcmpA(val, "apple"),
12551 "Expected val to be unchanged, got \"%s\"\n", val);
12552 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12553
12554 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
12555 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12556
12557 /* Patches key exists */
12558 size = MAX_PATH;
12559 lstrcpyA(val, "apple");
12560 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12561 MSIINSTALLCONTEXT_USERMANAGED,
12562 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12563 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12564 ok(!lstrcmpA(val, "apple"),
12565 "Expected val to be unchanged, got \"%s\"\n", val);
12566 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12567
12568 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12569 (const BYTE *)"transforms", 11);
12570 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12571
12572 /* specific patch value exists */
12573 size = MAX_PATH;
12574 lstrcpyA(val, "apple");
12575 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12576 MSIINSTALLCONTEXT_USERMANAGED,
12577 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12578 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12579 ok(!lstrcmpA(val, "apple"),
12580 "Expected val to be unchanged, got \"%s\"\n", val);
12581 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12582
12583 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12584 lstrcatA(keypath, usersid);
12585 lstrcatA(keypath, "\\Patches\\");
12586 lstrcatA(keypath, patch_squashed);
12587
12588 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12589 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12590
12591 /* UserData Patches key exists */
12592 size = MAX_PATH;
12593 lstrcpyA(val, "apple");
12594 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12595 MSIINSTALLCONTEXT_USERMANAGED,
12596 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12597 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12598 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12599 ok(size == 0, "Expected 0, got %d\n", size);
12600
12601 res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
12602 (const BYTE *)"pack", 5);
12603 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12604
12605 /* ManagedLocalPatch value exists */
12606 size = MAX_PATH;
12607 lstrcpyA(val, "apple");
12608 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12609 MSIINSTALLCONTEXT_USERMANAGED,
12610 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12611 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12612 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12613 ok(size == 4, "Expected 4, got %d\n", size);
12614
12615 size = MAX_PATH;
12616 lstrcpyA(val, "apple");
12617 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12618 MSIINSTALLCONTEXT_USERMANAGED,
12619 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12620 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12621 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12622 ok(size == 10, "Expected 10, got %d\n", size);
12623
12624 res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
12625 (const BYTE *)"mydate", 7);
12626 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12627
12628 /* Installed value exists */
12629 size = MAX_PATH;
12630 lstrcpyA(val, "apple");
12631 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12632 MSIINSTALLCONTEXT_USERMANAGED,
12633 INSTALLPROPERTY_INSTALLDATEA, val, &size);
12634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12635 ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
12636 ok(size == 6, "Expected 6, got %d\n", size);
12637
12638 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
12639 (const BYTE *)"yes", 4);
12640 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12641
12642 /* Uninstallable value exists */
12643 size = MAX_PATH;
12644 lstrcpyA(val, "apple");
12645 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12646 MSIINSTALLCONTEXT_USERMANAGED,
12647 INSTALLPROPERTY_UNINSTALLABLEA, val, &size);
12648 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12649 ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
12650 ok(size == 3, "Expected 3, got %d\n", size);
12651
12652 res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
12653 (const BYTE *)"good", 5);
12654 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12655
12656 /* State value exists */
12657 size = MAX_PATH;
12658 lstrcpyA(val, "apple");
12659 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12660 MSIINSTALLCONTEXT_USERMANAGED,
12661 INSTALLPROPERTY_PATCHSTATEA, val, &size);
12662 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12663 ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
12664 ok(size == 4, "Expected 4, got %d\n", size);
12665
12666 size = 1;
12667 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
12668 (const BYTE *)&size, sizeof(DWORD));
12669 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12670
12671 /* State value exists */
12672 size = MAX_PATH;
12673 lstrcpyA(val, "apple");
12674 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12675 MSIINSTALLCONTEXT_USERMANAGED,
12676 INSTALLPROPERTY_PATCHSTATEA, val, &size);
12677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12678 ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
12679 ok(size == 1, "Expected 1, got %d\n", size);
12680
12681 size = 1;
12682 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_DWORD,
12683 (const BYTE *)&size, sizeof(DWORD));
12684 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12685
12686 /* Uninstallable value exists */
12687 size = MAX_PATH;
12688 lstrcpyA(val, "apple");
12689 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12690 MSIINSTALLCONTEXT_USERMANAGED,
12691 INSTALLPROPERTY_UNINSTALLABLEA, val, &size);
12692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12693 ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
12694 ok(size == 1, "Expected 1, got %d\n", size);
12695
12696 res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
12697 (const BYTE *)"display", 8);
12698 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12699
12700 /* DisplayName value exists */
12701 size = MAX_PATH;
12702 lstrcpyA(val, "apple");
12703 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12704 MSIINSTALLCONTEXT_USERMANAGED,
12705 INSTALLPROPERTY_DISPLAYNAMEA, val, &size);
12706 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12707 ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
12708 ok(size == 7, "Expected 7, got %d\n", size);
12709
12710 res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
12711 (const BYTE *)"moreinfo", 9);
12712 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12713
12714 /* MoreInfoURL value exists */
12715 size = MAX_PATH;
12716 lstrcpyA(val, "apple");
12717 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12718 MSIINSTALLCONTEXT_USERMANAGED,
12719 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12720 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12721 ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
12722 ok(size == 8, "Expected 8, got %d\n", size);
12723
12724 /* szProperty is invalid */
12725 size = MAX_PATH;
12726 lstrcpyA(val, "apple");
12727 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12728 MSIINSTALLCONTEXT_USERMANAGED,
12729 "IDontExist", val, &size);
12730 ok(r == ERROR_UNKNOWN_PROPERTY,
12731 "Expected ERROR_UNKNOWN_PROPERTY, 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 /* lpValue is NULL, while pcchValue is non-NULL */
12736 size = MAX_PATH;
12737 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12738 MSIINSTALLCONTEXT_USERMANAGED,
12739 INSTALLPROPERTY_MOREINFOURLA, NULL, &size);
12740 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12741 ok(size == 16, "Expected 16, got %d\n", size);
12742
12743 /* pcchValue is NULL, while lpValue is non-NULL */
12744 lstrcpyA(val, "apple");
12745 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12746 MSIINSTALLCONTEXT_USERMANAGED,
12747 INSTALLPROPERTY_MOREINFOURLA, val, NULL);
12748 ok(r == ERROR_INVALID_PARAMETER,
12749 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12750 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12751
12752 /* both lpValue and pcchValue are NULL */
12753 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12754 MSIINSTALLCONTEXT_USERMANAGED,
12755 INSTALLPROPERTY_MOREINFOURLA, NULL, NULL);
12756 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12757
12758 /* pcchValue doesn't have enough room for NULL terminator */
12759 size = 8;
12760 lstrcpyA(val, "apple");
12761 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12762 MSIINSTALLCONTEXT_USERMANAGED,
12763 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12764 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
12765 ok(!lstrcmpA(val, "moreinf"),
12766 "Expected \"moreinf\", got \"%s\"\n", val);
12767 ok(size == 16, "Expected 16, got %d\n", size);
12768
12769 /* pcchValue has exactly enough room for NULL terminator */
12770 size = 9;
12771 lstrcpyA(val, "apple");
12772 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12773 MSIINSTALLCONTEXT_USERMANAGED,
12774 INSTALLPROPERTY_MOREINFOURLA, val, &size);
12775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12776 ok(!lstrcmpA(val, "moreinfo"),
12777 "Expected \"moreinfo\", got \"%s\"\n", val);
12778 ok(size == 8, "Expected 8, got %d\n", size);
12779
12780 /* pcchValue is too small, lpValue is NULL */
12781 size = 0;
12782 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12783 MSIINSTALLCONTEXT_USERMANAGED,
12784 INSTALLPROPERTY_MOREINFOURLA, NULL, &size);
12785 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12786 ok(size == 16, "Expected 16, got %d\n", size);
12787
12788 RegDeleteValueA(prodpatches, patch_squashed);
12789 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12790 RegCloseKey(prodpatches);
12791 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12792 RegCloseKey(prodkey);
12793
12794 /* UserData is sufficient for all properties
12795 * except INSTALLPROPERTY_TRANSFORMS
12796 */
12797 size = MAX_PATH;
12798 lstrcpyA(val, "apple");
12799 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12800 MSIINSTALLCONTEXT_USERMANAGED,
12801 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12802 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12803 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12804 ok(size == 4, "Expected 4, got %d\n", size);
12805
12806 /* UserData is sufficient for all properties
12807 * except INSTALLPROPERTY_TRANSFORMS
12808 */
12809 size = MAX_PATH;
12810 lstrcpyA(val, "apple");
12811 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12812 MSIINSTALLCONTEXT_USERMANAGED,
12813 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12814 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12815 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12816 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12817
12818 RegDeleteValueA(hpatch, "MoreInfoURL");
12819 RegDeleteValueA(hpatch, "Display");
12820 RegDeleteValueA(hpatch, "State");
12821 RegDeleteValueA(hpatch, "Uninstallable");
12822 RegDeleteValueA(hpatch, "Installed");
12823 RegDeleteValueA(udpatch, "ManagedLocalPackage");
12824 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12825 RegCloseKey(udpatch);
12826 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12827 RegCloseKey(hpatch);
12828 delete_key(patches, "", access & KEY_WOW64_64KEY);
12829 RegCloseKey(patches);
12830 delete_key(props, "", access & KEY_WOW64_64KEY);
12831 RegCloseKey(props);
12832 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12833 RegCloseKey(udprod);
12834
12835 /* MSIINSTALLCONTEXT_USERUNMANAGED */
12836
12837 size = MAX_PATH;
12838 lstrcpyA(val, "apple");
12839 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12840 MSIINSTALLCONTEXT_USERUNMANAGED,
12841 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12842 ok(r == ERROR_UNKNOWN_PRODUCT,
12843 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12844 ok(!lstrcmpA(val, "apple"),
12845 "Expected val to be unchanged, got \"%s\"\n", val);
12846 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12847
12848 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12849 lstrcatA(keypath, usersid);
12850 lstrcatA(keypath, "\\Products\\");
12851 lstrcatA(keypath, prod_squashed);
12852
12853 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12854 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12855
12856 /* local UserData product key exists */
12857 size = MAX_PATH;
12858 lstrcpyA(val, "apple");
12859 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12860 MSIINSTALLCONTEXT_USERUNMANAGED,
12861 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12862 ok(r == ERROR_UNKNOWN_PRODUCT,
12863 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12864 ok(!lstrcmpA(val, "apple"),
12865 "Expected val to be unchanged, got \"%s\"\n", val);
12866 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12867
12868 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12869 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12870
12871 /* InstallProperties key exists */
12872 size = MAX_PATH;
12873 lstrcpyA(val, "apple");
12874 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12875 MSIINSTALLCONTEXT_USERUNMANAGED,
12876 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12877 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12878 ok(!lstrcmpA(val, "apple"),
12879 "Expected val to be unchanged, got \"%s\"\n", val);
12880 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12881
12882 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12883 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12884
12885 /* Patches key exists */
12886 size = MAX_PATH;
12887 lstrcpyA(val, "apple");
12888 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12889 MSIINSTALLCONTEXT_USERUNMANAGED,
12890 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12891 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12892 ok(!lstrcmpA(val, "apple"),
12893 "Expected val to be unchanged, got \"%s\"\n", val);
12894 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12895
12896 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12897 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12898
12899 /* Patches key exists */
12900 size = MAX_PATH;
12901 lstrcpyA(val, "apple");
12902 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12903 MSIINSTALLCONTEXT_USERUNMANAGED,
12904 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12905 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12906 ok(!lstrcmpA(val, "apple"),
12907 "Expected val to be unchanged, got \"%s\"\n", val);
12908 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12909
12910 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
12911 lstrcatA(keypath, prod_squashed);
12912
12913 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
12914 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12915
12916 /* current user product key exists */
12917 size = MAX_PATH;
12918 lstrcpyA(val, "apple");
12919 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12920 MSIINSTALLCONTEXT_USERUNMANAGED,
12921 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12922 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12923 ok(!lstrcmpA(val, "apple"),
12924 "Expected val to be unchanged, got \"%s\"\n", val);
12925 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12926
12927 res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
12928 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12929
12930 /* Patches key exists */
12931 size = MAX_PATH;
12932 lstrcpyA(val, "apple");
12933 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12934 MSIINSTALLCONTEXT_USERUNMANAGED,
12935 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12936 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12937 ok(!lstrcmpA(val, "apple"),
12938 "Expected val to be unchanged, got \"%s\"\n", val);
12939 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12940
12941 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12942 (const BYTE *)"transforms", 11);
12943 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12944
12945 /* specific patch value exists */
12946 size = MAX_PATH;
12947 lstrcpyA(val, "apple");
12948 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12949 MSIINSTALLCONTEXT_USERUNMANAGED,
12950 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12951 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12952 ok(!lstrcmpA(val, "apple"),
12953 "Expected val to be unchanged, got \"%s\"\n", val);
12954 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12955
12956 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12957 lstrcatA(keypath, usersid);
12958 lstrcatA(keypath, "\\Patches\\");
12959 lstrcatA(keypath, patch_squashed);
12960
12961 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12962 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12963
12964 /* UserData Patches key exists */
12965 size = MAX_PATH;
12966 lstrcpyA(val, "apple");
12967 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12968 MSIINSTALLCONTEXT_USERUNMANAGED,
12969 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12970 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12971 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12972 ok(size == 0, "Expected 0, got %d\n", size);
12973
12974 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12975 (const BYTE *)"pack", 5);
12976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12977
12978 /* LocalPatch value exists */
12979 size = MAX_PATH;
12980 lstrcpyA(val, "apple");
12981 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12982 MSIINSTALLCONTEXT_USERUNMANAGED,
12983 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12984 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12985 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12986 ok(size == 4, "Expected 4, got %d\n", size);
12987
12988 size = MAX_PATH;
12989 lstrcpyA(val, "apple");
12990 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12991 MSIINSTALLCONTEXT_USERUNMANAGED,
12992 INSTALLPROPERTY_TRANSFORMSA, val, &size);
12993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12994 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12995 ok(size == 10, "Expected 10, got %d\n", size);
12996
12997 RegDeleteValueA(prodpatches, patch_squashed);
12998 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12999 RegCloseKey(prodpatches);
13000 RegDeleteKeyA(prodkey, "");
13001 RegCloseKey(prodkey);
13002
13003 /* UserData is sufficient for all properties
13004 * except INSTALLPROPERTY_TRANSFORMS
13005 */
13006 size = MAX_PATH;
13007 lstrcpyA(val, "apple");
13008 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
13009 MSIINSTALLCONTEXT_USERUNMANAGED,
13010 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13012 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
13013 ok(size == 4, "Expected 4, got %d\n", size);
13014
13015 /* UserData is sufficient for all properties
13016 * except INSTALLPROPERTY_TRANSFORMS
13017 */
13018 size = MAX_PATH;
13019 lstrcpyA(val, "apple");
13020 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
13021 MSIINSTALLCONTEXT_USERUNMANAGED,
13022 INSTALLPROPERTY_TRANSFORMSA, val, &size);
13023 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
13024 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
13025 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
13026
13027 RegDeleteValueA(udpatch, "LocalPackage");
13028 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
13029 RegCloseKey(udpatch);
13030 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
13031 RegCloseKey(hpatch);
13032 delete_key(patches, "", access & KEY_WOW64_64KEY);
13033 RegCloseKey(patches);
13034 delete_key(props, "", access & KEY_WOW64_64KEY);
13035 RegCloseKey(props);
13036 delete_key(udprod, "", access & KEY_WOW64_64KEY);
13037 RegCloseKey(udprod);
13038
13039 /* MSIINSTALLCONTEXT_MACHINE */
13040
13041 size = MAX_PATH;
13042 lstrcpyA(val, "apple");
13043 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13044 MSIINSTALLCONTEXT_MACHINE,
13045 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13046 ok(r == ERROR_UNKNOWN_PRODUCT,
13047 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13048 ok(!lstrcmpA(val, "apple"),
13049 "Expected val to be unchanged, got \"%s\"\n", val);
13050 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
13051
13052 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
13053 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
13054 lstrcatA(keypath, prod_squashed);
13055
13056 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
13057 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13058
13059 /* local UserData product key exists */
13060 size = MAX_PATH;
13061 lstrcpyA(val, "apple");
13062 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13063 MSIINSTALLCONTEXT_MACHINE,
13064 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13065 ok(r == ERROR_UNKNOWN_PRODUCT,
13066 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13067 ok(!lstrcmpA(val, "apple"),
13068 "Expected val to be unchanged, got \"%s\"\n", val);
13069 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
13070
13071 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
13072 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13073
13074 /* InstallProperties key exists */
13075 size = MAX_PATH;
13076 lstrcpyA(val, "apple");
13077 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13078 MSIINSTALLCONTEXT_MACHINE,
13079 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13080 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
13081 ok(!lstrcmpA(val, "apple"),
13082 "Expected val to be unchanged, got \"%s\"\n", val);
13083 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
13084
13085 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
13086 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13087
13088 /* Patches key exists */
13089 size = MAX_PATH;
13090 lstrcpyA(val, "apple");
13091 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13092 MSIINSTALLCONTEXT_MACHINE,
13093 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13094 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
13095 ok(!lstrcmpA(val, "apple"),
13096 "Expected val to be unchanged, got \"%s\"\n", val);
13097 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
13098
13099 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
13100 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13101
13102 /* Patches key exists */
13103 size = MAX_PATH;
13104 lstrcpyA(val, "apple");
13105 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13106 MSIINSTALLCONTEXT_MACHINE,
13107 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13108 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
13109 ok(!lstrcmpA(val, "apple"),
13110 "Expected val to be unchanged, got \"%s\"\n", val);
13111 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
13112
13113 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
13114 lstrcatA(keypath, prod_squashed);
13115
13116 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
13117 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13118
13119 /* local product key exists */
13120 size = MAX_PATH;
13121 lstrcpyA(val, "apple");
13122 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13123 MSIINSTALLCONTEXT_MACHINE,
13124 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13125 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
13126 ok(!lstrcmpA(val, "apple"),
13127 "Expected val to be unchanged, got \"%s\"\n", val);
13128 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
13129
13130 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
13131 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13132
13133 /* Patches key exists */
13134 size = MAX_PATH;
13135 lstrcpyA(val, "apple");
13136 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13137 MSIINSTALLCONTEXT_MACHINE,
13138 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13139 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
13140 ok(!lstrcmpA(val, "apple"),
13141 "Expected val to be unchanged, got \"%s\"\n", val);
13142 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
13143
13144 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
13145 (const BYTE *)"transforms", 11);
13146 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13147
13148 /* specific patch value exists */
13149 size = MAX_PATH;
13150 lstrcpyA(val, "apple");
13151 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13152 MSIINSTALLCONTEXT_MACHINE,
13153 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13154 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
13155 ok(!lstrcmpA(val, "apple"),
13156 "Expected val to be unchanged, got \"%s\"\n", val);
13157 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
13158
13159 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
13160 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
13161 lstrcatA(keypath, patch_squashed);
13162
13163 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
13164 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13165
13166 /* UserData Patches key exists */
13167 size = MAX_PATH;
13168 lstrcpyA(val, "apple");
13169 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13170 MSIINSTALLCONTEXT_MACHINE,
13171 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13172 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13173 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
13174 ok(size == 0, "Expected 0, got %d\n", size);
13175
13176 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
13177 (const BYTE *)"pack", 5);
13178 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13179
13180 /* LocalPatch value exists */
13181 size = MAX_PATH;
13182 lstrcpyA(val, "apple");
13183 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13184 MSIINSTALLCONTEXT_MACHINE,
13185 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13186 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13187 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
13188 ok(size == 4, "Expected 4, got %d\n", size);
13189
13190 size = MAX_PATH;
13191 lstrcpyA(val, "apple");
13192 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13193 MSIINSTALLCONTEXT_MACHINE,
13194 INSTALLPROPERTY_TRANSFORMSA, val, &size);
13195 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13196 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
13197 ok(size == 10, "Expected 10, got %d\n", size);
13198
13199 RegDeleteValueA(prodpatches, patch_squashed);
13200 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
13201 RegCloseKey(prodpatches);
13202 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
13203 RegCloseKey(prodkey);
13204
13205 /* UserData is sufficient for all properties
13206 * except INSTALLPROPERTY_TRANSFORMS
13207 */
13208 size = MAX_PATH;
13209 lstrcpyA(val, "apple");
13210 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13211 MSIINSTALLCONTEXT_MACHINE,
13212 INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13213 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13214 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
13215 ok(size == 4, "Expected 4, got %d\n", size);
13216
13217 /* UserData is sufficient for all properties
13218 * except INSTALLPROPERTY_TRANSFORMS
13219 */
13220 size = MAX_PATH;
13221 lstrcpyA(val, "apple");
13222 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
13223 MSIINSTALLCONTEXT_MACHINE,
13224 INSTALLPROPERTY_TRANSFORMSA, val, &size);
13225 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
13226 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
13227 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
13228
13229 RegDeleteValueA(udpatch, "LocalPackage");
13230 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
13231 RegCloseKey(udpatch);
13232 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
13233 RegCloseKey(hpatch);
13234 delete_key(patches, "", access & KEY_WOW64_64KEY);
13235 RegCloseKey(patches);
13236 delete_key(props, "", access & KEY_WOW64_64KEY);
13237 RegCloseKey(props);
13238 delete_key(udprod, "", access & KEY_WOW64_64KEY);
13239 RegCloseKey(udprod);
13240 LocalFree(usersid);
13241 }
13242
13243 static void test_MsiGetPatchInfo(void)
13244 {
13245 UINT r;
13246 char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
13247 char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
13248 WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
13249 HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
13250 HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
13251 DWORD size;
13252 LONG res;
13253 REGSAM access = KEY_ALL_ACCESS;
13254
13255 create_test_guid(patch_code, patch_squashed);
13256 create_test_guid(prod_code, prod_squashed);
13257 MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
13258
13259 if (is_wow64)
13260 access |= KEY_WOW64_64KEY;
13261
13262 r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
13263 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13264
13265 r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
13266 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13267
13268 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
13269 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13270
13271 size = 0;
13272 r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
13273 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13274
13275 r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
13276 ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
13277
13278 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
13279 lstrcatA(keypath, prod_squashed);
13280
13281 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
13282 if (res == ERROR_ACCESS_DENIED)
13283 {
13284 skip("Not enough rights to perform tests\n");
13285 return;
13286 }
13287 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13288
13289 /* product key exists */
13290 size = MAX_PATH;
13291 lstrcpyA(val, "apple");
13292 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13293 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13294 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
13295 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13296
13297 res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
13298 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13299
13300 /* patches key exists */
13301 size = MAX_PATH;
13302 lstrcpyA(val, "apple");
13303 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13304 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13305 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
13306 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13307
13308 res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
13309 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13310
13311 /* patch key exists */
13312 size = MAX_PATH;
13313 lstrcpyA(val, "apple");
13314 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13315 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13316 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
13317 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13318
13319 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
13320 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
13321 lstrcatA(keypath, prod_squashed);
13322
13323 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
13324 if (res == ERROR_ACCESS_DENIED)
13325 {
13326 skip("Not enough rights to perform tests\n");
13327 goto done;
13328 }
13329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
13330
13331 /* UserData product key exists */
13332 size = MAX_PATH;
13333 lstrcpyA(val, "apple");
13334 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13335 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13336 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
13337 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13338
13339 res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
13340 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13341
13342 /* InstallProperties key exists */
13343 size = MAX_PATH;
13344 lstrcpyA(val, "apple");
13345 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13346 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13347 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
13348 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13349
13350 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
13351 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13352
13353 /* UserData Patches key exists */
13354 size = MAX_PATH;
13355 lstrcpyA(val, "apple");
13356 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13357 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13358 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
13359 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13360
13361 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
13362 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13363
13364 res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
13365 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13366
13367 /* UserData product patch key exists */
13368 size = MAX_PATH;
13369 lstrcpyA(val, "apple");
13370 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13371 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
13372 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
13373 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
13374
13375 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
13376 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
13377 lstrcatA(keypath, patch_squashed);
13378
13379 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
13380 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13381
13382 res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
13383 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
13384
13385 /* UserData Patch key exists */
13386 size = 0;
13387 lstrcpyA(val, "apple");
13388 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13389 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
13390 ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
13391 ok(size == 11, "expected 11 got %u\n", size);
13392
13393 size = MAX_PATH;
13394 lstrcpyA(val, "apple");
13395 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
13396 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
13397 ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
13398 ok(size == 11, "expected 11 got %u\n", size);
13399
13400 size = 0;
13401 valW[0] = 0;
13402 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
13403 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
13404 ok(!valW[0], "expected 0 got %u\n", valW[0]);
13405 ok(size == 11, "expected 11 got %u\n", size);
13406
13407 size = MAX_PATH;
13408 valW[0] = 0;
13409 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
13410 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
13411 ok(valW[0], "expected > 0 got %u\n", valW[0]);
13412 ok(size == 11, "expected 11 got %u\n", size);
13413
13414 delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
13415 RegCloseKey(hkey_udproductpatch);
13416 delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
13417 RegCloseKey(hkey_udproductpatches);
13418 delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
13419 RegCloseKey(hkey_udpatch);
13420 delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
13421 RegCloseKey(hkey_udpatches);
13422 delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
13423 RegCloseKey(hkey_udprops);
13424 delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
13425 RegCloseKey(hkey_udproduct);
13426
13427 done:
13428 delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
13429 RegCloseKey(hkey_patches);
13430 delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
13431 RegCloseKey(hkey_product);
13432 delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
13433 RegCloseKey(hkey_patch);
13434 }
13435
13436 static void test_MsiEnumProducts(void)
13437 {
13438 UINT r;
13439 BOOL found1, found2, found3;
13440 DWORD index;
13441 char product1[39], product2[39], product3[39], guid[39];
13442 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
13443 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
13444 char *usersid;
13445 HKEY key1, key2, key3;
13446 REGSAM access = KEY_ALL_ACCESS;
13447
13448 create_test_guid(product1, product_squashed1);
13449 create_test_guid(product2, product_squashed2);
13450 create_test_guid(product3, product_squashed3);
13451 usersid = get_user_sid();
13452
13453 if (is_wow64)
13454 access |= KEY_WOW64_64KEY;
13455
13456 strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
13457 strcat(keypath2, usersid);
13458 strcat(keypath2, "\\Installer\\Products\\");
13459 strcat(keypath2, product_squashed2);
13460
13461 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
13462 if (r == ERROR_ACCESS_DENIED)
13463 {
13464 skip("Not enough rights to perform tests\n");
13465 LocalFree(usersid);
13466 return;
13467 }
13468 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13469
13470 strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
13471 strcat(keypath1, product_squashed1);
13472
13473 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
13474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13475
13476 strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
13477 strcat(keypath3, product_squashed3);
13478
13479 r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
13480 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13481
13482 index = 0;
13483 r = MsiEnumProductsA(index, guid);
13484 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13485
13486 r = MsiEnumProductsA(index, NULL);
13487 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
13488
13489 index = 2;
13490 r = MsiEnumProductsA(index, guid);
13491 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
13492
13493 index = 0;
13494 r = MsiEnumProductsA(index, guid);
13495 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13496
13497 found1 = found2 = found3 = FALSE;
13498 while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
13499 {
13500 if (!strcmp(product1, guid)) found1 = TRUE;
13501 if (!strcmp(product2, guid)) found2 = TRUE;
13502 if (!strcmp(product3, guid)) found3 = TRUE;
13503 index++;
13504 }
13505 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
13506 ok(found1, "product1 not found\n");
13507 ok(found2, "product2 not found\n");
13508 ok(found3, "product3 not found\n");
13509
13510 delete_key(key1, "", access & KEY_WOW64_64KEY);
13511 delete_key(key2, "", access & KEY_WOW64_64KEY);
13512 RegDeleteKeyA(key3, "");
13513 RegCloseKey(key1);
13514 RegCloseKey(key2);
13515 RegCloseKey(key3);
13516 LocalFree(usersid);
13517 }
13518
13519 static void test_MsiGetFileSignatureInformation(void)
13520 {
13521 HRESULT hr;
13522 const CERT_CONTEXT *cert;
13523 DWORD len;
13524
13525 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
13526 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13527
13528 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
13529 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13530
13531 hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
13532 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13533
13534 hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
13535 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13536
13537 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
13538 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13539
13540 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
13541 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13542
13543 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
13544 todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
13545
13546 create_file( "signature.bin", "signature", sizeof("signature") );
13547
13548 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
13549 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13550
13551 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
13552 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
13553
13554 cert = (const CERT_CONTEXT *)0xdeadbeef;
13555 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
13556 todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
13557 ok(cert == NULL, "got %p\n", cert);
13558
13559 DeleteFileA( "signature.bin" );
13560 }
13561
13562 static void test_MsiEnumProductsEx(void)
13563 {
13564 UINT r;
13565 DWORD len, index;
13566 MSIINSTALLCONTEXT context;
13567 char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
13568 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
13569 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
13570 HKEY key1 = NULL, key2 = NULL, key3 = NULL;
13571 REGSAM access = KEY_ALL_ACCESS;
13572 char *usersid = get_user_sid();
13573
13574 if (!pMsiEnumProductsExA)
13575 {
13576 win_skip("MsiEnumProductsExA not implemented\n");
13577 return;
13578 }
13579
13580 create_test_guid( product0, NULL );
13581 create_test_guid( product1, product_squashed1 );
13582 create_test_guid( product2, product_squashed2 );
13583 create_test_guid( product3, product_squashed3 );
13584
13585 if (is_wow64) access |= KEY_WOW64_64KEY;
13586
13587 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
13588 strcat( keypath2, usersid );
13589 strcat( keypath2, "\\Installer\\Products\\" );
13590 strcat( keypath2, product_squashed2 );
13591
13592 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13593 if (r == ERROR_ACCESS_DENIED)
13594 {
13595 skip( "insufficient rights\n" );
13596 goto done;
13597 }
13598 ok( r == ERROR_SUCCESS, "got %u\n", r );
13599
13600 strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
13601 strcat( keypath1, product_squashed1 );
13602
13603 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13604 ok( r == ERROR_SUCCESS, "got %u\n", r );
13605
13606 strcpy( keypath3, usersid );
13607 strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
13608 strcat( keypath3, product_squashed3 );
13609
13610 r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
13611 ok( r == ERROR_SUCCESS, "got %u\n", r );
13612
13613 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
13614 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13615
13616 len = sizeof(sid);
13617 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
13618 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13619 ok( len == sizeof(sid), "got %u\n", len );
13620
13621 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
13622 ok( r == ERROR_SUCCESS, "got %u\n", r );
13623
13624 sid[0] = 0;
13625 len = sizeof(sid);
13626 r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
13627 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
13628 ok( len == sizeof(sid), "got %u\n", len );
13629 ok( !sid[0], "got %s\n", sid );
13630
13631 sid[0] = 0;
13632 len = sizeof(sid);
13633 r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
13634 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
13635 ok( len == sizeof(sid), "got %u\n", len );
13636 ok( !sid[0], "got %s\n", sid );
13637
13638 sid[0] = 0;
13639 len = 0;
13640 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
13641 ok( r == ERROR_MORE_DATA, "got %u\n", r );
13642 ok( len, "length unchanged\n" );
13643 ok( !sid[0], "got %s\n", sid );
13644
13645 guid[0] = 0;
13646 context = 0xdeadbeef;
13647 sid[0] = 0;
13648 len = sizeof(sid);
13649 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13650 ok( r == ERROR_SUCCESS, "got %u\n", r );
13651 ok( guid[0], "empty guid\n" );
13652 ok( context != 0xdeadbeef, "context unchanged\n" );
13653 ok( !len, "got %u\n", len );
13654 ok( !sid[0], "got %s\n", sid );
13655
13656 guid[0] = 0;
13657 context = 0xdeadbeef;
13658 sid[0] = 0;
13659 len = sizeof(sid);
13660 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13661 ok( r == ERROR_SUCCESS, "got %u\n", r );
13662 ok( guid[0], "empty guid\n" );
13663 ok( context != 0xdeadbeef, "context unchanged\n" );
13664 ok( !len, "got %u\n", len );
13665 ok( !sid[0], "got %s\n", sid );
13666
13667 guid[0] = 0;
13668 context = 0xdeadbeef;
13669 sid[0] = 0;
13670 len = sizeof(sid);
13671 r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13672 if (r == ERROR_ACCESS_DENIED)
13673 {
13674 skip( "insufficient rights\n" );
13675 goto done;
13676 }
13677 ok( r == ERROR_SUCCESS, "got %u\n", r );
13678 ok( guid[0], "empty guid\n" );
13679 ok( context != 0xdeadbeef, "context unchanged\n" );
13680 ok( !len, "got %u\n", len );
13681 ok( !sid[0], "got %s\n", sid );
13682
13683 index = 0;
13684 guid[0] = 0;
13685 context = 0xdeadbeef;
13686 sid[0] = 0;
13687 len = sizeof(sid);
13688 while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13689 {
13690 if (!strcmp( product1, guid ))
13691 {
13692 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13693 ok( !sid[0], "got \"%s\"\n", sid );
13694 ok( !len, "unexpected length %u\n", len );
13695 }
13696 if (!strcmp( product2, guid ))
13697 {
13698 ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
13699 ok( sid[0], "empty sid\n" );
13700 ok( len == strlen(sid), "unexpected length %u\n", len );
13701 }
13702 if (!strcmp( product3, guid ))
13703 {
13704 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13705 ok( sid[0], "empty sid\n" );
13706 ok( len == strlen(sid), "unexpected length %u\n", len );
13707 }
13708 index++;
13709 guid[0] = 0;
13710 context = 0xdeadbeef;
13711 sid[0] = 0;
13712 len = sizeof(sid);
13713 }
13714
13715 done:
13716 delete_key( key1, "", access );
13717 delete_key( key2, "", access );
13718 delete_key( key3, "", access );
13719 RegCloseKey( key1 );
13720 RegCloseKey( key2 );
13721 RegCloseKey( key3 );
13722 LocalFree( usersid );
13723 }
13724
13725 static void test_MsiEnumComponents(void)
13726 {
13727 UINT r;
13728 BOOL found1, found2;
13729 DWORD index;
13730 char comp1[39], comp2[39], guid[39];
13731 char comp_squashed1[33], comp_squashed2[33];
13732 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13733 REGSAM access = KEY_ALL_ACCESS;
13734 char *usersid = get_user_sid();
13735 HKEY key1 = NULL, key2 = NULL;
13736
13737 create_test_guid( comp1, comp_squashed1 );
13738 create_test_guid( comp2, comp_squashed2 );
13739
13740 if (is_wow64) access |= KEY_WOW64_64KEY;
13741
13742 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13743 strcat( keypath1, "S-1-5-18\\Components\\" );
13744 strcat( keypath1, comp_squashed1 );
13745
13746 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13747 if (r == ERROR_ACCESS_DENIED)
13748 {
13749 skip( "insufficient rights\n" );
13750 goto done;
13751 }
13752 ok( r == ERROR_SUCCESS, "got %u\n", r );
13753
13754 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13755 strcat( keypath2, usersid );
13756 strcat( keypath2, "\\Components\\" );
13757 strcat( keypath2, comp_squashed2 );
13758
13759 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13760 if (r == ERROR_ACCESS_DENIED)
13761 {
13762 skip( "insufficient rights\n" );
13763 goto done;
13764 }
13765
13766 r = MsiEnumComponentsA( 0, NULL );
13767 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13768
13769 index = 0;
13770 guid[0] = 0;
13771 found1 = found2 = FALSE;
13772 while (!MsiEnumComponentsA( index, guid ))
13773 {
13774 if (!strcmp( guid, comp1 )) found1 = TRUE;
13775 if (!strcmp( guid, comp2 )) found2 = TRUE;
13776 ok( guid[0], "empty guid\n" );
13777 guid[0] = 0;
13778 index++;
13779 }
13780 ok( found1, "comp1 not found\n" );
13781 ok( found2, "comp2 not found\n" );
13782
13783 done:
13784 delete_key( key1, "", access );
13785 delete_key( key2, "", access );
13786 RegCloseKey( key1 );
13787 RegCloseKey( key2 );
13788 LocalFree( usersid );
13789 }
13790
13791 static void test_MsiEnumComponentsEx(void)
13792 {
13793 UINT r;
13794 BOOL found1, found2;
13795 DWORD len, index;
13796 MSIINSTALLCONTEXT context;
13797 char comp1[39], comp2[39], guid[39], sid[128];
13798 char comp_squashed1[33], comp_squashed2[33];
13799 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13800 HKEY key1 = NULL, key2 = NULL;
13801 REGSAM access = KEY_ALL_ACCESS;
13802 char *usersid = get_user_sid();
13803
13804 if (!pMsiEnumComponentsExA)
13805 {
13806 win_skip( "MsiEnumComponentsExA not implemented\n" );
13807 return;
13808 }
13809 create_test_guid( comp1, comp_squashed1 );
13810 create_test_guid( comp2, comp_squashed2 );
13811
13812 if (is_wow64) access |= KEY_WOW64_64KEY;
13813
13814 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13815 strcat( keypath1, "S-1-5-18\\Components\\" );
13816 strcat( keypath1, comp_squashed1 );
13817
13818 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13819 if (r == ERROR_ACCESS_DENIED)
13820 {
13821 skip( "insufficient rights\n" );
13822 goto done;
13823 }
13824 ok( r == ERROR_SUCCESS, "got %u\n", r );
13825
13826 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13827 strcat( keypath2, usersid );
13828 strcat( keypath2, "\\Components\\" );
13829 strcat( keypath2, comp_squashed2 );
13830
13831 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13832 if (r == ERROR_ACCESS_DENIED)
13833 {
13834 skip( "insufficient rights\n" );
13835 goto done;
13836 }
13837 ok( r == ERROR_SUCCESS, "got %u\n", r );
13838 r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
13839 sizeof("c:\\doesnotexist"));
13840 ok( r == ERROR_SUCCESS, "got %u\n", r );
13841
13842 index = 0;
13843 guid[0] = 0;
13844 context = 0xdeadbeef;
13845 sid[0] = 0;
13846 len = sizeof(sid);
13847 found1 = found2 = FALSE;
13848 while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13849 {
13850 if (!strcmp( comp1, guid ))
13851 {
13852 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13853 ok( !sid[0], "got \"%s\"\n", sid );
13854 ok( !len, "unexpected length %u\n", len );
13855 found1 = TRUE;
13856 }
13857 if (!strcmp( comp2, guid ))
13858 {
13859 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13860 ok( sid[0], "empty sid\n" );
13861 ok( len == strlen(sid), "unexpected length %u\n", len );
13862 found2 = TRUE;
13863 }
13864 index++;
13865 guid[0] = 0;
13866 context = 0xdeadbeef;
13867 sid[0] = 0;
13868 len = sizeof(sid);
13869 }
13870 ok( found1, "comp1 not found\n" );
13871 ok( found2, "comp2 not found\n" );
13872
13873 r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
13874 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13875
13876 r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
13877 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13878
13879 done:
13880 RegDeleteValueA( key2, comp_squashed2 );
13881 delete_key( key1, "", access );
13882 delete_key( key2, "", access );
13883 RegCloseKey( key1 );
13884 RegCloseKey( key2 );
13885 LocalFree( usersid );
13886 }
13887
13888 static void test_MsiConfigureProductEx(void)
13889 {
13890 UINT r;
13891 LONG res;
13892 DWORD type, size;
13893 HKEY props, source;
13894 CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
13895 REGSAM access = KEY_ALL_ACCESS;
13896
13897 if (is_process_limited())
13898 {
13899 skip("process is limited\n");
13900 return;
13901 }
13902
13903 CreateDirectoryA("msitest", NULL);
13904 create_file("msitest\\hydrogen", "hydrogen", 500);
13905 create_file("msitest\\helium", "helium", 500);
13906 create_file("msitest\\lithium", "lithium", 500);
13907
13908 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13909
13910 if (is_wow64)
13911 access |= KEY_WOW64_64KEY;
13912
13913 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13914
13915 /* NULL szProduct */
13916 r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
13917 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13918 ok(r == ERROR_INVALID_PARAMETER,
13919 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13920
13921 /* empty szProduct */
13922 r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
13923 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13924 ok(r == ERROR_INVALID_PARAMETER,
13925 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13926
13927 /* garbage szProduct */
13928 r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
13929 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13930 ok(r == ERROR_INVALID_PARAMETER,
13931 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13932
13933 /* guid without brackets */
13934 r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
13935 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13936 "PROPVAR=42");
13937 ok(r == ERROR_INVALID_PARAMETER,
13938 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13939
13940 /* guid with brackets */
13941 r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
13942 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13943 "PROPVAR=42");
13944 ok(r == ERROR_UNKNOWN_PRODUCT,
13945 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13946
13947 /* same length as guid, but random */
13948 r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
13949 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13950 "PROPVAR=42");
13951 ok(r == ERROR_UNKNOWN_PRODUCT,
13952 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13953
13954 /* product not installed yet */
13955 r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
13956 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13957 "PROPVAR=42");
13958 ok(r == ERROR_UNKNOWN_PRODUCT,
13959 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13960
13961 /* install the product, per-user unmanaged */
13962 r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
13963 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13964 {
13965 skip("Not enough rights to perform tests\n");
13966 goto error;
13967 }
13968 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13969 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13970 ok(pf_exists("msitest\\helium"), "File not installed\n");
13971 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13972 ok(pf_exists("msitest"), "File not installed\n");
13973
13974 /* product is installed per-user managed, remove it */
13975 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13976 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13977 "PROPVAR=42");
13978 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13979 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13980 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13981 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13982 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13983
13984 /* product has been removed */
13985 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13986 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13987 "PROPVAR=42");
13988 ok(r == ERROR_UNKNOWN_PRODUCT,
13989 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13990
13991 /* install the product, machine */
13992 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13994 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13995 ok(pf_exists("msitest\\helium"), "File not installed\n");
13996 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13997 ok(pf_exists("msitest"), "File not installed\n");
13998
13999 /* product is installed machine, remove it */
14000 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
14001 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
14002 "PROPVAR=42");
14003 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
14004 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
14005 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
14006 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
14007 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
14008
14009 /* product has been removed */
14010 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
14011 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
14012 "PROPVAR=42");
14013 ok(r == ERROR_UNKNOWN_PRODUCT,
14014 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14015
14016 /* install the product, machine */
14017 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
14018 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14019 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
14020 ok(pf_exists("msitest\\helium"), "File not installed\n");
14021 ok(pf_exists("msitest\\lithium"), "File not installed\n");
14022 ok(pf_exists("msitest"), "File not installed\n");
14023
14024 DeleteFileA(msifile);
14025
14026 /* msifile is removed */
14027 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
14028 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
14029 "PROPVAR=42");
14030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
14031 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
14032 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
14033 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
14034 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
14035
14036 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
14037
14038 /* install the product, machine */
14039 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
14040 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14041 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
14042 ok(pf_exists("msitest\\helium"), "File not installed\n");
14043 ok(pf_exists("msitest\\lithium"), "File not installed\n");
14044 ok(pf_exists("msitest"), "File not installed\n");
14045
14046 DeleteFileA(msifile);
14047
14048 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
14049 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
14050 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
14051
14052 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
14053 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14054
14055 type = REG_SZ;
14056 size = MAX_PATH;
14057 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
14058 (LPBYTE)localpackage, &size);
14059 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14060
14061 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
14062 (const BYTE *)"C:\\idontexist.msi", 18);
14063 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14064
14065 /* LocalPackage is used to find the cached msi package */
14066 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
14067 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
14068 "PROPVAR=42");
14069 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
14070 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
14071 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
14072 ok(pf_exists("msitest\\helium"), "File not installed\n");
14073 ok(pf_exists("msitest\\lithium"), "File not installed\n");
14074 ok(pf_exists("msitest"), "File not installed\n");
14075
14076 RegCloseKey(props);
14077 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
14078
14079 /* LastUsedSource can be used as a last resort */
14080 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
14081 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
14082 "PROPVAR=42");
14083 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
14084 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
14085 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
14086 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
14087 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
14088 DeleteFileA( localpackage );
14089
14090 /* install the product, machine */
14091 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
14092 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14093 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
14094 ok(pf_exists("msitest\\helium"), "File not installed\n");
14095 ok(pf_exists("msitest\\lithium"), "File not installed\n");
14096 ok(pf_exists("msitest"), "File not installed\n");
14097
14098 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
14099 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
14100 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
14101
14102 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
14103 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14104
14105 type = REG_SZ;
14106 size = MAX_PATH;
14107 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
14108 (LPBYTE)localpackage, &size);
14109 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14110
14111 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
14112 (const BYTE *)"C:\\idontexist.msi", 18);
14113 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14114
14115 lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
14116 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\SourceList");
14117
14118 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source);
14119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14120
14121 type = REG_SZ;
14122 size = MAX_PATH;
14123 res = RegQueryValueExA(source, "PackageName", NULL, &type,
14124 (LPBYTE)packagename, &size);
14125 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14126
14127 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
14128 (const BYTE *)"idontexist.msi", 15);
14129 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14130
14131 /* SourceList is altered */
14132 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
14133 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
14134 "PROPVAR=42");
14135 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
14136 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
14137 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
14138 ok(pf_exists("msitest\\helium"), "File not installed\n");
14139 ok(pf_exists("msitest\\lithium"), "File not installed\n");
14140 ok(pf_exists("msitest"), "File not installed\n");
14141
14142 /* restore PackageName */
14143 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
14144 (const BYTE *)packagename, lstrlenA(packagename) + 1);
14145 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14146
14147 /* restore LocalPackage */
14148 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
14149 (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
14150 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
14151
14152 /* finally remove the product */
14153 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
14154 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
14155 "PROPVAR=42");
14156 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
14157 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
14158 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
14159 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
14160 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
14161
14162 RegCloseKey(source);
14163 RegCloseKey(props);
14164
14165 error:
14166 DeleteFileA("msitest\\hydrogen");
14167 DeleteFileA("msitest\\helium");
14168 DeleteFileA("msitest\\lithium");
14169 RemoveDirectoryA("msitest");
14170 DeleteFileA(msifile);
14171 }
14172
14173 static void test_MsiSetFeatureAttributes(void)
14174 {
14175 UINT r;
14176 DWORD attrs;
14177 char path[MAX_PATH];
14178 MSIHANDLE package;
14179
14180 if (is_process_limited())
14181 {
14182 skip("process is limited\n");
14183 return;
14184 }
14185 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
14186
14187 strcpy( path, CURR_DIR );
14188 strcat( path, "\\" );
14189 strcat( path, msifile );
14190
14191 r = MsiOpenPackageA( path, &package );
14192 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14193 {
14194 skip("Not enough rights to perform tests\n");
14195 DeleteFileA( msifile );
14196 return;
14197 }
14198 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14199
14200 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
14201 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r);
14202
14203 r = MsiDoActionA( package, "CostInitialize" );
14204 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14205
14206 r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
14207 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
14208
14209 r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
14210 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
14211
14212 r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
14213 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
14214
14215 r = MsiSetFeatureAttributesA( package, "One", 0 );
14216 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14217
14218 attrs = 0xdeadbeef;
14219 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
14220 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14221 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
14222 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
14223
14224 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
14225 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14226
14227 attrs = 0;
14228 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
14229 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14230 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
14231 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
14232
14233 r = MsiDoActionA( package, "FileCost" );
14234 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14235
14236 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE );
14237 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14238
14239 attrs = 0;
14240 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
14241 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14242 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE,
14243 "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs);
14244
14245 r = MsiDoActionA( package, "CostFinalize" );
14246 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14247
14248 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
14249 ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r);
14250
14251 MsiCloseHandle( package );
14252 DeleteFileA( msifile );
14253 }
14254
14255 static void test_MsiGetFeatureInfo(void)
14256 {
14257 UINT r;
14258 MSIHANDLE package;
14259 char title[32], help[32], path[MAX_PATH];
14260 DWORD attrs, title_len, help_len;
14261
14262 if (is_process_limited())
14263 {
14264 skip("process is limited\n");
14265 return;
14266 }
14267 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
14268
14269 strcpy( path, CURR_DIR );
14270 strcat( path, "\\" );
14271 strcat( path, msifile );
14272
14273 r = MsiOpenPackageA( path, &package );
14274 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14275 {
14276 skip("Not enough rights to perform tests\n");
14277 DeleteFileA( msifile );
14278 return;
14279 }
14280 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14281
14282 r = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL );
14283 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
14284
14285 r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
14286 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
14287
14288 r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
14289 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
14290
14291 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
14292 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14293
14294 r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
14295 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
14296
14297 title_len = help_len = 0;
14298 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
14299 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14300 ok(title_len == 3, "expected 3, got %u\n", title_len);
14301 ok(help_len == 3, "expected 3, got %u\n", help_len);
14302
14303 title[0] = help[0] = 0;
14304 title_len = help_len = 0;
14305 r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
14306 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
14307 ok(title_len == 3, "expected 3, got %u\n", title_len);
14308 ok(help_len == 3, "expected 3, got %u\n", help_len);
14309
14310 attrs = 0;
14311 title[0] = help[0] = 0;
14312 title_len = sizeof(title);
14313 help_len = sizeof(help);
14314 r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
14315 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14316 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
14317 ok(title_len == 3, "expected 3, got %u\n", title_len);
14318 ok(help_len == 3, "expected 3, got %u\n", help_len);
14319 ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
14320 ok(!strcmp(help, "One"), "expected \"One\", got \"%s\"\n", help);
14321
14322 attrs = 0;
14323 title[0] = help[0] = 0;
14324 title_len = sizeof(title);
14325 help_len = sizeof(help);
14326 r = MsiGetFeatureInfoA( package, "Two", &attrs, title, &title_len, help, &help_len );
14327 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14328 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
14329 ok(!title_len, "expected 0, got %u\n", title_len);
14330 ok(!help_len, "expected 0, got %u\n", help_len);
14331 ok(!title[0], "expected \"\", got \"%s\"\n", title);
14332 ok(!help[0], "expected \"\", got \"%s\"\n", help);
14333
14334 MsiCloseHandle( package );
14335 DeleteFileA( msifile );
14336 }
14337
14338 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
14339 {
14340 return IDOK;
14341 }
14342
14343 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
14344 {
14345 return IDOK;
14346 }
14347
14348 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
14349 {
14350 return IDOK;
14351 }
14352
14353 static void test_MsiSetInternalUI(void)
14354 {
14355 INSTALLUILEVEL level;
14356
14357 level = MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14358 ok(level == INSTALLUILEVEL_DEFAULT, "expected INSTALLUILEVEL_DEFAULT, got %d\n", level);
14359
14360 level = MsiSetInternalUI(INSTALLUILEVEL_DEFAULT, NULL);
14361 ok(level == INSTALLUILEVEL_FULL, "expected INSTALLUILEVEL_FULL, got %d\n", level);
14362
14363 level = MsiSetInternalUI(INSTALLUILEVEL_NOCHANGE, NULL);
14364 ok(level == INSTALLUILEVEL_DEFAULT, "expected INSTALLUILEVEL_DEFAULT, got %d\n", level);
14365
14366 level = MsiSetInternalUI(0xdeadbeef, NULL);
14367 ok(level == INSTALLUILEVEL_NOCHANGE, "expected INSTALLUILEVEL_NOCHANGE, got %d\n", level);
14368 }
14369
14370 static void test_MsiSetExternalUI(void)
14371 {
14372 INSTALLUI_HANDLERA ret_a;
14373 INSTALLUI_HANDLERW ret_w;
14374 INSTALLUI_HANDLER_RECORD prev;
14375 UINT error;
14376
14377 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
14378 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
14379
14380 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
14381 ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
14382
14383 /* Not present before Installer 3.1 */
14384 if (!pMsiSetExternalUIRecord) {
14385 win_skip("MsiSetExternalUIRecord is not available\n");
14386 return;
14387 }
14388
14389 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
14390 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14391 ok(prev == NULL, "expected NULL, got %p\n", prev);
14392
14393 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
14394 error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
14395 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14396 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
14397
14398 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
14399 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
14400
14401 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
14402 ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
14403
14404 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
14405 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
14406
14407 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
14408 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
14409
14410 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
14411 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
14412 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14413 ok(prev == NULL, "expected NULL, got %p\n", prev);
14414
14415 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
14416 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
14417
14418 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
14419 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
14420
14421 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
14422 error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
14423 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14424 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
14425
14426 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
14427 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14428
14429 error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
14430 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
14431 }
14432
14433 static void test_lastusedsource(void)
14434 {
14435 static const char prodcode[] = "{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}";
14436 char value[MAX_PATH], path[MAX_PATH];
14437 DWORD size;
14438 UINT r;
14439
14440 if (!pMsiSourceListGetInfoA)
14441 {
14442 win_skip("MsiSourceListGetInfoA is not available\n");
14443 return;
14444 }
14445
14446 CreateDirectoryA("msitest", NULL);
14447 create_file("maximus", "maximus", 500);
14448 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
14449 DeleteFileA("maximus");
14450
14451 create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
14452 create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
14453 create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
14454
14455 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14456
14457 /* no cabinet file */
14458
14459 size = MAX_PATH;
14460 lstrcpyA(value, "aaa");
14461 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14462 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14463 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14464 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14465
14466 r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
14467 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14468 {
14469 skip("Not enough rights to perform tests\n");
14470 goto error;
14471 }
14472 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14473
14474 lstrcpyA(path, CURR_DIR);
14475 lstrcatA(path, "\\");
14476
14477 size = MAX_PATH;
14478 lstrcpyA(value, "aaa");
14479 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14480 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14481 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14482 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14483 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
14484
14485 r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
14486 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14487
14488 /* separate cabinet file */
14489
14490 size = MAX_PATH;
14491 lstrcpyA(value, "aaa");
14492 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14493 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14494 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14495 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14496
14497 r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
14498 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14499
14500 lstrcpyA(path, CURR_DIR);
14501 lstrcatA(path, "\\");
14502
14503 size = MAX_PATH;
14504 lstrcpyA(value, "aaa");
14505 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14506 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14507 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14508 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14509 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
14510
14511 r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
14512 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14513
14514 size = MAX_PATH;
14515 lstrcpyA(value, "aaa");
14516 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14517 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14518 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14519 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14520
14521 /* embedded cabinet stream */
14522
14523 add_cabinet_storage("msifile2.msi", "test1.cab");
14524
14525 r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
14526 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14527
14528 size = MAX_PATH;
14529 lstrcpyA(value, "aaa");
14530 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14531 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14532 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14533 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14534 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
14535
14536 r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
14537 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14538
14539 size = MAX_PATH;
14540 lstrcpyA(value, "aaa");
14541 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14542 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
14543 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14544 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14545
14546 error:
14547 delete_cab_files();
14548 DeleteFileA("msitest\\maximus");
14549 RemoveDirectoryA("msitest");
14550 DeleteFileA("msifile0.msi");
14551 DeleteFileA("msifile1.msi");
14552 DeleteFileA("msifile2.msi");
14553 }
14554
14555 static void test_setpropertyfolder(void)
14556 {
14557 UINT r;
14558 CHAR path[MAX_PATH];
14559 DWORD attr;
14560
14561 if (is_process_limited())
14562 {
14563 skip("process is limited\n");
14564 return;
14565 }
14566
14567 lstrcpyA(path, PROG_FILES_DIR);
14568 lstrcatA(path, "\\msitest\\added");
14569
14570 CreateDirectoryA("msitest", NULL);
14571 create_file("msitest\\maximus", "msitest\\maximus", 500);
14572
14573 create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
14574
14575 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14576
14577 r = MsiInstallProductA(msifile, NULL);
14578 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14579 {
14580 skip("Not enough rights to perform tests\n");
14581 goto error;
14582 }
14583 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14584 attr = GetFileAttributesA(path);
14585 if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
14586 {
14587 ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
14588 ok(delete_pf("msitest\\added", FALSE), "Directory not created\n");
14589 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14590 }
14591 else
14592 {
14593 trace("changing folder property not supported\n");
14594 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14595 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14596 }
14597
14598 error:
14599 DeleteFileA(msifile);
14600 DeleteFileA("msitest\\maximus");
14601 RemoveDirectoryA("msitest");
14602 }
14603
14604 static void test_sourcedir_props(void)
14605 {
14606 UINT r;
14607
14608 if (is_process_limited())
14609 {
14610 skip("process is limited\n");
14611 return;
14612 }
14613
14614 create_test_files();
14615 create_file("msitest\\sourcedir.txt", "msitest\\sourcedir.txt", 1000);
14616 create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
14617
14618 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14619
14620 /* full UI, no ResolveSource action */
14621 r = MsiInstallProductA(msifile, NULL);
14622 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14623
14624 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14625 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14626
14627 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14628 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14629
14630 /* full UI, ResolveSource action */
14631 r = MsiInstallProductA(msifile, "ResolveSource=1");
14632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14633
14634 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14636
14637 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14638 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14639
14640 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14641
14642 /* no UI, no ResolveSource action */
14643 r = MsiInstallProductA(msifile, NULL);
14644 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14645
14646 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14647 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14648
14649 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14650 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14651
14652 /* no UI, ResolveSource action */
14653 r = MsiInstallProductA(msifile, "ResolveSource=1");
14654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14655
14656 r = MsiInstallProductA(msifile, "REMOVE=ALL");
14657 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14658
14659 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
14660 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
14661
14662 DeleteFileA("msitest\\sourcedir.txt");
14663 delete_test_files();
14664 DeleteFileA(msifile);
14665 }
14666
14667 static void test_concurrentinstall(void)
14668 {
14669 UINT r;
14670 CHAR path[MAX_PATH];
14671
14672 if (is_process_limited())
14673 {
14674 skip("process is limited\n");
14675 return;
14676 }
14677
14678 CreateDirectoryA("msitest", NULL);
14679 CreateDirectoryA("msitest\\msitest", NULL);
14680 create_file("msitest\\maximus", "msitest\\maximus", 500);
14681 create_file("msitest\\msitest\\augustus", "msitest\\msitest\\augustus", 500);
14682
14683 create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
14684
14685 lstrcpyA(path, CURR_DIR);
14686 lstrcatA(path, "\\msitest\\concurrent.msi");
14687 create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
14688
14689 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14690
14691 r = MsiInstallProductA(msifile, NULL);
14692 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14693 {
14694 skip("Not enough rights to perform tests\n");
14695 goto error;
14696 }
14697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14698 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
14699 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14700 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14701
14702 r = MsiConfigureProductA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", INSTALLLEVEL_DEFAULT,
14703 INSTALLSTATE_ABSENT);
14704 ok(r == ERROR_SUCCESS, "got %u\n", r);
14705
14706 r = MsiConfigureProductA("{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}", INSTALLLEVEL_DEFAULT,
14707 INSTALLSTATE_ABSENT);
14708 ok(r == ERROR_SUCCESS, "got %u\n", r);
14709
14710 error:
14711 DeleteFileA(path);
14712 DeleteFileA(msifile);
14713 DeleteFileA("msitest\\msitest\\augustus");
14714 DeleteFileA("msitest\\maximus");
14715 RemoveDirectoryA("msitest\\msitest");
14716 RemoveDirectoryA("msitest");
14717 }
14718
14719 static void test_command_line_parsing(void)
14720 {
14721 UINT r;
14722 const char *cmd;
14723
14724 if (is_process_limited())
14725 {
14726 skip("process is limited\n");
14727 return;
14728 }
14729
14730 create_test_files();
14731 create_database(msifile, cl_tables, sizeof(cl_tables)/sizeof(msi_table));
14732
14733 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14734
14735 cmd = " ";
14736 r = MsiInstallProductA(msifile, cmd);
14737 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14738
14739 cmd = "=";
14740 r = MsiInstallProductA(msifile, cmd);
14741 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14742
14743 cmd = "==";
14744 r = MsiInstallProductA(msifile, cmd);
14745 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14746
14747 cmd = "one";
14748 r = MsiInstallProductA(msifile, cmd);
14749 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14750
14751 cmd = "=one";
14752 r = MsiInstallProductA(msifile, cmd);
14753 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14754
14755 cmd = "P=";
14756 r = MsiInstallProductA(msifile, cmd);
14757 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14758
14759 cmd = " P=";
14760 r = MsiInstallProductA(msifile, cmd);
14761 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14762
14763 cmd = "P= ";
14764 r = MsiInstallProductA(msifile, cmd);
14765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14766
14767 cmd = "P=\"";
14768 r = MsiInstallProductA(msifile, cmd);
14769 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14770
14771 cmd = "P=\"\"";
14772 r = MsiInstallProductA(msifile, cmd);
14773 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14774
14775 cmd = "P=\"\"\"";
14776 r = MsiInstallProductA(msifile, cmd);
14777 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14778
14779 cmd = "P=\"\"\"\"";
14780 r = MsiInstallProductA(msifile, cmd);
14781 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14782
14783 cmd = "P=\" ";
14784 r = MsiInstallProductA(msifile, cmd);
14785 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14786
14787 cmd = "P= \"";
14788 r = MsiInstallProductA(msifile, cmd);
14789 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14790
14791 cmd = "P= \"\" ";
14792 r = MsiInstallProductA(msifile, cmd);
14793 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14794
14795 cmd = "P=\" \"";
14796 r = MsiInstallProductA(msifile, cmd);
14797 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14798
14799 cmd = "P=one";
14800 r = MsiInstallProductA(msifile, cmd);
14801 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14802
14803 cmd = "P= one";
14804 r = MsiInstallProductA(msifile, cmd);
14805 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14806
14807 cmd = "P=\"one";
14808 r = MsiInstallProductA(msifile, cmd);
14809 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14810
14811 cmd = "P=one\"";
14812 r = MsiInstallProductA(msifile, cmd);
14813 todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14814
14815 cmd = "P=\"one\"";
14816 r = MsiInstallProductA(msifile, cmd);
14817 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14818
14819 cmd = "P= \"one\" ";
14820 r = MsiInstallProductA(msifile, cmd);
14821 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14822
14823 cmd = "P=\"one\"\"";
14824 r = MsiInstallProductA(msifile, cmd);
14825 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14826
14827 cmd = "P=\"\"one\"";
14828 r = MsiInstallProductA(msifile, cmd);
14829 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14830
14831 cmd = "P=\"\"one\"\"";
14832 r = MsiInstallProductA(msifile, cmd);
14833 todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14834
14835 cmd = "P=\"one two\"";
14836 r = MsiInstallProductA(msifile, cmd);
14837 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14838
14839 cmd = "P=\"\"\"one\"\" two\"";
14840 r = MsiInstallProductA(msifile, cmd);
14841 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14842
14843 cmd = "P=\"\"\"one\"\" two\" Q=three";
14844 r = MsiInstallProductA(msifile, cmd);
14845 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14846
14847 cmd = "P=\"\" Q=\"two\"";
14848 r = MsiInstallProductA(msifile, cmd);
14849 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14850
14851 cmd = "P=\"one\" Q=\"two\"";
14852 r = MsiInstallProductA(msifile, cmd);
14853 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14854
14855 cmd = "P=\"one=two\"";
14856 r = MsiInstallProductA(msifile, cmd);
14857 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14858
14859 cmd = "Q=\"\" P=\"one\"";
14860 r = MsiInstallProductA(msifile, cmd);
14861 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14862
14863 cmd = "P=\"\"\"one\"\"\" Q=\"two\"";
14864 r = MsiInstallProductA(msifile, cmd);
14865 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14866
14867 cmd = "P=\"one \"\"two\"\"\" Q=\"three\"";
14868 r = MsiInstallProductA(msifile, cmd);
14869 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14870
14871 cmd = "P=\"\"\"one\"\" two\" Q=\"three\"";
14872 r = MsiInstallProductA(msifile, cmd);
14873 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14874
14875 DeleteFileA(msifile);
14876 delete_test_files();
14877 }
14878
14879 START_TEST(msi)
14880 {
14881 DWORD len;
14882 char temp_path[MAX_PATH], prev_path[MAX_PATH];
14883
14884 #ifdef __REACTOS__
14885 if (!winetest_interactive &&
14886 !strcmp(winetest_platform, "windows"))
14887 {
14888 skip("ROSTESTS-180: Skipping msi_winetest:msi because it hangs on WHS-Testbot. Set winetest_interactive to run it anyway.\n");
14889 return;
14890 }
14891 #endif
14892
14893 init_functionpointers();
14894
14895 if (pIsWow64Process)
14896 pIsWow64Process(GetCurrentProcess(), &is_wow64);
14897
14898 GetCurrentDirectoryA(MAX_PATH, prev_path);
14899 GetTempPathA(MAX_PATH, temp_path);
14900 SetCurrentDirectoryA(temp_path);
14901
14902 lstrcpyA(CURR_DIR, temp_path);
14903 len = lstrlenA(CURR_DIR);
14904
14905 if(len && (CURR_DIR[len - 1] == '\\'))
14906 CURR_DIR[len - 1] = 0;
14907
14908 ok(get_system_dirs(), "failed to retrieve system dirs\n");
14909
14910 test_usefeature();
14911 test_null();
14912 test_getcomponentpath();
14913 test_MsiGetFileHash();
14914 test_MsiSetInternalUI();
14915
14916 if (!pConvertSidToStringSidA)
14917 win_skip("ConvertSidToStringSidA not implemented\n");
14918 else
14919 {
14920 /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
14921 test_MsiQueryProductState();
14922 test_MsiQueryFeatureState();
14923 test_MsiQueryComponentState();
14924 test_MsiGetComponentPath();
14925 test_MsiGetComponentPathEx();
14926 test_MsiProvideComponent();
14927 test_MsiGetProductCode();
14928 test_MsiEnumClients();
14929 test_MsiGetProductInfo();
14930 test_MsiGetProductInfoEx();
14931 test_MsiGetUserInfo();
14932 test_MsiOpenProduct();
14933 test_MsiEnumPatchesEx();
14934 test_MsiEnumPatches();
14935 test_MsiGetPatchInfoEx();
14936 test_MsiGetPatchInfo();
14937 test_MsiEnumProducts();
14938 test_MsiEnumProductsEx();
14939 test_MsiEnumComponents();
14940 test_MsiEnumComponentsEx();
14941 }
14942 test_MsiGetFileVersion();
14943 test_MsiGetFileSignatureInformation();
14944 test_MsiConfigureProductEx();
14945 test_MsiSetFeatureAttributes();
14946 test_MsiGetFeatureInfo();
14947 test_MsiSetExternalUI();
14948 test_lastusedsource();
14949 test_setpropertyfolder();
14950 test_sourcedir_props();
14951 if (pMsiGetComponentPathExA)
14952 test_concurrentinstall();
14953 test_command_line_parsing();
14954 test_MsiProvideQualifiedComponentEx();
14955
14956 SetCurrentDirectoryA(prev_path);
14957 }