[MSI_WINETEST]
[reactos.git] / rostests / winetests / msi / msi.c
1 /*
2 * tests for Microsoft Installer functionality
3 *
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define _WIN32_MSI 300
22 #define COBJMACROS
23
24 #include <stdio.h>
25 #include <windows.h>
26 #include <msi.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <sddl.h>
30 #include <fci.h>
31
32 #include "wine/test.h"
33
34 static BOOL is_wow64;
35 static const char msifile[] = "winetest.msi";
36 static char CURR_DIR[MAX_PATH];
37 static char PROG_FILES_DIR[MAX_PATH];
38 static char PROG_FILES_DIR_NATIVE[MAX_PATH];
39 static char COMMON_FILES_DIR[MAX_PATH];
40 static char WINDOWS_DIR[MAX_PATH];
41
42 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
43 static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
44 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
45 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
46
47 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
48 (LPCSTR, LPCSTR, LPSTR, DWORD*);
49 static UINT (WINAPI *pMsiGetFileHashA)
50 (LPCSTR, DWORD, PMSIFILEHASHINFO);
51 static UINT (WINAPI *pMsiGetProductInfoExA)
52 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
53 static UINT (WINAPI *pMsiOpenPackageExA)
54 (LPCSTR, DWORD, MSIHANDLE*);
55 static UINT (WINAPI *pMsiOpenPackageExW)
56 (LPCWSTR, DWORD, MSIHANDLE*);
57 static UINT (WINAPI *pMsiEnumPatchesExA)
58 (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
59 MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
60 static UINT (WINAPI *pMsiQueryComponentStateA)
61 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
62 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
63 (LPCSTR, LPCSTR ,DWORD, DWORD);
64 static UINT (WINAPI *pMsiGetPatchInfoExA)
65 (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
66 static UINT (WINAPI *pMsiEnumProductsExA)
67 (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
68 static UINT (WINAPI *pMsiEnumComponentsExA)
69 (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
70 static UINT (WINAPI *pMsiSetExternalUIRecord)
71 (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD);
72 static UINT (WINAPI *pMsiSourceListGetInfoA)
73 (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
74
75 static void init_functionpointers(void)
76 {
77 HMODULE hmsi = GetModuleHandleA("msi.dll");
78 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
79 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
80
81 #define GET_PROC(dll, func) \
82 p ## func = (void *)GetProcAddress(dll, #func); \
83 if(!p ## func) \
84 trace("GetProcAddress(%s) failed\n", #func);
85
86 GET_PROC(hmsi, MsiGetComponentPathA)
87 GET_PROC(hmsi, MsiGetFileHashA)
88 GET_PROC(hmsi, MsiGetProductInfoExA)
89 GET_PROC(hmsi, MsiOpenPackageExA)
90 GET_PROC(hmsi, MsiOpenPackageExW)
91 GET_PROC(hmsi, MsiEnumPatchesExA)
92 GET_PROC(hmsi, MsiQueryComponentStateA)
93 GET_PROC(hmsi, MsiSetExternalUIRecord)
94 GET_PROC(hmsi, MsiUseFeatureExA)
95 GET_PROC(hmsi, MsiGetPatchInfoExA)
96 GET_PROC(hmsi, MsiEnumProductsExA)
97 GET_PROC(hmsi, MsiEnumComponentsExA)
98 GET_PROC(hmsi, MsiSourceListGetInfoA)
99
100 GET_PROC(hadvapi32, ConvertSidToStringSidA)
101 GET_PROC(hadvapi32, OpenProcessToken);
102 GET_PROC(hadvapi32, RegDeleteKeyExA)
103 GET_PROC(hkernel32, IsWow64Process)
104
105 #undef GET_PROC
106 }
107
108 static BOOL get_system_dirs(void)
109 {
110 HKEY hkey;
111 DWORD type, size;
112
113 if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
114 return FALSE;
115
116 size = MAX_PATH;
117 if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
118 RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
119 {
120 RegCloseKey(hkey);
121 return FALSE;
122 }
123 size = MAX_PATH;
124 if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
125 RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
126 {
127 RegCloseKey(hkey);
128 return FALSE;
129 }
130 size = MAX_PATH;
131 if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR_NATIVE, &size))
132 {
133 RegCloseKey(hkey);
134 return FALSE;
135 }
136 RegCloseKey(hkey);
137 if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH)) return FALSE;
138 return TRUE;
139 }
140
141 static BOOL file_exists(const char *file)
142 {
143 return GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES;
144 }
145
146 static BOOL pf_exists(const char *file)
147 {
148 char path[MAX_PATH];
149
150 lstrcpyA(path, PROG_FILES_DIR);
151 lstrcatA(path, "\\");
152 lstrcatA(path, file);
153 return file_exists(path);
154 }
155
156 static BOOL delete_pf(const char *rel_path, BOOL is_file)
157 {
158 char path[MAX_PATH];
159
160 lstrcpyA(path, PROG_FILES_DIR);
161 lstrcatA(path, "\\");
162 lstrcatA(path, rel_path);
163
164 if (is_file)
165 return DeleteFileA(path);
166 else
167 return RemoveDirectoryA(path);
168 }
169
170 static BOOL is_process_limited(void)
171 {
172 HANDLE token;
173 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
174 DWORD size;
175 BOOL ret;
176
177 if (!pOpenProcessToken) return FALSE;
178 if (!pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) return FALSE;
179 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
180 CloseHandle(token);
181 return (ret && type == TokenElevationTypeLimited);
182 }
183
184 /* cabinet definitions */
185
186 /* make the max size large so there is only one cab file */
187 #define MEDIA_SIZE 0x7FFFFFFF
188 #define FOLDER_THRESHOLD 900000
189
190 /* the FCI callbacks */
191
192 static void * CDECL mem_alloc(ULONG cb)
193 {
194 return HeapAlloc(GetProcessHeap(), 0, cb);
195 }
196
197 static void CDECL mem_free(void *memory)
198 {
199 HeapFree(GetProcessHeap(), 0, memory);
200 }
201
202 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
203 {
204 sprintf(pccab->szCab, pv, pccab->iCab);
205 return TRUE;
206 }
207
208 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
209 {
210 return 0;
211 }
212
213 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
214 BOOL fContinuation, void *pv)
215 {
216 return 0;
217 }
218
219 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
220 {
221 HANDLE handle;
222 DWORD dwAccess = 0;
223 DWORD dwShareMode = 0;
224 DWORD dwCreateDisposition = OPEN_EXISTING;
225
226 dwAccess = GENERIC_READ | GENERIC_WRITE;
227 /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
228 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
229
230 if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
231 dwCreateDisposition = OPEN_EXISTING;
232 else
233 dwCreateDisposition = CREATE_NEW;
234
235 handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
236 dwCreateDisposition, 0, NULL);
237
238 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
239
240 return (INT_PTR)handle;
241 }
242
243 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
244 {
245 HANDLE handle = (HANDLE)hf;
246 DWORD dwRead;
247 BOOL res;
248
249 res = ReadFile(handle, memory, cb, &dwRead, NULL);
250 ok(res, "Failed to ReadFile\n");
251
252 return dwRead;
253 }
254
255 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
256 {
257 HANDLE handle = (HANDLE)hf;
258 DWORD dwWritten;
259 BOOL res;
260
261 res = WriteFile(handle, memory, cb, &dwWritten, NULL);
262 ok(res, "Failed to WriteFile\n");
263
264 return dwWritten;
265 }
266
267 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
268 {
269 HANDLE handle = (HANDLE)hf;
270 ok(CloseHandle(handle), "Failed to CloseHandle\n");
271
272 return 0;
273 }
274
275 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
276 {
277 HANDLE handle = (HANDLE)hf;
278 DWORD ret;
279
280 ret = SetFilePointer(handle, dist, NULL, seektype);
281 ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
282
283 return ret;
284 }
285
286 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
287 {
288 BOOL ret = DeleteFileA(pszFile);
289 ok(ret, "Failed to DeleteFile %s\n", pszFile);
290
291 return 0;
292 }
293
294 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
295 {
296 LPSTR tempname;
297
298 tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
299 GetTempFileNameA(".", "xx", 0, tempname);
300
301 if (tempname && (strlen(tempname) < (unsigned)cbTempName))
302 {
303 lstrcpyA(pszTempName, tempname);
304 HeapFree(GetProcessHeap(), 0, tempname);
305 return TRUE;
306 }
307
308 HeapFree(GetProcessHeap(), 0, tempname);
309
310 return FALSE;
311 }
312
313 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
314 USHORT *pattribs, int *err, void *pv)
315 {
316 BY_HANDLE_FILE_INFORMATION finfo;
317 FILETIME filetime;
318 HANDLE handle;
319 DWORD attrs;
320 BOOL res;
321
322 handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
323 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
324
325 ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
326
327 res = GetFileInformationByHandle(handle, &finfo);
328 ok(res, "Expected GetFileInformationByHandle to succeed\n");
329
330 FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
331 FileTimeToDosDateTime(&filetime, pdate, ptime);
332
333 attrs = GetFileAttributes(pszName);
334 ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
335
336 return (INT_PTR)handle;
337 }
338
339 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
340 {
341 char path[MAX_PATH];
342 char filename[MAX_PATH];
343
344 lstrcpyA(path, CURR_DIR);
345 lstrcatA(path, "\\");
346 lstrcatA(path, file);
347
348 lstrcpyA(filename, file);
349
350 return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
351 progress, get_open_info, compress);
352 }
353
354 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
355 {
356 ZeroMemory(pCabParams, sizeof(CCAB));
357
358 pCabParams->cb = max_size;
359 pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
360 pCabParams->setID = 0xbeef;
361 pCabParams->iCab = 1;
362 lstrcpyA(pCabParams->szCabPath, CURR_DIR);
363 lstrcatA(pCabParams->szCabPath, "\\");
364 lstrcpyA(pCabParams->szCab, name);
365 }
366
367 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
368 {
369 CCAB cabParams;
370 LPCSTR ptr;
371 HFCI hfci;
372 ERF erf;
373 BOOL res;
374
375 set_cab_parameters(&cabParams, name, max_size);
376
377 hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
378 fci_read, fci_write, fci_close, fci_seek, fci_delete,
379 get_temp_file, &cabParams, NULL);
380
381 ok(hfci != NULL, "Failed to create an FCI context\n");
382
383 ptr = files;
384 while (*ptr)
385 {
386 res = add_file(hfci, ptr, tcompTYPE_MSZIP);
387 ok(res, "Failed to add file: %s\n", ptr);
388 ptr += lstrlen(ptr) + 1;
389 }
390
391 res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
392 ok(res, "Failed to flush the cabinet\n");
393
394 res = FCIDestroy(hfci);
395 ok(res, "Failed to destroy the cabinet\n");
396 }
397
398 static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
399 {
400 WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
401 IStorage *stg;
402 IStream *stm;
403 HRESULT hr;
404 HANDLE handle;
405
406 MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
407 hr = StgOpenStorage(dbW, NULL, STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
408 if (FAILED(hr))
409 return FALSE;
410
411 MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
412 hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
413 if (FAILED(hr))
414 {
415 IStorage_Release(stg);
416 return FALSE;
417 }
418
419 handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
420 if (handle != INVALID_HANDLE_VALUE)
421 {
422 DWORD count;
423 char buffer[1024];
424 if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
425 IStream_Write(stm, buffer, count, &count);
426 CloseHandle(handle);
427 }
428
429 IStream_Release(stm);
430 IStorage_Release(stg);
431
432 return TRUE;
433 }
434
435 static void delete_cab_files(void)
436 {
437 SHFILEOPSTRUCT shfl;
438 CHAR path[MAX_PATH+10];
439
440 lstrcpyA(path, CURR_DIR);
441 lstrcatA(path, "\\*.cab");
442 path[strlen(path) + 1] = '\0';
443
444 shfl.hwnd = NULL;
445 shfl.wFunc = FO_DELETE;
446 shfl.pFrom = path;
447 shfl.pTo = NULL;
448 shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT;
449
450 SHFileOperation(&shfl);
451 }
452
453 /* msi database data */
454
455 static const char directory_dat[] =
456 "Directory\tDirectory_Parent\tDefaultDir\n"
457 "s72\tS72\tl255\n"
458 "Directory\tDirectory\n"
459 "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
460 "ProgramFilesFolder\tTARGETDIR\t.\n"
461 "TARGETDIR\t\tSourceDir";
462
463 static const char component_dat[] =
464 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
465 "s72\tS38\ts72\ti2\tS255\tS72\n"
466 "Component\tComponent\n"
467 "One\t{8F5BAEEF-DD92-40AC-9397-BE3CF9F97C81}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n";
468
469 static const char feature_dat[] =
470 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
471 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
472 "Feature\tFeature\n"
473 "One\t\tOne\tOne\t1\t3\tMSITESTDIR\t0\n"
474 "Two\t\t\t\t2\t1\tTARGETDIR\t0\n";
475
476 static const char feature_comp_dat[] =
477 "Feature_\tComponent_\n"
478 "s38\ts72\n"
479 "FeatureComponents\tFeature_\tComponent_\n"
480 "One\tOne\n";
481
482 static const char file_dat[] =
483 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
484 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
485 "File\tFile\n"
486 "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n";
487
488 static const char install_exec_seq_dat[] =
489 "Action\tCondition\tSequence\n"
490 "s72\tS255\tI2\n"
491 "InstallExecuteSequence\tAction\n"
492 "ValidateProductID\t\t700\n"
493 "CostInitialize\t\t800\n"
494 "FileCost\t\t900\n"
495 "CostFinalize\t\t1000\n"
496 "InstallValidate\t\t1400\n"
497 "InstallInitialize\t\t1500\n"
498 "ProcessComponents\t\t1600\n"
499 "UnpublishFeatures\t\t1800\n"
500 "RemoveFiles\t\t3500\n"
501 "InstallFiles\t\t4000\n"
502 "RegisterProduct\t\t6100\n"
503 "PublishFeatures\t\t6300\n"
504 "PublishProduct\t\t6400\n"
505 "InstallFinalize\t\t6600";
506
507 static const char media_dat[] =
508 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
509 "i2\ti4\tL64\tS255\tS32\tS72\n"
510 "Media\tDiskId\n"
511 "1\t1\t\t\tDISK1\t\n";
512
513 static const char property_dat[] =
514 "Property\tValue\n"
515 "s72\tl0\n"
516 "Property\tProperty\n"
517 "INSTALLLEVEL\t3\n"
518 "Manufacturer\tWine\n"
519 "ProductCode\t{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}\n"
520 "ProductName\tMSITEST\n"
521 "ProductVersion\t1.1.1\n"
522 "UpgradeCode\t{9574448F-9B86-4E07-B6F6-8D199DA12127}\n"
523 "MSIFASTINSTALL\t1\n";
524
525 static const char mcp_component_dat[] =
526 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
527 "s72\tS38\ts72\ti2\tS255\tS72\n"
528 "Component\tComponent\n"
529 "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
530 "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
531 "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
532
533 static const char mcp_feature_dat[] =
534 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
535 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
536 "Feature\tFeature\n"
537 "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
538 "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
539 "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
540
541 static const char mcp_feature_comp_dat[] =
542 "Feature_\tComponent_\n"
543 "s38\ts72\n"
544 "FeatureComponents\tFeature_\tComponent_\n"
545 "hydroxyl\thydrogen\n"
546 "heliox\thelium\n"
547 "lithia\tlithium";
548
549 static const char mcp_file_dat[] =
550 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
551 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
552 "File\tFile\n"
553 "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
554 "helium\thelium\thelium\t0\t\t\t8192\t1\n"
555 "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
556
557 static const char lus_component_dat[] =
558 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
559 "s72\tS38\ts72\ti2\tS255\tS72\n"
560 "Component\tComponent\n"
561 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
562
563 static const char lus_feature_dat[] =
564 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
565 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
566 "Feature\tFeature\n"
567 "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
568 "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
569
570 static const char lus_file_dat[] =
571 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
572 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
573 "File\tFile\n"
574 "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
575
576 static const char lus_feature_comp_dat[] =
577 "Feature_\tComponent_\n"
578 "s38\ts72\n"
579 "FeatureComponents\tFeature_\tComponent_\n"
580 "feature\tmaximus\n"
581 "montecristo\tmaximus";
582
583 static const char lus_install_exec_seq_dat[] =
584 "Action\tCondition\tSequence\n"
585 "s72\tS255\tI2\n"
586 "InstallExecuteSequence\tAction\n"
587 "ValidateProductID\t\t700\n"
588 "CostInitialize\t\t800\n"
589 "FileCost\t\t900\n"
590 "CostFinalize\t\t1000\n"
591 "InstallValidate\t\t1400\n"
592 "InstallInitialize\t\t1500\n"
593 "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
594 "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
595 "RemoveFiles\t\t3500\n"
596 "InstallFiles\t\t4000\n"
597 "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
598 "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
599 "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
600 "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
601 "InstallFinalize\t\t6600";
602
603 static const char lus0_media_dat[] =
604 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
605 "i2\ti4\tL64\tS255\tS32\tS72\n"
606 "Media\tDiskId\n"
607 "1\t1\t\t\tDISK1\t\n";
608
609 static const char lus1_media_dat[] =
610 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
611 "i2\ti4\tL64\tS255\tS32\tS72\n"
612 "Media\tDiskId\n"
613 "1\t1\t\ttest1.cab\tDISK1\t\n";
614
615 static const char lus2_media_dat[] =
616 "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
617 "i2\ti4\tL64\tS255\tS32\tS72\n"
618 "Media\tDiskId\n"
619 "1\t1\t\t#test1.cab\tDISK1\t\n";
620
621 static const char spf_custom_action_dat[] =
622 "Action\tType\tSource\tTarget\tISComments\n"
623 "s72\ti2\tS64\tS0\tS255\n"
624 "CustomAction\tAction\n"
625 "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
626
627 static const char spf_install_exec_seq_dat[] =
628 "Action\tCondition\tSequence\n"
629 "s72\tS255\tI2\n"
630 "InstallExecuteSequence\tAction\n"
631 "CostFinalize\t\t1000\n"
632 "CostInitialize\t\t800\n"
633 "FileCost\t\t900\n"
634 "SetFolderProp\t\t950\n"
635 "InstallFiles\t\t4000\n"
636 "InstallServices\t\t5000\n"
637 "InstallFinalize\t\t6600\n"
638 "InstallInitialize\t\t1500\n"
639 "InstallValidate\t\t1400\n"
640 "LaunchConditions\t\t100";
641
642 static const char spf_install_ui_seq_dat[] =
643 "Action\tCondition\tSequence\n"
644 "s72\tS255\tI2\n"
645 "InstallUISequence\tAction\n"
646 "CostInitialize\t\t800\n"
647 "FileCost\t\t900\n"
648 "CostFinalize\t\t1000\n"
649 "ExecuteAction\t\t1100\n";
650
651 static const char sd_file_dat[] =
652 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
653 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
654 "File\tFile\n"
655 "sourcedir.txt\tsourcedir\tsourcedir.txt\t1000\t\t\t8192\t1\n";
656
657 static const char sd_feature_dat[] =
658 "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
659 "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
660 "Feature\tFeature\n"
661 "sourcedir\t\t\tsourcedir feature\t1\t2\tMSITESTDIR\t0\n";
662
663 static const char sd_feature_comp_dat[] =
664 "Feature_\tComponent_\n"
665 "s38\ts72\n"
666 "FeatureComponents\tFeature_\tComponent_\n"
667 "sourcedir\tsourcedir\n";
668
669 static const char sd_component_dat[] =
670 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
671 "s72\tS38\ts72\ti2\tS255\tS72\n"
672 "Component\tComponent\n"
673 "sourcedir\t{DD422F92-3ED8-49B5-A0B7-F266F98357DF}\tMSITESTDIR\t0\t\tsourcedir.txt\n";
674
675 static const char sd_install_ui_seq_dat[] =
676 "Action\tCondition\tSequence\n"
677 "s72\tS255\tI2\n"
678 "InstallUISequence\tAction\n"
679 "TestSourceDirProp1\tnot SourceDir and not SOURCEDIR and not Installed\t99\n"
680 "AppSearch\t\t100\n"
681 "TestSourceDirProp2\tnot SourceDir and not SOURCEDIR and not Installed\t101\n"
682 "LaunchConditions\tnot Installed \t110\n"
683 "TestSourceDirProp3\tnot SourceDir and not SOURCEDIR and not Installed\t111\n"
684 "FindRelatedProducts\t\t120\n"
685 "TestSourceDirProp4\tnot SourceDir and not SOURCEDIR and not Installed\t121\n"
686 "CCPSearch\t\t130\n"
687 "TestSourceDirProp5\tnot SourceDir and not SOURCEDIR and not Installed\t131\n"
688 "RMCCPSearch\t\t140\n"
689 "TestSourceDirProp6\tnot SourceDir and not SOURCEDIR and not Installed\t141\n"
690 "ValidateProductID\t\t150\n"
691 "TestSourceDirProp7\tnot SourceDir and not SOURCEDIR and not Installed\t151\n"
692 "CostInitialize\t\t800\n"
693 "TestSourceDirProp8\tnot SourceDir and not SOURCEDIR and not Installed\t801\n"
694 "FileCost\t\t900\n"
695 "TestSourceDirProp9\tnot SourceDir and not SOURCEDIR and not Installed\t901\n"
696 "IsolateComponents\t\t1000\n"
697 "TestSourceDirProp10\tnot SourceDir and not SOURCEDIR and not Installed\t1001\n"
698 "CostFinalize\t\t1100\n"
699 "TestSourceDirProp11\tnot SourceDir and not SOURCEDIR and not Installed\t1101\n"
700 "MigrateFeatureStates\t\t1200\n"
701 "TestSourceDirProp12\tnot SourceDir and not SOURCEDIR and not Installed\t1201\n"
702 "ExecuteAction\t\t1300\n"
703 "TestSourceDirProp13\tnot SourceDir and not SOURCEDIR and not Installed\t1301\n";
704
705 static const char sd_install_exec_seq_dat[] =
706 "Action\tCondition\tSequence\n"
707 "s72\tS255\tI2\n"
708 "InstallExecuteSequence\tAction\n"
709 "TestSourceDirProp14\tSourceDir and SOURCEDIR and not Installed\t99\n"
710 "LaunchConditions\t\t100\n"
711 "TestSourceDirProp15\tSourceDir and SOURCEDIR and not Installed\t101\n"
712 "ValidateProductID\t\t700\n"
713 "TestSourceDirProp16\tSourceDir and SOURCEDIR and not Installed\t701\n"
714 "CostInitialize\t\t800\n"
715 "TestSourceDirProp17\tSourceDir and SOURCEDIR and not Installed\t801\n"
716 "ResolveSource\tResolveSource and not Installed\t850\n"
717 "TestSourceDirProp18\tResolveSource and not SourceDir and not SOURCEDIR and not Installed\t851\n"
718 "TestSourceDirProp19\tnot ResolveSource and SourceDir and SOURCEDIR and not Installed\t852\n"
719 "FileCost\t\t900\n"
720 "TestSourceDirProp20\tSourceDir and SOURCEDIR and not Installed\t901\n"
721 "IsolateComponents\t\t1000\n"
722 "TestSourceDirProp21\tSourceDir and SOURCEDIR and not Installed\t1001\n"
723 "CostFinalize\t\t1100\n"
724 "TestSourceDirProp22\tSourceDir and SOURCEDIR and not Installed\t1101\n"
725 "MigrateFeatureStates\t\t1200\n"
726 "TestSourceDirProp23\tSourceDir and SOURCEDIR and not Installed\t1201\n"
727 "InstallValidate\t\t1400\n"
728 "TestSourceDirProp24\tSourceDir and SOURCEDIR and not Installed\t1401\n"
729 "InstallInitialize\t\t1500\n"
730 "TestSourceDirProp25\tSourceDir and SOURCEDIR and not Installed\t1501\n"
731 "ProcessComponents\t\t1600\n"
732 "TestSourceDirProp26\tnot SourceDir and not SOURCEDIR and not Installed\t1601\n"
733 "UnpublishFeatures\t\t1800\n"
734 "TestSourceDirProp27\tnot SourceDir and not SOURCEDIR and not Installed\t1801\n"
735 "RemoveFiles\t\t3500\n"
736 "TestSourceDirProp28\tnot SourceDir and not SOURCEDIR and not Installed\t3501\n"
737 "InstallFiles\t\t4000\n"
738 "TestSourceDirProp29\tnot SourceDir and not SOURCEDIR and not Installed\t4001\n"
739 "RegisterUser\t\t6000\n"
740 "TestSourceDirProp30\tnot SourceDir and not SOURCEDIR and not Installed\t6001\n"
741 "RegisterProduct\t\t6100\n"
742 "TestSourceDirProp31\tnot SourceDir and not SOURCEDIR and not Installed\t6101\n"
743 "PublishFeatures\t\t6300\n"
744 "TestSourceDirProp32\tnot SourceDir and not SOURCEDIR and not Installed\t6301\n"
745 "PublishProduct\t\t6400\n"
746 "TestSourceDirProp33\tnot SourceDir and not SOURCEDIR and not Installed\t6401\n"
747 "InstallExecute\t\t6500\n"
748 "TestSourceDirProp34\tnot SourceDir and not SOURCEDIR and not Installed\t6501\n"
749 "InstallFinalize\t\t6600\n"
750 "TestSourceDirProp35\tnot SourceDir and not SOURCEDIR and not Installed\t6601\n";
751
752 static const char sd_custom_action_dat[] =
753 "Action\tType\tSource\tTarget\tISComments\n"
754 "s72\ti2\tS64\tS0\tS255\n"
755 "CustomAction\tAction\n"
756 "TestSourceDirProp1\t19\t\tTest 1 failed\t\n"
757 "TestSourceDirProp2\t19\t\tTest 2 failed\t\n"
758 "TestSourceDirProp3\t19\t\tTest 3 failed\t\n"
759 "TestSourceDirProp4\t19\t\tTest 4 failed\t\n"
760 "TestSourceDirProp5\t19\t\tTest 5 failed\t\n"
761 "TestSourceDirProp6\t19\t\tTest 6 failed\t\n"
762 "TestSourceDirProp7\t19\t\tTest 7 failed\t\n"
763 "TestSourceDirProp8\t19\t\tTest 8 failed\t\n"
764 "TestSourceDirProp9\t19\t\tTest 9 failed\t\n"
765 "TestSourceDirProp10\t19\t\tTest 10 failed\t\n"
766 "TestSourceDirProp11\t19\t\tTest 11 failed\t\n"
767 "TestSourceDirProp12\t19\t\tTest 12 failed\t\n"
768 "TestSourceDirProp13\t19\t\tTest 13 failed\t\n"
769 "TestSourceDirProp14\t19\t\tTest 14 failed\t\n"
770 "TestSourceDirProp15\t19\t\tTest 15 failed\t\n"
771 "TestSourceDirProp16\t19\t\tTest 16 failed\t\n"
772 "TestSourceDirProp17\t19\t\tTest 17 failed\t\n"
773 "TestSourceDirProp18\t19\t\tTest 18 failed\t\n"
774 "TestSourceDirProp19\t19\t\tTest 19 failed\t\n"
775 "TestSourceDirProp20\t19\t\tTest 20 failed\t\n"
776 "TestSourceDirProp21\t19\t\tTest 21 failed\t\n"
777 "TestSourceDirProp22\t19\t\tTest 22 failed\t\n"
778 "TestSourceDirProp23\t19\t\tTest 23 failed\t\n"
779 "TestSourceDirProp24\t19\t\tTest 24 failed\t\n"
780 "TestSourceDirProp25\t19\t\tTest 25 failed\t\n"
781 "TestSourceDirProp26\t19\t\tTest 26 failed\t\n"
782 "TestSourceDirProp27\t19\t\tTest 27 failed\t\n"
783 "TestSourceDirProp28\t19\t\tTest 28 failed\t\n"
784 "TestSourceDirProp29\t19\t\tTest 29 failed\t\n"
785 "TestSourceDirProp30\t19\t\tTest 30 failed\t\n"
786 "TestSourceDirProp31\t19\t\tTest 31 failed\t\n"
787 "TestSourceDirProp32\t19\t\tTest 32 failed\t\n"
788 "TestSourceDirProp33\t19\t\tTest 33 failed\t\n"
789 "TestSourceDirProp34\t19\t\tTest 34 failed\t\n"
790 "TestSourceDirProp35\t19\t\tTest 35 failed\t\n";
791
792 static const char ci_install_exec_seq_dat[] =
793 "Action\tCondition\tSequence\n"
794 "s72\tS255\tI2\n"
795 "InstallExecuteSequence\tAction\n"
796 "CostFinalize\t\t1000\n"
797 "CostInitialize\t\t800\n"
798 "FileCost\t\t900\n"
799 "InstallFiles\t\t4000\n"
800 "InstallServices\t\t5000\n"
801 "InstallFinalize\t\t6600\n"
802 "InstallInitialize\t\t1500\n"
803 "RunInstall\t\t1600\n"
804 "InstallValidate\t\t1400\n"
805 "LaunchConditions\t\t100";
806
807 static const char ci_custom_action_dat[] =
808 "Action\tType\tSource\tTarget\tISComments\n"
809 "s72\ti2\tS64\tS0\tS255\n"
810 "CustomAction\tAction\n"
811 "RunInstall\t87\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
812
813 static const char ci_component_dat[] =
814 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
815 "s72\tS38\ts72\ti2\tS255\tS72\n"
816 "Component\tComponent\n"
817 "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
818
819 static const char ci2_component_dat[] =
820 "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
821 "s72\tS38\ts72\ti2\tS255\tS72\n"
822 "Component\tComponent\n"
823 "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
824
825 static const char ci2_feature_comp_dat[] =
826 "Feature_\tComponent_\n"
827 "s38\ts72\n"
828 "FeatureComponents\tFeature_\tComponent_\n"
829 "feature\taugustus";
830
831 static const char ci2_file_dat[] =
832 "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
833 "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
834 "File\tFile\n"
835 "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
836
837 static const char cl_custom_action_dat[] =
838 "Action\tType\tSource\tTarget\tISComments\n"
839 "s72\ti2\tS64\tS0\tS255\n"
840 "CustomAction\tAction\n"
841 "TestCommandlineProp\t19\t\tTest1\t\n";
842
843 static const char cl_install_exec_seq_dat[] =
844 "Action\tCondition\tSequence\n"
845 "s72\tS255\tI2\n"
846 "InstallExecuteSequence\tAction\n"
847 "LaunchConditions\t\t100\n"
848 "ValidateProductID\t\t700\n"
849 "CostInitialize\t\t800\n"
850 "FileCost\t\t900\n"
851 "CostFinalize\t\t1000\n"
852 "TestCommandlineProp\tP=\"one\"\t1100\n"
853 "InstallInitialize\t\t1500\n"
854 "ProcessComponents\t\t1600\n"
855 "InstallValidate\t\t1400\n"
856 "InstallFinalize\t\t5000\n";
857
858 typedef struct _msi_table
859 {
860 const CHAR *filename;
861 const CHAR *data;
862 int size;
863 } msi_table;
864
865 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
866
867 static const msi_table tables[] =
868 {
869 ADD_TABLE(directory),
870 ADD_TABLE(component),
871 ADD_TABLE(feature),
872 ADD_TABLE(feature_comp),
873 ADD_TABLE(file),
874 ADD_TABLE(install_exec_seq),
875 ADD_TABLE(media),
876 ADD_TABLE(property),
877 };
878
879 static const msi_table mcp_tables[] =
880 {
881 ADD_TABLE(directory),
882 ADD_TABLE(mcp_component),
883 ADD_TABLE(mcp_feature),
884 ADD_TABLE(mcp_feature_comp),
885 ADD_TABLE(mcp_file),
886 ADD_TABLE(install_exec_seq),
887 ADD_TABLE(media),
888 ADD_TABLE(property)
889 };
890
891 static const msi_table lus0_tables[] =
892 {
893 ADD_TABLE(lus_component),
894 ADD_TABLE(directory),
895 ADD_TABLE(lus_feature),
896 ADD_TABLE(lus_feature_comp),
897 ADD_TABLE(lus_file),
898 ADD_TABLE(lus_install_exec_seq),
899 ADD_TABLE(lus0_media),
900 ADD_TABLE(property)
901 };
902
903 static const msi_table lus1_tables[] =
904 {
905 ADD_TABLE(lus_component),
906 ADD_TABLE(directory),
907 ADD_TABLE(lus_feature),
908 ADD_TABLE(lus_feature_comp),
909 ADD_TABLE(lus_file),
910 ADD_TABLE(lus_install_exec_seq),
911 ADD_TABLE(lus1_media),
912 ADD_TABLE(property)
913 };
914
915 static const msi_table lus2_tables[] =
916 {
917 ADD_TABLE(lus_component),
918 ADD_TABLE(directory),
919 ADD_TABLE(lus_feature),
920 ADD_TABLE(lus_feature_comp),
921 ADD_TABLE(lus_file),
922 ADD_TABLE(lus_install_exec_seq),
923 ADD_TABLE(lus2_media),
924 ADD_TABLE(property)
925 };
926
927 static const msi_table spf_tables[] =
928 {
929 ADD_TABLE(lus_component),
930 ADD_TABLE(directory),
931 ADD_TABLE(lus_feature),
932 ADD_TABLE(lus_feature_comp),
933 ADD_TABLE(lus_file),
934 ADD_TABLE(lus0_media),
935 ADD_TABLE(property),
936 ADD_TABLE(spf_custom_action),
937 ADD_TABLE(spf_install_exec_seq),
938 ADD_TABLE(spf_install_ui_seq)
939 };
940
941 static const msi_table sd_tables[] =
942 {
943 ADD_TABLE(directory),
944 ADD_TABLE(sd_component),
945 ADD_TABLE(sd_feature),
946 ADD_TABLE(sd_feature_comp),
947 ADD_TABLE(sd_file),
948 ADD_TABLE(sd_install_exec_seq),
949 ADD_TABLE(sd_install_ui_seq),
950 ADD_TABLE(sd_custom_action),
951 ADD_TABLE(media),
952 ADD_TABLE(property)
953 };
954
955 static const msi_table ci_tables[] =
956 {
957 ADD_TABLE(ci_component),
958 ADD_TABLE(directory),
959 ADD_TABLE(lus_feature),
960 ADD_TABLE(lus_feature_comp),
961 ADD_TABLE(lus_file),
962 ADD_TABLE(ci_install_exec_seq),
963 ADD_TABLE(lus0_media),
964 ADD_TABLE(property),
965 ADD_TABLE(ci_custom_action),
966 };
967
968 static const msi_table ci2_tables[] =
969 {
970 ADD_TABLE(ci2_component),
971 ADD_TABLE(directory),
972 ADD_TABLE(lus_feature),
973 ADD_TABLE(ci2_feature_comp),
974 ADD_TABLE(ci2_file),
975 ADD_TABLE(install_exec_seq),
976 ADD_TABLE(lus0_media),
977 ADD_TABLE(property),
978 };
979
980 static const msi_table cl_tables[] =
981 {
982 ADD_TABLE(component),
983 ADD_TABLE(directory),
984 ADD_TABLE(feature),
985 ADD_TABLE(feature_comp),
986 ADD_TABLE(file),
987 ADD_TABLE(cl_custom_action),
988 ADD_TABLE(cl_install_exec_seq),
989 ADD_TABLE(media),
990 ADD_TABLE(property)
991 };
992
993 static void write_file(const CHAR *filename, const char *data, int data_size)
994 {
995 DWORD size;
996
997 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
998 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
999
1000 WriteFile(hf, data, data_size, &size, NULL);
1001 CloseHandle(hf);
1002 }
1003
1004 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
1005 {
1006 MSIHANDLE summary;
1007 UINT r;
1008
1009 r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1010 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1011
1012 r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
1013 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1014
1015 r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1016 "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
1017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1018
1019 r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
1020 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1021
1022 r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
1023 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1024
1025 r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1026 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1027
1028 /* write the summary changes back to the stream */
1029 r = MsiSummaryInfoPersist(summary);
1030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1031
1032 MsiCloseHandle(summary);
1033 }
1034
1035 #define create_database(name, tables, num_tables) \
1036 create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
1037
1038 #define create_database_template(name, tables, num_tables, version, template) \
1039 create_database_wordcount(name, tables, num_tables, version, 0, template);
1040
1041 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
1042 int num_tables, INT version, INT wordcount,
1043 const char *template)
1044 {
1045 MSIHANDLE db;
1046 UINT r;
1047 int j;
1048
1049 r = MsiOpenDatabaseA(name, MSIDBOPEN_CREATE, &db);
1050 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1051
1052 /* import the tables into the database */
1053 for (j = 0; j < num_tables; j++)
1054 {
1055 const msi_table *table = &tables[j];
1056
1057 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1058
1059 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1060 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1061
1062 DeleteFileA(table->filename);
1063 }
1064
1065 write_msi_summary_info(db, version, wordcount, template);
1066
1067 r = MsiDatabaseCommit(db);
1068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1069
1070 MsiCloseHandle(db);
1071 }
1072
1073 static UINT run_query(MSIHANDLE hdb, const char *query)
1074 {
1075 MSIHANDLE hview = 0;
1076 UINT r;
1077
1078 r = MsiDatabaseOpenView(hdb, query, &hview);
1079 if (r != ERROR_SUCCESS)
1080 return r;
1081
1082 r = MsiViewExecute(hview, 0);
1083 if (r == ERROR_SUCCESS)
1084 r = MsiViewClose(hview);
1085 MsiCloseHandle(hview);
1086 return r;
1087 }
1088
1089 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
1090 {
1091 UINT res;
1092 MSIHANDLE suminfo;
1093
1094 /* build summary info */
1095 res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
1096 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
1097
1098 res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
1099 "Installation Database");
1100 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1101
1102 res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
1103 "Installation Database");
1104 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1105
1106 res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
1107 "Wine Hackers");
1108 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1109
1110 res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
1111 ";1033");
1112 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1113
1114 res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
1115 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
1116 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1117
1118 res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
1119 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1120
1121 res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
1122 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1123
1124 res = MsiSummaryInfoPersist(suminfo);
1125 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
1126
1127 res = MsiCloseHandle(suminfo);
1128 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
1129
1130 return res;
1131 }
1132
1133 static MSIHANDLE create_package_db(LPSTR prodcode)
1134 {
1135 MSIHANDLE hdb = 0;
1136 CHAR query[MAX_PATH];
1137 UINT res;
1138
1139 DeleteFile(msifile);
1140
1141 /* create an empty database */
1142 res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
1143 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1144 if (res != ERROR_SUCCESS)
1145 return hdb;
1146
1147 res = MsiDatabaseCommit(hdb);
1148 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1149
1150 set_summary_info(hdb, prodcode);
1151
1152 res = run_query(hdb,
1153 "CREATE TABLE `Directory` ( "
1154 "`Directory` CHAR(255) NOT NULL, "
1155 "`Directory_Parent` CHAR(255), "
1156 "`DefaultDir` CHAR(255) NOT NULL "
1157 "PRIMARY KEY `Directory`)");
1158 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1159
1160 res = run_query(hdb,
1161 "CREATE TABLE `Property` ( "
1162 "`Property` CHAR(72) NOT NULL, "
1163 "`Value` CHAR(255) "
1164 "PRIMARY KEY `Property`)");
1165 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1166
1167 sprintf(query, "INSERT INTO `Property` "
1168 "(`Property`, `Value`) "
1169 "VALUES( 'ProductCode', '%s' )", prodcode);
1170 res = run_query(hdb, query);
1171 ok(res == ERROR_SUCCESS , "Failed\n");
1172
1173 res = MsiDatabaseCommit(hdb);
1174 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1175
1176 return hdb;
1177 }
1178
1179 static void test_usefeature(void)
1180 {
1181 INSTALLSTATE r;
1182
1183 if (!pMsiUseFeatureExA)
1184 {
1185 win_skip("MsiUseFeatureExA not implemented\n");
1186 return;
1187 }
1188
1189 r = MsiQueryFeatureState(NULL,NULL);
1190 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1191
1192 r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
1193 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1194
1195 r = pMsiUseFeatureExA(NULL,NULL,0,0);
1196 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1197
1198 r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
1199 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1200
1201 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1202 NULL, -2, 0 );
1203 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1204
1205 r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
1206 "WORDVIEWFiles", -2, 0 );
1207 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1208
1209 r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
1210 "WORDVIEWFiles", -2, 0 );
1211 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1212
1213 r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1214 "WORDVIEWFiles", -2, 1 );
1215 ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1216 }
1217
1218 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
1219 {
1220 if (pRegDeleteKeyExA)
1221 return pRegDeleteKeyExA( key, subkey, access, 0 );
1222 return RegDeleteKeyA( key, subkey );
1223 }
1224
1225 static void test_null(void)
1226 {
1227 MSIHANDLE hpkg;
1228 UINT r;
1229 HKEY hkey;
1230 DWORD dwType, cbData;
1231 LPBYTE lpData = NULL;
1232 INSTALLSTATE state;
1233 REGSAM access = KEY_ALL_ACCESS;
1234
1235 if (is_wow64)
1236 access |= KEY_WOW64_64KEY;
1237
1238 r = pMsiOpenPackageExW(NULL, 0, &hpkg);
1239 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1240
1241 state = MsiQueryProductStateW(NULL);
1242 ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
1243
1244 r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
1245 ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1246
1247 r = MsiConfigureFeatureW(NULL, NULL, 0);
1248 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1249
1250 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
1251 ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1252
1253 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
1254 ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1255
1256 r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
1257 ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
1258
1259 /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
1260 * necessary registry values */
1261
1262 /* empty product string */
1263 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
1264 if (r == ERROR_ACCESS_DENIED)
1265 {
1266 skip("Not enough rights to perform tests\n");
1267 return;
1268 }
1269 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1270
1271 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1272 ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
1273 if ( r == ERROR_SUCCESS )
1274 {
1275 lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
1276 if (!lpData)
1277 skip("Out of memory\n");
1278 else
1279 {
1280 r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1281 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1282 }
1283 }
1284
1285 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1286 if (r == ERROR_ACCESS_DENIED)
1287 {
1288 skip("Not enough rights to perform tests\n");
1289 HeapFree(GetProcessHeap(), 0, lpData);
1290 RegCloseKey(hkey);
1291 return;
1292 }
1293 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1294
1295 r = MsiGetProductInfoA("", "", NULL, NULL);
1296 ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1297
1298 if (lpData)
1299 {
1300 r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
1301 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1302
1303 HeapFree(GetProcessHeap(), 0, lpData);
1304 }
1305 else
1306 {
1307 r = RegDeleteValueA(hkey, NULL);
1308 ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1309 }
1310
1311 r = RegCloseKey(hkey);
1312 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1313
1314 /* empty attribute */
1315 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1316 0, NULL, 0, access, NULL, &hkey, NULL);
1317 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1318
1319 r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1320 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1321
1322 r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
1323 ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
1324
1325 r = RegCloseKey(hkey);
1326 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1327
1328 r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1329 access & KEY_WOW64_64KEY);
1330 ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1331 }
1332
1333 static void test_getcomponentpath(void)
1334 {
1335 INSTALLSTATE r;
1336 char buffer[0x100];
1337 DWORD sz;
1338
1339 if(!pMsiGetComponentPathA)
1340 return;
1341
1342 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
1343 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1344
1345 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
1346 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1347
1348 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
1349 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1350
1351 sz = sizeof buffer;
1352 buffer[0]=0;
1353 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
1354 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1355
1356 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
1357 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
1358 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1359
1360 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1361 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
1362 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1363
1364 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1365 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
1366 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1367
1368 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
1369 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
1370 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1371 }
1372
1373 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
1374 {
1375 HANDLE file;
1376 DWORD written;
1377
1378 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1379 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1380 WriteFile(file, data, strlen(data), &written, NULL);
1381
1382 if (size)
1383 {
1384 SetFilePointer(file, size, NULL, FILE_BEGIN);
1385 SetEndOfFile(file);
1386 }
1387
1388 CloseHandle(file);
1389 }
1390
1391 static void create_test_files(void)
1392 {
1393 CreateDirectoryA("msitest", NULL);
1394 create_file("msitest\\one.txt", "msitest\\one.txt", 100);
1395 CreateDirectoryA("msitest\\first", NULL);
1396 create_file("msitest\\first\\two.txt", "msitest\\first\\two.txt", 100);
1397 CreateDirectoryA("msitest\\second", NULL);
1398 create_file("msitest\\second\\three.txt", "msitest\\second\\three.txt", 100);
1399
1400 create_file("four.txt", "four.txt", 100);
1401 create_file("five.txt", "five.txt", 100);
1402 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1403
1404 create_file("msitest\\filename", "msitest\\filename", 100);
1405 create_file("msitest\\service.exe", "msitest\\service.exe", 100);
1406
1407 DeleteFileA("four.txt");
1408 DeleteFileA("five.txt");
1409 }
1410
1411 static void delete_test_files(void)
1412 {
1413 DeleteFileA("msitest.msi");
1414 DeleteFileA("msitest.cab");
1415 DeleteFileA("msitest\\second\\three.txt");
1416 DeleteFileA("msitest\\first\\two.txt");
1417 DeleteFileA("msitest\\one.txt");
1418 DeleteFileA("msitest\\service.exe");
1419 DeleteFileA("msitest\\filename");
1420 RemoveDirectoryA("msitest\\second");
1421 RemoveDirectoryA("msitest\\first");
1422 RemoveDirectoryA("msitest");
1423 }
1424
1425 #define HASHSIZE sizeof(MSIFILEHASHINFO)
1426
1427 static const struct
1428 {
1429 LPCSTR data;
1430 DWORD size;
1431 MSIFILEHASHINFO hash;
1432 } hash_data[] =
1433 {
1434 { "", 0,
1435 { HASHSIZE,
1436 { 0, 0, 0, 0 },
1437 },
1438 },
1439
1440 { "abc", 0,
1441 { HASHSIZE,
1442 { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
1443 },
1444 },
1445
1446 { "C:\\Program Files\\msitest\\caesar\n", 0,
1447 { HASHSIZE,
1448 { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
1449 },
1450 },
1451
1452 { "C:\\Program Files\\msitest\\caesar\n", 500,
1453 { HASHSIZE,
1454 { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
1455 },
1456 },
1457 };
1458
1459 static void test_MsiGetFileHash(void)
1460 {
1461 const char name[] = "msitest.bin";
1462 UINT r;
1463 MSIFILEHASHINFO hash;
1464 DWORD i;
1465
1466 if (!pMsiGetFileHashA)
1467 {
1468 win_skip("MsiGetFileHash not implemented\n");
1469 return;
1470 }
1471
1472 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1473
1474 /* szFilePath is NULL */
1475 r = pMsiGetFileHashA(NULL, 0, &hash);
1476 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1477
1478 /* szFilePath is empty */
1479 r = pMsiGetFileHashA("", 0, &hash);
1480 ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
1481 "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
1482
1483 /* szFilePath is nonexistent */
1484 r = pMsiGetFileHashA(name, 0, &hash);
1485 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
1486
1487 /* dwOptions is non-zero */
1488 r = pMsiGetFileHashA(name, 1, &hash);
1489 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1490
1491 /* pHash.dwFileHashInfoSize is not correct */
1492 hash.dwFileHashInfoSize = 0;
1493 r = pMsiGetFileHashA(name, 0, &hash);
1494 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1495
1496 /* pHash is NULL */
1497 r = pMsiGetFileHashA(name, 0, NULL);
1498 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1499
1500 for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
1501 {
1502 int ret;
1503
1504 create_file(name, hash_data[i].data, hash_data[i].size);
1505
1506 memset(&hash, 0, sizeof(MSIFILEHASHINFO));
1507 hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1508
1509 r = pMsiGetFileHashA(name, 0, &hash);
1510 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1511
1512 ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
1513 ok(!ret, "Hash incorrect\n");
1514
1515 DeleteFile(name);
1516 }
1517 }
1518
1519 /* copied from dlls/msi/registry.c */
1520 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
1521 {
1522 DWORD i,n=1;
1523 GUID guid;
1524
1525 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
1526 return FALSE;
1527
1528 for(i=0; i<8; i++)
1529 out[7-i] = in[n++];
1530 n++;
1531 for(i=0; i<4; i++)
1532 out[11-i] = in[n++];
1533 n++;
1534 for(i=0; i<4; i++)
1535 out[15-i] = in[n++];
1536 n++;
1537 for(i=0; i<2; i++)
1538 {
1539 out[17+i*2] = in[n++];
1540 out[16+i*2] = in[n++];
1541 }
1542 n++;
1543 for( ; i<8; i++)
1544 {
1545 out[17+i*2] = in[n++];
1546 out[16+i*2] = in[n++];
1547 }
1548 out[32]=0;
1549 return TRUE;
1550 }
1551
1552 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
1553 {
1554 WCHAR guidW[MAX_PATH];
1555 WCHAR squashedW[MAX_PATH];
1556 GUID guid;
1557 HRESULT hr;
1558 int size;
1559
1560 hr = CoCreateGuid(&guid);
1561 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1562
1563 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1564 ok(size == 39, "Expected 39, got %d\n", hr);
1565
1566 WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
1567 if (squashed)
1568 {
1569 squash_guid(guidW, squashedW);
1570 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1571 }
1572 }
1573
1574 static char *get_user_sid(void)
1575 {
1576 HANDLE token;
1577 DWORD size = 0;
1578 TOKEN_USER *user;
1579 char *usersid = NULL;
1580
1581 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
1582 GetTokenInformation(token, TokenUser, NULL, size, &size);
1583
1584 user = HeapAlloc(GetProcessHeap(), 0, size);
1585 GetTokenInformation(token, TokenUser, user, size, &size);
1586 pConvertSidToStringSidA(user->User.Sid, &usersid);
1587 HeapFree(GetProcessHeap(), 0, user);
1588
1589 CloseHandle(token);
1590 return usersid;
1591 }
1592
1593 static void test_MsiQueryProductState(void)
1594 {
1595 CHAR prodcode[MAX_PATH];
1596 CHAR prod_squashed[MAX_PATH];
1597 CHAR keypath[MAX_PATH*2];
1598 LPSTR usersid;
1599 INSTALLSTATE state;
1600 LONG res;
1601 HKEY userkey, localkey, props;
1602 HKEY prodkey;
1603 DWORD data, error;
1604 REGSAM access = KEY_ALL_ACCESS;
1605
1606 create_test_guid(prodcode, prod_squashed);
1607 usersid = get_user_sid();
1608
1609 if (is_wow64)
1610 access |= KEY_WOW64_64KEY;
1611
1612 /* NULL prodcode */
1613 SetLastError(0xdeadbeef);
1614 state = MsiQueryProductStateA(NULL);
1615 error = GetLastError();
1616 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1617 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1618
1619 /* empty prodcode */
1620 SetLastError(0xdeadbeef);
1621 state = MsiQueryProductStateA("");
1622 error = GetLastError();
1623 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1624 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1625
1626 /* garbage prodcode */
1627 SetLastError(0xdeadbeef);
1628 state = MsiQueryProductStateA("garbage");
1629 error = GetLastError();
1630 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1631 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1632
1633 /* guid without brackets */
1634 SetLastError(0xdeadbeef);
1635 state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
1636 error = GetLastError();
1637 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1638 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1639
1640 /* guid with brackets */
1641 SetLastError(0xdeadbeef);
1642 state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
1643 error = GetLastError();
1644 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1645 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1646 "expected ERROR_SUCCESS, got %u\n", error);
1647
1648 /* same length as guid, but random */
1649 SetLastError(0xdeadbeef);
1650 state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
1651 error = GetLastError();
1652 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1653 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1654
1655 /* MSIINSTALLCONTEXT_USERUNMANAGED */
1656
1657 SetLastError(0xdeadbeef);
1658 state = MsiQueryProductStateA(prodcode);
1659 error = GetLastError();
1660 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1661 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1662 "expected ERROR_SUCCESS, got %u\n", error);
1663
1664 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1665 lstrcatA(keypath, prod_squashed);
1666
1667 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1668 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1669
1670 /* user product key exists */
1671 SetLastError(0xdeadbeef);
1672 state = MsiQueryProductStateA(prodcode);
1673 error = GetLastError();
1674 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1675 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1676 "expected ERROR_SUCCESS, got %u\n", error);
1677
1678 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
1679 lstrcatA(keypath, prodcode);
1680
1681 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1682 if (res == ERROR_ACCESS_DENIED)
1683 {
1684 skip("Not enough rights to perform tests\n");
1685 RegDeleteKeyA(userkey, "");
1686 LocalFree(usersid);
1687 return;
1688 }
1689 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1690
1691 /* local uninstall key exists */
1692 SetLastError(0xdeadbeef);
1693 state = MsiQueryProductStateA(prodcode);
1694 error = GetLastError();
1695 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1696 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1697 "expected ERROR_SUCCESS, got %u\n", error);
1698
1699 data = 1;
1700 res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1701 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1702
1703 /* WindowsInstaller value exists */
1704 SetLastError(0xdeadbeef);
1705 state = MsiQueryProductStateA(prodcode);
1706 error = GetLastError();
1707 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1708 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1709 "expected ERROR_SUCCESS, got %u\n", error);
1710
1711 RegDeleteValueA(localkey, "WindowsInstaller");
1712 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1713
1714 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1715 lstrcatA(keypath, usersid);
1716 lstrcatA(keypath, "\\Products\\");
1717 lstrcatA(keypath, prod_squashed);
1718
1719 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1720 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1721
1722 /* local product key exists */
1723 SetLastError(0xdeadbeef);
1724 state = MsiQueryProductStateA(prodcode);
1725 error = GetLastError();
1726 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1727 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1728 "expected ERROR_SUCCESS, got %u\n", error);
1729
1730 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1731 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1732
1733 /* install properties key exists */
1734 SetLastError(0xdeadbeef);
1735 state = MsiQueryProductStateA(prodcode);
1736 error = GetLastError();
1737 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1738 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1739 "expected ERROR_SUCCESS, got %u\n", error);
1740
1741 data = 1;
1742 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1743 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1744
1745 /* WindowsInstaller value exists */
1746 SetLastError(0xdeadbeef);
1747 state = MsiQueryProductStateA(prodcode);
1748 error = GetLastError();
1749 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1750 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1751 "expected ERROR_SUCCESS, got %u\n", error);
1752
1753 data = 2;
1754 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1755 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1756
1757 /* WindowsInstaller value is not 1 */
1758 SetLastError(0xdeadbeef);
1759 state = MsiQueryProductStateA(prodcode);
1760 error = GetLastError();
1761 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1762 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1763 "expected ERROR_SUCCESS, got %u\n", error);
1764
1765 RegDeleteKeyA(userkey, "");
1766
1767 /* user product key does not exist */
1768 SetLastError(0xdeadbeef);
1769 state = MsiQueryProductStateA(prodcode);
1770 error = GetLastError();
1771 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1772 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1773 "expected ERROR_SUCCESS, got %u\n", error);
1774
1775 RegDeleteValueA(props, "WindowsInstaller");
1776 delete_key(props, "", access & KEY_WOW64_64KEY);
1777 RegCloseKey(props);
1778 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1779 RegCloseKey(localkey);
1780 RegDeleteKeyA(userkey, "");
1781 RegCloseKey(userkey);
1782
1783 /* MSIINSTALLCONTEXT_USERMANAGED */
1784
1785 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1786 lstrcatA(keypath, usersid);
1787 lstrcatA(keypath, "\\Installer\\Products\\");
1788 lstrcatA(keypath, prod_squashed);
1789
1790 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1791 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1792
1793 state = MsiQueryProductStateA(prodcode);
1794 ok(state == INSTALLSTATE_ADVERTISED,
1795 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1796
1797 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1798 lstrcatA(keypath, usersid);
1799 lstrcatA(keypath, "\\Products\\");
1800 lstrcatA(keypath, prod_squashed);
1801
1802 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1803 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1804
1805 state = MsiQueryProductStateA(prodcode);
1806 ok(state == INSTALLSTATE_ADVERTISED,
1807 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1808
1809 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1810 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1811
1812 state = MsiQueryProductStateA(prodcode);
1813 ok(state == INSTALLSTATE_ADVERTISED,
1814 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1815
1816 data = 1;
1817 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1818 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1819
1820 /* WindowsInstaller value exists */
1821 state = MsiQueryProductStateA(prodcode);
1822 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1823
1824 RegDeleteValueA(props, "WindowsInstaller");
1825 delete_key(props, "", access & KEY_WOW64_64KEY);
1826 RegCloseKey(props);
1827 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1828 RegCloseKey(localkey);
1829 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1830 RegCloseKey(prodkey);
1831
1832 /* MSIINSTALLCONTEXT_MACHINE */
1833
1834 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1835 lstrcatA(keypath, prod_squashed);
1836
1837 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1838 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1839
1840 state = MsiQueryProductStateA(prodcode);
1841 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1842
1843 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1844 lstrcatA(keypath, "S-1-5-18\\Products\\");
1845 lstrcatA(keypath, prod_squashed);
1846
1847 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1848 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1849
1850 state = MsiQueryProductStateA(prodcode);
1851 ok(state == INSTALLSTATE_ADVERTISED,
1852 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1853
1854 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1855 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1856
1857 state = MsiQueryProductStateA(prodcode);
1858 ok(state == INSTALLSTATE_ADVERTISED,
1859 "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1860
1861 data = 1;
1862 res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1863 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1864
1865 /* WindowsInstaller value exists */
1866 state = MsiQueryProductStateA(prodcode);
1867 ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1868
1869 RegDeleteValueA(props, "WindowsInstaller");
1870 delete_key(props, "", access & KEY_WOW64_64KEY);
1871 RegCloseKey(props);
1872 delete_key(localkey, "", access & KEY_WOW64_64KEY);
1873 RegCloseKey(localkey);
1874 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1875 RegCloseKey(prodkey);
1876
1877 LocalFree(usersid);
1878 }
1879
1880 static const char table_enc85[] =
1881 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
1882 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
1883 "yz{}~";
1884
1885 /*
1886 * Encodes a base85 guid given a GUID pointer
1887 * Caller should provide a 21 character buffer for the encoded string.
1888 */
1889 static void encode_base85_guid( GUID *guid, LPWSTR str )
1890 {
1891 unsigned int x, *p, i;
1892
1893 p = (unsigned int*) guid;
1894 for( i=0; i<4; i++ )
1895 {
1896 x = p[i];
1897 *str++ = table_enc85[x%85];
1898 x = x/85;
1899 *str++ = table_enc85[x%85];
1900 x = x/85;
1901 *str++ = table_enc85[x%85];
1902 x = x/85;
1903 *str++ = table_enc85[x%85];
1904 x = x/85;
1905 *str++ = table_enc85[x%85];
1906 }
1907 *str = 0;
1908 }
1909
1910 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
1911 {
1912 WCHAR guidW[MAX_PATH];
1913 WCHAR base85W[MAX_PATH];
1914 WCHAR squashedW[MAX_PATH];
1915 GUID guid;
1916 HRESULT hr;
1917 int size;
1918
1919 hr = CoCreateGuid(&guid);
1920 ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1921
1922 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1923 ok(size == 39, "Expected 39, got %d\n", hr);
1924
1925 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1926 encode_base85_guid(&guid, base85W);
1927 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1928 squash_guid(guidW, squashedW);
1929 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1930 }
1931
1932 static void test_MsiQueryFeatureState(void)
1933 {
1934 HKEY userkey, localkey, compkey, compkey2;
1935 CHAR prodcode[MAX_PATH];
1936 CHAR prod_squashed[MAX_PATH];
1937 CHAR component[MAX_PATH];
1938 CHAR comp_base85[MAX_PATH];
1939 CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
1940 CHAR keypath[MAX_PATH*2];
1941 INSTALLSTATE state;
1942 LPSTR usersid;
1943 LONG res;
1944 REGSAM access = KEY_ALL_ACCESS;
1945 DWORD error;
1946
1947 create_test_guid(prodcode, prod_squashed);
1948 compose_base85_guid(component, comp_base85, comp_squashed);
1949 compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
1950 usersid = get_user_sid();
1951
1952 if (is_wow64)
1953 access |= KEY_WOW64_64KEY;
1954
1955 /* NULL prodcode */
1956 SetLastError(0xdeadbeef);
1957 state = MsiQueryFeatureStateA(NULL, "feature");
1958 error = GetLastError();
1959 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1960 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1961
1962 /* empty prodcode */
1963 SetLastError(0xdeadbeef);
1964 state = MsiQueryFeatureStateA("", "feature");
1965 error = GetLastError();
1966 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1967 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1968
1969 /* garbage prodcode */
1970 SetLastError(0xdeadbeef);
1971 state = MsiQueryFeatureStateA("garbage", "feature");
1972 error = GetLastError();
1973 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1974 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1975
1976 /* guid without brackets */
1977 SetLastError(0xdeadbeef);
1978 state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
1979 error = GetLastError();
1980 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1981 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1982
1983 /* guid with brackets */
1984 SetLastError(0xdeadbeef);
1985 state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
1986 error = GetLastError();
1987 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1988 ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
1989 "expected ERROR_SUCCESS, got %u\n", error);
1990
1991 /* same length as guid, but random */
1992 SetLastError(0xdeadbeef);
1993 state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
1994 error = GetLastError();
1995 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1996 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1997
1998 /* NULL szFeature */
1999 SetLastError(0xdeadbeef);
2000 state = MsiQueryFeatureStateA(prodcode, NULL);
2001 error = GetLastError();
2002 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2003 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2004
2005 /* empty szFeature */
2006 SetLastError(0xdeadbeef);
2007 state = MsiQueryFeatureStateA(prodcode, "");
2008 error = GetLastError();
2009 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2010 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2011 "expected ERROR_SUCCESS, got %u\n", error);
2012
2013 /* feature key does not exist yet */
2014 SetLastError(0xdeadbeef);
2015 state = MsiQueryFeatureStateA(prodcode, "feature");
2016 error = GetLastError();
2017 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2018 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2019 "expected ERROR_SUCCESS, got %u\n", error);
2020
2021 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2022
2023 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
2024 lstrcatA(keypath, prod_squashed);
2025
2026 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2028
2029 /* feature key exists */
2030 SetLastError(0xdeadbeef);
2031 state = MsiQueryFeatureStateA(prodcode, "feature");
2032 error = GetLastError();
2033 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2034 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2035 "expected ERROR_SUCCESS, got %u\n", error);
2036
2037 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
2038 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2039
2040 /* feature value exists */
2041 SetLastError(0xdeadbeef);
2042 state = MsiQueryFeatureStateA(prodcode, "feature");
2043 error = GetLastError();
2044 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2045 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2046 "expected ERROR_SUCCESS, got %u\n", error);
2047
2048 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2049 lstrcatA(keypath, usersid);
2050 lstrcatA(keypath, "\\Products\\");
2051 lstrcatA(keypath, prod_squashed);
2052 lstrcatA(keypath, "\\Features");
2053
2054 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2055 if (res == ERROR_ACCESS_DENIED)
2056 {
2057 skip("Not enough rights to perform tests\n");
2058 RegDeleteKeyA(userkey, "");
2059 RegCloseKey(userkey);
2060 LocalFree(usersid);
2061 return;
2062 }
2063 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2064
2065 /* userdata features key exists */
2066 SetLastError(0xdeadbeef);
2067 state = MsiQueryFeatureStateA(prodcode, "feature");
2068 error = GetLastError();
2069 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2070 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2071 "expected ERROR_SUCCESS, got %u\n", error);
2072
2073 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2074 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2075
2076 SetLastError(0xdeadbeef);
2077 state = MsiQueryFeatureStateA(prodcode, "feature");
2078 error = GetLastError();
2079 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2080 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2081 "expected ERROR_SUCCESS, got %u\n", error);
2082
2083 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2084 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2085
2086 SetLastError(0xdeadbeef);
2087 state = MsiQueryFeatureStateA(prodcode, "feature");
2088 error = GetLastError();
2089 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2090 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2091 "expected ERROR_SUCCESS, got %u\n", error);
2092
2093 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2094 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2095
2096 SetLastError(0xdeadbeef);
2097 state = MsiQueryFeatureStateA(prodcode, "feature");
2098 error = GetLastError();
2099 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2100 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2101 "expected ERROR_SUCCESS, got %u\n", error);
2102
2103 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2104 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2105
2106 SetLastError(0xdeadbeef);
2107 state = MsiQueryFeatureStateA(prodcode, "feature");
2108 error = GetLastError();
2109 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2110 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2111 "expected ERROR_SUCCESS, got %u\n", error);
2112
2113 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2114 lstrcatA(keypath, usersid);
2115 lstrcatA(keypath, "\\Components\\");
2116 lstrcatA(keypath, comp_squashed);
2117
2118 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2119 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2120
2121 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2122 lstrcatA(keypath, usersid);
2123 lstrcatA(keypath, "\\Components\\");
2124 lstrcatA(keypath, comp_squashed2);
2125
2126 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2127 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2128
2129 SetLastError(0xdeadbeef);
2130 state = MsiQueryFeatureStateA(prodcode, "feature");
2131 error = GetLastError();
2132 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2133 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2134 "expected ERROR_SUCCESS, got %u\n", error);
2135
2136 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2137 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2138
2139 SetLastError(0xdeadbeef);
2140 state = MsiQueryFeatureStateA(prodcode, "feature");
2141 error = GetLastError();
2142 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2143 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2144 "expected ERROR_SUCCESS, got %u\n", error);
2145
2146 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2147 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2148
2149 SetLastError(0xdeadbeef);
2150 state = MsiQueryFeatureStateA(prodcode, "feature");
2151 error = GetLastError();
2152 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2153 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2154 "expected ERROR_SUCCESS, got %u\n", error);
2155
2156 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2157 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2158
2159 /* INSTALLSTATE_LOCAL */
2160 SetLastError(0xdeadbeef);
2161 state = MsiQueryFeatureStateA(prodcode, "feature");
2162 error = GetLastError();
2163 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2164 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2165 "expected ERROR_SUCCESS, got %u\n", error);
2166
2167 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2168 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2169
2170 /* INSTALLSTATE_SOURCE */
2171 SetLastError(0xdeadbeef);
2172 state = MsiQueryFeatureStateA(prodcode, "feature");
2173 error = GetLastError();
2174 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2175 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2176 "expected ERROR_SUCCESS, got %u\n", error);
2177
2178 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2179 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2180
2181 /* bad INSTALLSTATE_SOURCE */
2182 SetLastError(0xdeadbeef);
2183 state = MsiQueryFeatureStateA(prodcode, "feature");
2184 error = GetLastError();
2185 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2186 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2187 "expected ERROR_SUCCESS, got %u\n", error);
2188
2189 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2190 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2191
2192 /* INSTALLSTATE_SOURCE */
2193 SetLastError(0xdeadbeef);
2194 state = MsiQueryFeatureStateA(prodcode, "feature");
2195 error = GetLastError();
2196 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2197 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2198 "expected ERROR_SUCCESS, got %u\n", error);
2199
2200 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2201 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2202
2203 /* bad INSTALLSTATE_SOURCE */
2204 SetLastError(0xdeadbeef);
2205 state = MsiQueryFeatureStateA(prodcode, "feature");
2206 error = GetLastError();
2207 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2208 ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2209 "expected ERROR_SUCCESS, got %u\n", error);
2210
2211 RegDeleteValueA(compkey, prod_squashed);
2212 RegDeleteValueA(compkey2, prod_squashed);
2213 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2214 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2215 RegDeleteValueA(localkey, "feature");
2216 RegDeleteValueA(userkey, "feature");
2217 RegDeleteKeyA(userkey, "");
2218 RegCloseKey(compkey);
2219 RegCloseKey(compkey2);
2220 RegCloseKey(localkey);
2221 RegCloseKey(userkey);
2222
2223 /* MSIINSTALLCONTEXT_USERMANAGED */
2224
2225 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2226 lstrcatA(keypath, usersid);
2227 lstrcatA(keypath, "\\Installer\\Features\\");
2228 lstrcatA(keypath, prod_squashed);
2229
2230 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2231 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2232
2233 /* feature key exists */
2234 state = MsiQueryFeatureStateA(prodcode, "feature");
2235 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2236
2237 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2238 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2239
2240 /* feature value exists */
2241 state = MsiQueryFeatureStateA(prodcode, "feature");
2242 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2243
2244 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2245 lstrcatA(keypath, usersid);
2246 lstrcatA(keypath, "\\Products\\");
2247 lstrcatA(keypath, prod_squashed);
2248 lstrcatA(keypath, "\\Features");
2249
2250 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2251 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2252
2253 /* userdata features key exists */
2254 state = MsiQueryFeatureStateA(prodcode, "feature");
2255 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2256
2257 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2258 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2259
2260 state = MsiQueryFeatureStateA(prodcode, "feature");
2261 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2262
2263 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2264 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2265
2266 state = MsiQueryFeatureStateA(prodcode, "feature");
2267 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2268
2269 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2270 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2271
2272 state = MsiQueryFeatureStateA(prodcode, "feature");
2273 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2274
2275 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2276 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2277
2278 state = MsiQueryFeatureStateA(prodcode, "feature");
2279 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2280
2281 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2282 lstrcatA(keypath, usersid);
2283 lstrcatA(keypath, "\\Components\\");
2284 lstrcatA(keypath, comp_squashed);
2285
2286 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2287 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2288
2289 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2290 lstrcatA(keypath, usersid);
2291 lstrcatA(keypath, "\\Components\\");
2292 lstrcatA(keypath, comp_squashed2);
2293
2294 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2295 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2296
2297 state = MsiQueryFeatureStateA(prodcode, "feature");
2298 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2299
2300 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2301 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2302
2303 state = MsiQueryFeatureStateA(prodcode, "feature");
2304 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2305
2306 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2307 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2308
2309 state = MsiQueryFeatureStateA(prodcode, "feature");
2310 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2311
2312 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2313 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2314
2315 state = MsiQueryFeatureStateA(prodcode, "feature");
2316 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2317
2318 RegDeleteValueA(compkey, prod_squashed);
2319 RegDeleteValueA(compkey2, prod_squashed);
2320 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2321 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2322 RegDeleteValueA(localkey, "feature");
2323 RegDeleteValueA(userkey, "feature");
2324 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2325 RegCloseKey(compkey);
2326 RegCloseKey(compkey2);
2327 RegCloseKey(localkey);
2328 RegCloseKey(userkey);
2329
2330 /* MSIINSTALLCONTEXT_MACHINE */
2331
2332 lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
2333 lstrcatA(keypath, prod_squashed);
2334
2335 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2336 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2337
2338 /* feature key exists */
2339 state = MsiQueryFeatureStateA(prodcode, "feature");
2340 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2341
2342 res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2343 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2344
2345 /* feature value exists */
2346 state = MsiQueryFeatureStateA(prodcode, "feature");
2347 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2348
2349 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2350 lstrcatA(keypath, "S-1-5-18\\Products\\");
2351 lstrcatA(keypath, prod_squashed);
2352 lstrcatA(keypath, "\\Features");
2353
2354 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2356
2357 /* userdata features key exists */
2358 state = MsiQueryFeatureStateA(prodcode, "feature");
2359 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2360
2361 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2362 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2363
2364 state = MsiQueryFeatureStateA(prodcode, "feature");
2365 ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2366
2367 res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
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(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
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(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2380 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2381
2382 state = MsiQueryFeatureStateA(prodcode, "feature");
2383 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2384
2385 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2386 lstrcatA(keypath, "S-1-5-18\\Components\\");
2387 lstrcatA(keypath, comp_squashed);
2388
2389 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2390 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2391
2392 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2393 lstrcatA(keypath, "S-1-5-18\\Components\\");
2394 lstrcatA(keypath, comp_squashed2);
2395
2396 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2397 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2398
2399 state = MsiQueryFeatureStateA(prodcode, "feature");
2400 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2401
2402 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2403 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2404
2405 state = MsiQueryFeatureStateA(prodcode, "feature");
2406 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2407
2408 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2410
2411 state = MsiQueryFeatureStateA(prodcode, "feature");
2412 ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2413
2414 res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2415 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2416
2417 state = MsiQueryFeatureStateA(prodcode, "feature");
2418 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2419
2420 RegDeleteValueA(compkey, prod_squashed);
2421 RegDeleteValueA(compkey2, prod_squashed);
2422 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2423 delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2424 RegDeleteValueA(localkey, "feature");
2425 RegDeleteValueA(userkey, "feature");
2426 delete_key(userkey, "", access & KEY_WOW64_64KEY);
2427 RegCloseKey(compkey);
2428 RegCloseKey(compkey2);
2429 RegCloseKey(localkey);
2430 RegCloseKey(userkey);
2431 LocalFree(usersid);
2432 }
2433
2434 static void test_MsiQueryComponentState(void)
2435 {
2436 HKEY compkey, prodkey;
2437 CHAR prodcode[MAX_PATH];
2438 CHAR prod_squashed[MAX_PATH];
2439 CHAR component[MAX_PATH];
2440 CHAR comp_base85[MAX_PATH];
2441 CHAR comp_squashed[MAX_PATH];
2442 CHAR keypath[MAX_PATH];
2443 INSTALLSTATE state;
2444 LPSTR usersid;
2445 LONG res;
2446 UINT r;
2447 REGSAM access = KEY_ALL_ACCESS;
2448 DWORD error;
2449
2450 static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
2451
2452 if (!pMsiQueryComponentStateA)
2453 {
2454 win_skip("MsiQueryComponentStateA not implemented\n");
2455 return;
2456 }
2457
2458 create_test_guid(prodcode, prod_squashed);
2459 compose_base85_guid(component, comp_base85, comp_squashed);
2460 usersid = get_user_sid();
2461
2462 if (is_wow64)
2463 access |= KEY_WOW64_64KEY;
2464
2465 /* NULL szProductCode */
2466 state = MAGIC_ERROR;
2467 SetLastError(0xdeadbeef);
2468 r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2469 error = GetLastError();
2470 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2471 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2472 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2473
2474 /* empty szProductCode */
2475 state = MAGIC_ERROR;
2476 SetLastError(0xdeadbeef);
2477 r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2478 error = GetLastError();
2479 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2480 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2481 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2482
2483 /* random szProductCode */
2484 state = MAGIC_ERROR;
2485 SetLastError(0xdeadbeef);
2486 r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2487 error = GetLastError();
2488 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2489 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2490 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2491
2492 /* GUID-length szProductCode */
2493 state = MAGIC_ERROR;
2494 SetLastError(0xdeadbeef);
2495 r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2496 error = GetLastError();
2497 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2498 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2499 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2500
2501 /* GUID-length with brackets */
2502 state = MAGIC_ERROR;
2503 SetLastError(0xdeadbeef);
2504 r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2505 error = GetLastError();
2506 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2507 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2508 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2509
2510 /* actual GUID */
2511 state = MAGIC_ERROR;
2512 SetLastError(0xdeadbeef);
2513 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2514 error = GetLastError();
2515 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2516 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2517 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2518
2519 state = MAGIC_ERROR;
2520 SetLastError(0xdeadbeef);
2521 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2522 error = GetLastError();
2523 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2524 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2525 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2526
2527 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2528 lstrcatA(keypath, prod_squashed);
2529
2530 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2531 if (res == ERROR_ACCESS_DENIED)
2532 {
2533 skip("Not enough rights to perform tests\n");
2534 LocalFree(usersid);
2535 return;
2536 }
2537 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2538
2539 state = MAGIC_ERROR;
2540 SetLastError(0xdeadbeef);
2541 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2542 error = GetLastError();
2543 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2544 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2545 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2546
2547 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2548 RegCloseKey(prodkey);
2549
2550 /* create local system product key */
2551 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
2552 lstrcatA(keypath, prod_squashed);
2553 lstrcatA(keypath, "\\InstallProperties");
2554
2555 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2556 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2557
2558 /* local system product key exists */
2559 state = MAGIC_ERROR;
2560 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2561 error = GetLastError();
2562 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2563 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2564 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2565
2566 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2567 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2568
2569 /* LocalPackage value exists */
2570 state = MAGIC_ERROR;
2571 SetLastError(0xdeadbeef);
2572 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2573 error = GetLastError();
2574 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2575 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2576 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2577
2578 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
2579 lstrcatA(keypath, comp_squashed);
2580
2581 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2582 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2583
2584 /* component key exists */
2585 state = MAGIC_ERROR;
2586 SetLastError(0xdeadbeef);
2587 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2588 error = GetLastError();
2589 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2590 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2591 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2592
2593 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2594 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2595
2596 /* component\product exists */
2597 state = MAGIC_ERROR;
2598 SetLastError(0xdeadbeef);
2599 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2601 error = GetLastError();
2602 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2603 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2604 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2605
2606 /* NULL component, product exists */
2607 state = MAGIC_ERROR;
2608 SetLastError(0xdeadbeef);
2609 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
2610 error = GetLastError();
2611 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2612 ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
2613 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2614
2615 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2616 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2617
2618 /* INSTALLSTATE_LOCAL */
2619 state = MAGIC_ERROR;
2620 SetLastError(0xdeadbeef);
2621 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2622 error = GetLastError();
2623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2624 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2625 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2626
2627 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2628 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2629
2630 /* INSTALLSTATE_SOURCE */
2631 state = MAGIC_ERROR;
2632 SetLastError(0xdeadbeef);
2633 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2634 error = GetLastError();
2635 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2636 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2637 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2638
2639 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2640 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2641
2642 /* bad INSTALLSTATE_SOURCE */
2643 state = MAGIC_ERROR;
2644 SetLastError(0xdeadbeef);
2645 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2646 error = GetLastError();
2647 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2648 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2649 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2650
2651 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2653
2654 /* INSTALLSTATE_SOURCE */
2655 state = MAGIC_ERROR;
2656 SetLastError(0xdeadbeef);
2657 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2658 error = GetLastError();
2659 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2660 ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2661 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2662
2663 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
2664 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2665
2666 /* registry component */
2667 state = MAGIC_ERROR;
2668 SetLastError(0xdeadbeef);
2669 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2670 error = GetLastError();
2671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2672 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2673 ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2674
2675 RegDeleteValueA(prodkey, "LocalPackage");
2676 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2677 RegDeleteValueA(compkey, prod_squashed);
2678 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2679 RegCloseKey(prodkey);
2680 RegCloseKey(compkey);
2681
2682 /* MSIINSTALLCONTEXT_USERUNMANAGED */
2683
2684 state = MAGIC_ERROR;
2685 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2686 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2687 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2688
2689 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2690 lstrcatA(keypath, prod_squashed);
2691
2692 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2693 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2694
2695 state = MAGIC_ERROR;
2696 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2697 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2698 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2699
2700 RegDeleteKeyA(prodkey, "");
2701 RegCloseKey(prodkey);
2702
2703 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2704 lstrcatA(keypath, usersid);
2705 lstrcatA(keypath, "\\Products\\");
2706 lstrcatA(keypath, prod_squashed);
2707 lstrcatA(keypath, "\\InstallProperties");
2708
2709 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2710 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2711
2712 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2713 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2714
2715 RegCloseKey(prodkey);
2716
2717 state = MAGIC_ERROR;
2718 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2719 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2720 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2721
2722 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2723 lstrcatA(keypath, usersid);
2724 lstrcatA(keypath, "\\Components\\");
2725 lstrcatA(keypath, comp_squashed);
2726
2727 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2728 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2729
2730 /* component key exists */
2731 state = MAGIC_ERROR;
2732 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2733 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2734 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2735
2736 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2737 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2738
2739 /* component\product exists */
2740 state = MAGIC_ERROR;
2741 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2742 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2743 ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
2744 "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2745
2746 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2747 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2748
2749 state = MAGIC_ERROR;
2750 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2751 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2752 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2753
2754 /* MSIINSTALLCONTEXT_USERMANAGED */
2755
2756 state = MAGIC_ERROR;
2757 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2758 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2759 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2760
2761 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2762 lstrcatA(keypath, prod_squashed);
2763
2764 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2765 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2766
2767 state = MAGIC_ERROR;
2768 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2769 ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2770 ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2771
2772 RegDeleteKeyA(prodkey, "");
2773 RegCloseKey(prodkey);
2774
2775 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2776 lstrcatA(keypath, usersid);
2777 lstrcatA(keypath, "\\Installer\\Products\\");
2778 lstrcatA(keypath, prod_squashed);
2779
2780 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2781 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2782
2783 state = MAGIC_ERROR;
2784 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2785 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2786 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2787
2788 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2789 RegCloseKey(prodkey);
2790
2791 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2792 lstrcatA(keypath, usersid);
2793 lstrcatA(keypath, "\\Products\\");
2794 lstrcatA(keypath, prod_squashed);
2795 lstrcatA(keypath, "\\InstallProperties");
2796
2797 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2798 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2799
2800 res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2801 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2802
2803 state = MAGIC_ERROR;
2804 r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2805 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2806 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2807
2808 RegDeleteValueA(prodkey, "LocalPackage");
2809 RegDeleteValueA(prodkey, "ManagedLocalPackage");
2810 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2811 RegDeleteValueA(compkey, prod_squashed);
2812 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2813 RegCloseKey(prodkey);
2814 RegCloseKey(compkey);
2815 LocalFree(usersid);
2816 }
2817
2818 static void test_MsiGetComponentPath(void)
2819 {
2820 HKEY compkey, prodkey, installprop;
2821 CHAR prodcode[MAX_PATH];
2822 CHAR prod_squashed[MAX_PATH];
2823 CHAR component[MAX_PATH];
2824 CHAR comp_base85[MAX_PATH];
2825 CHAR comp_squashed[MAX_PATH];
2826 CHAR keypath[MAX_PATH];
2827 CHAR path[MAX_PATH];
2828 INSTALLSTATE state;
2829 LPSTR usersid;
2830 DWORD size, val;
2831 REGSAM access = KEY_ALL_ACCESS;
2832 LONG res;
2833
2834 create_test_guid(prodcode, prod_squashed);
2835 compose_base85_guid(component, comp_base85, comp_squashed);
2836 usersid = get_user_sid();
2837
2838 if (is_wow64)
2839 access |= KEY_WOW64_64KEY;
2840
2841 /* NULL szProduct */
2842 size = MAX_PATH;
2843 state = MsiGetComponentPathA(NULL, component, path, &size);
2844 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2845 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2846
2847 /* NULL szComponent */
2848 size = MAX_PATH;
2849 state = MsiGetComponentPathA(prodcode, NULL, path, &size);
2850 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2851 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2852
2853 size = MAX_PATH;
2854 state = MsiLocateComponentA(NULL, path, &size);
2855 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2856 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2857
2858 /* NULL lpPathBuf */
2859 size = MAX_PATH;
2860 state = MsiGetComponentPathA(prodcode, component, NULL, &size);
2861 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2862 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2863
2864 size = MAX_PATH;
2865 state = MsiLocateComponentA(component, NULL, &size);
2866 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2867 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2868
2869 /* NULL pcchBuf */
2870 size = MAX_PATH;
2871 state = MsiGetComponentPathA(prodcode, component, path, NULL);
2872 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2873 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2874
2875 size = MAX_PATH;
2876 state = MsiLocateComponentA(component, path, NULL);
2877 ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2878 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2879
2880 /* all params valid */
2881 size = MAX_PATH;
2882 state = MsiGetComponentPathA(prodcode, component, path, &size);
2883 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2884 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2885
2886 size = MAX_PATH;
2887 state = MsiLocateComponentA(component, path, &size);
2888 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2889 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2890
2891 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2892 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2893 lstrcatA(keypath, comp_squashed);
2894
2895 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2896 if (res == ERROR_ACCESS_DENIED)
2897 {
2898 skip("Not enough rights to perform tests\n");
2899 LocalFree(usersid);
2900 return;
2901 }
2902 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2903
2904 /* local system component key exists */
2905 size = MAX_PATH;
2906 state = MsiGetComponentPathA(prodcode, component, path, &size);
2907 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2908 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2909
2910 size = MAX_PATH;
2911 state = MsiLocateComponentA(component, path, &size);
2912 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2913 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2914
2915 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2916 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2917
2918 /* product value exists */
2919 path[0] = 0;
2920 size = MAX_PATH;
2921 state = MsiGetComponentPathA(prodcode, component, path, &size);
2922 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2923 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2924 ok(size == 10, "Expected 10, got %d\n", size);
2925
2926 path[0] = 0;
2927 size = MAX_PATH;
2928 state = MsiLocateComponentA(component, path, &size);
2929 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2930 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2931 ok(size == 10, "Expected 10, got %d\n", size);
2932
2933 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2934 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
2935 lstrcatA(keypath, prod_squashed);
2936 lstrcatA(keypath, "\\InstallProperties");
2937
2938 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
2939 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2940
2941 val = 1;
2942 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2943 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2944
2945 /* install properties key exists */
2946 path[0] = 0;
2947 size = MAX_PATH;
2948 state = MsiGetComponentPathA(prodcode, component, path, &size);
2949 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2950 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2951 ok(size == 10, "Expected 10, got %d\n", size);
2952
2953 path[0] = 0;
2954 size = MAX_PATH;
2955 state = MsiLocateComponentA(component, path, &size);
2956 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2957 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2958 ok(size == 10, "Expected 10, got %d\n", size);
2959
2960 create_file("C:\\imapath", "C:\\imapath", 11);
2961
2962 /* file exists */
2963 path[0] = 0;
2964 size = MAX_PATH;
2965 state = MsiGetComponentPathA(prodcode, component, path, &size);
2966 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2967 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2968 ok(size == 10, "Expected 10, got %d\n", size);
2969
2970 path[0] = 0;
2971 size = MAX_PATH;
2972 state = MsiLocateComponentA(component, path, &size);
2973 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2974 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2975 ok(size == 10, "Expected 10, got %d\n", size);
2976
2977 RegDeleteValueA(compkey, prod_squashed);
2978 delete_key(compkey, "", access & KEY_WOW64_64KEY);
2979 RegDeleteValueA(installprop, "WindowsInstaller");
2980 delete_key(installprop, "", access & KEY_WOW64_64KEY);
2981 RegCloseKey(compkey);
2982 RegCloseKey(installprop);
2983 DeleteFileA("C:\\imapath");
2984
2985 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2986 lstrcatA(keypath, "Installer\\UserData\\");
2987 lstrcatA(keypath, usersid);
2988 lstrcatA(keypath, "\\Components\\");
2989 lstrcatA(keypath, comp_squashed);
2990
2991 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2992 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2993
2994 /* user managed component key exists */
2995 size = MAX_PATH;
2996 state = MsiGetComponentPathA(prodcode, component, path, &size);
2997 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2998 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2999
3000 size = MAX_PATH;
3001 state = MsiLocateComponentA(component, path, &size);
3002 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3003 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3004
3005 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3006 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3007
3008 /* product value exists */
3009 path[0] = 0;
3010 size = MAX_PATH;
3011 state = MsiGetComponentPathA(prodcode, component, path, &size);
3012 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3013 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3014 ok(size == 10, "Expected 10, got %d\n", size);
3015
3016 path[0] = 0;
3017 size = MAX_PATH;
3018 state = MsiLocateComponentA(component, path, &size);
3019 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3020 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3021 ok(size == 10, "Expected 10, got %d\n", size);
3022
3023 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3024 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3025 lstrcatA(keypath, prod_squashed);
3026 lstrcatA(keypath, "\\InstallProperties");
3027
3028 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3029 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3030
3031 val = 1;
3032 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3033 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3034
3035 /* install properties key exists */
3036 path[0] = 0;
3037 size = MAX_PATH;
3038 state = MsiGetComponentPathA(prodcode, component, path, &size);
3039 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3040 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, 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 = MsiLocateComponentA(component, path, &size);
3046 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, 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 create_file("C:\\imapath", "C:\\imapath", 11);
3051
3052 /* file exists */
3053 path[0] = 0;
3054 size = MAX_PATH;
3055 state = MsiGetComponentPathA(prodcode, component, path, &size);
3056 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3057 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3058 ok(size == 10, "Expected 10, got %d\n", size);
3059
3060 path[0] = 0;
3061 size = MAX_PATH;
3062 state = MsiLocateComponentA(component, path, &size);
3063 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3064 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3065 ok(size == 10, "Expected 10, got %d\n", size);
3066
3067 RegDeleteValueA(compkey, prod_squashed);
3068 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3069 RegDeleteValueA(installprop, "WindowsInstaller");
3070 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3071 RegCloseKey(compkey);
3072 RegCloseKey(installprop);
3073 DeleteFileA("C:\\imapath");
3074
3075 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3076 lstrcatA(keypath, "Installer\\Managed\\");
3077 lstrcatA(keypath, usersid);
3078 lstrcatA(keypath, "\\Installer\\Products\\");
3079 lstrcatA(keypath, prod_squashed);
3080
3081 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3082 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3083
3084 /* user managed product key exists */
3085 size = MAX_PATH;
3086 state = MsiGetComponentPathA(prodcode, component, path, &size);
3087 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3088 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3089
3090 size = MAX_PATH;
3091 state = MsiLocateComponentA(component, path, &size);
3092 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3093 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3094
3095 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3096 lstrcatA(keypath, "Installer\\UserData\\");
3097 lstrcatA(keypath, usersid);
3098 lstrcatA(keypath, "\\Components\\");
3099 lstrcatA(keypath, comp_squashed);
3100
3101 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3103
3104 /* user managed component key exists */
3105 size = MAX_PATH;
3106 state = MsiGetComponentPathA(prodcode, component, path, &size);
3107 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3108 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3109
3110 size = MAX_PATH;
3111 state = MsiLocateComponentA(component, path, &size);
3112 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3113 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3114
3115 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3116 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3117
3118 /* product value exists */
3119 path[0] = 0;
3120 size = MAX_PATH;
3121 state = MsiGetComponentPathA(prodcode, component, path, &size);
3122 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3123 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3124 ok(size == 10, "Expected 10, got %d\n", size);
3125
3126 path[0] = 0;
3127 size = MAX_PATH;
3128 state = MsiLocateComponentA(component, path, &size);
3129 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3130 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3131 ok(size == 10, "Expected 10, got %d\n", size);
3132
3133 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3134 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3135 lstrcatA(keypath, prod_squashed);
3136 lstrcatA(keypath, "\\InstallProperties");
3137
3138 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3139 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3140
3141 val = 1;
3142 res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3143 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3144
3145 /* install properties key exists */
3146 path[0] = 0;
3147 size = MAX_PATH;
3148 state = MsiGetComponentPathA(prodcode, component, path, &size);
3149 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3150 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3151 ok(size == 10, "Expected 10, got %d\n", size);
3152
3153 path[0] = 0;
3154 size = MAX_PATH;
3155 state = MsiLocateComponentA(component, path, &size);
3156 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3157 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3158 ok(size == 10, "Expected 10, got %d\n", size);
3159
3160 create_file("C:\\imapath", "C:\\imapath", 11);
3161
3162 /* file exists */
3163 path[0] = 0;
3164 size = MAX_PATH;
3165 state = MsiGetComponentPathA(prodcode, component, path, &size);
3166 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3167 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3168 ok(size == 10, "Expected 10, got %d\n", size);
3169
3170 path[0] = 0;
3171 size = MAX_PATH;
3172 state = MsiLocateComponentA(component, path, &size);
3173 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3174 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3175 ok(size == 10, "Expected 10, got %d\n", size);
3176
3177 RegDeleteValueA(compkey, prod_squashed);
3178 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3179 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3180 RegDeleteValueA(installprop, "WindowsInstaller");
3181 delete_key(installprop, "", access & KEY_WOW64_64KEY);
3182 RegCloseKey(prodkey);
3183 RegCloseKey(compkey);
3184 RegCloseKey(installprop);
3185 DeleteFileA("C:\\imapath");
3186
3187 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3188 lstrcatA(keypath, prod_squashed);
3189
3190 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3191 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3192
3193 /* user unmanaged product key exists */
3194 size = MAX_PATH;
3195 state = MsiGetComponentPathA(prodcode, component, path, &size);
3196 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3197 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3198
3199 size = MAX_PATH;
3200 state = MsiLocateComponentA(component, path, &size);
3201 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3202 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3203
3204 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3205 lstrcatA(keypath, "Installer\\UserData\\");
3206 lstrcatA(keypath, usersid);
3207 lstrcatA(keypath, "\\Components\\");
3208 lstrcatA(keypath, comp_squashed);
3209
3210 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3211 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3212
3213 /* user unmanaged component key exists */
3214 size = MAX_PATH;
3215 state = MsiGetComponentPathA(prodcode, component, path, &size);
3216 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3217 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3218
3219 size = MAX_PATH;
3220 state = MsiLocateComponentA(component, path, &size);
3221 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3222 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3223
3224 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3225 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3226
3227 /* product value exists */
3228 path[0] = 0;
3229 size = MAX_PATH;
3230 state = MsiGetComponentPathA(prodcode, component, path, &size);
3231 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3232 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3233 ok(size == 10, "Expected 10, got %d\n", size);
3234
3235 path[0] = 0;
3236 size = MAX_PATH;
3237 state = MsiLocateComponentA(component, path, &size);
3238 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3239 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3240 ok(size == 10, "Expected 10, got %d\n", size);
3241
3242 create_file("C:\\imapath", "C:\\imapath", 11);
3243
3244 /* file exists */
3245 path[0] = 0;
3246 size = MAX_PATH;
3247 state = MsiGetComponentPathA(prodcode, component, path, &size);
3248 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3249 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3250 ok(size == 10, "Expected 10, got %d\n", size);
3251
3252 path[0] = 0;
3253 size = MAX_PATH;
3254 state = MsiLocateComponentA(component, path, &size);
3255 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3256 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3257 ok(size == 10, "Expected 10, got %d\n", size);
3258
3259 RegDeleteValueA(compkey, prod_squashed);
3260 RegDeleteKeyA(prodkey, "");
3261 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3262 RegCloseKey(prodkey);
3263 RegCloseKey(compkey);
3264 DeleteFileA("C:\\imapath");
3265
3266 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3267 lstrcatA(keypath, prod_squashed);
3268
3269 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3270 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3271
3272 /* local classes product key exists */
3273 size = MAX_PATH;
3274 state = MsiGetComponentPathA(prodcode, component, path, &size);
3275 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3276 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3277
3278 size = MAX_PATH;
3279 state = MsiLocateComponentA(component, path, &size);
3280 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3281 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3282
3283 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3284 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3285 lstrcatA(keypath, comp_squashed);
3286
3287 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3288 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3289
3290 /* local user component key exists */
3291 size = MAX_PATH;
3292 state = MsiGetComponentPathA(prodcode, component, path, &size);
3293 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3294 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3295
3296 size = MAX_PATH;
3297 state = MsiLocateComponentA(component, path, &size);
3298 ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3299 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3300
3301 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3302 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3303
3304 /* product value exists */
3305 path[0] = 0;
3306 size = MAX_PATH;
3307 state = MsiGetComponentPathA(prodcode, component, path, &size);
3308 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3309 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3310 ok(size == 10, "Expected 10, got %d\n", size);
3311
3312 path[0] = 0;
3313 size = MAX_PATH;
3314 state = MsiLocateComponentA(component, path, &size);
3315 ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3316 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3317 ok(size == 10, "Expected 10, got %d\n", size);
3318
3319 create_file("C:\\imapath", "C:\\imapath", 11);
3320
3321 /* file exists */
3322 path[0] = 0;
3323 size = MAX_PATH;
3324 state = MsiGetComponentPathA(prodcode, component, path, &size);
3325 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, 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 path[0] = 0;
3330 size = MAX_PATH;
3331 state = MsiLocateComponentA(component, path, &size);
3332 ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3333 ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3334 ok(size == 10, "Expected 10, got %d\n", size);
3335
3336 RegDeleteValueA(compkey, prod_squashed);
3337 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3338 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3339 RegCloseKey(prodkey);
3340 RegCloseKey(compkey);
3341 DeleteFileA("C:\\imapath");
3342 LocalFree(usersid);
3343 }
3344
3345 static void test_MsiGetProductCode(void)
3346 {
3347 HKEY compkey, prodkey;
3348 CHAR prodcode[MAX_PATH];
3349 CHAR prod_squashed[MAX_PATH];
3350 CHAR prodcode2[MAX_PATH];
3351 CHAR prod2_squashed[MAX_PATH];
3352 CHAR component[MAX_PATH];
3353 CHAR comp_base85[MAX_PATH];
3354 CHAR comp_squashed[MAX_PATH];
3355 CHAR keypath[MAX_PATH];
3356 CHAR product[MAX_PATH];
3357 LPSTR usersid;
3358 LONG res;
3359 UINT r;
3360 REGSAM access = KEY_ALL_ACCESS;
3361
3362 create_test_guid(prodcode, prod_squashed);
3363 create_test_guid(prodcode2, prod2_squashed);
3364 compose_base85_guid(component, comp_base85, comp_squashed);
3365 usersid = get_user_sid();
3366
3367 if (is_wow64)
3368 access |= KEY_WOW64_64KEY;
3369
3370 /* szComponent is NULL */
3371 lstrcpyA(product, "prod");
3372 r = MsiGetProductCodeA(NULL, product);
3373 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3374 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3375
3376 /* szComponent is empty */
3377 lstrcpyA(product, "prod");
3378 r = MsiGetProductCodeA("", product);
3379 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3380 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3381
3382 /* garbage szComponent */
3383 lstrcpyA(product, "prod");
3384 r = MsiGetProductCodeA("garbage", product);
3385 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3386 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3387
3388 /* guid without brackets */
3389 lstrcpyA(product, "prod");
3390 r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
3391 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3392 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3393
3394 /* guid with brackets */
3395 lstrcpyA(product, "prod");
3396 r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
3397 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3398 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3399
3400 /* same length as guid, but random */
3401 lstrcpyA(product, "prod");
3402 r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
3403 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3404 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3405
3406 /* all params correct, szComponent not published */
3407 lstrcpyA(product, "prod");
3408 r = MsiGetProductCodeA(component, product);
3409 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3410 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3411
3412 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3413 lstrcatA(keypath, "Installer\\UserData\\");
3414 lstrcatA(keypath, usersid);
3415 lstrcatA(keypath, "\\Components\\");
3416 lstrcatA(keypath, comp_squashed);
3417
3418 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3419 if (res == ERROR_ACCESS_DENIED)
3420 {
3421 skip("Not enough rights to perform tests\n");
3422 LocalFree(usersid);
3423 return;
3424 }
3425 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3426
3427 /* user unmanaged component key exists */
3428 lstrcpyA(product, "prod");
3429 r = MsiGetProductCodeA(component, product);
3430 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3431 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3432
3433 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3434 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436 /* product value exists */
3437 lstrcpyA(product, "prod");
3438 r = MsiGetProductCodeA(component, product);
3439 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3440 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3441
3442 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3443 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3444
3445 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3446 lstrcatA(keypath, "Installer\\Managed\\");
3447 lstrcatA(keypath, usersid);
3448 lstrcatA(keypath, "\\Installer\\Products\\");
3449 lstrcatA(keypath, prod_squashed);
3450
3451 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3452 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3453
3454 /* user managed product key of first product exists */
3455 lstrcpyA(product, "prod");
3456 r = MsiGetProductCodeA(component, product);
3457 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3458 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3459
3460 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3461 RegCloseKey(prodkey);
3462
3463 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3464 lstrcatA(keypath, prod_squashed);
3465
3466 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3467 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3468
3469 /* user unmanaged product key exists */
3470 lstrcpyA(product, "prod");
3471 r = MsiGetProductCodeA(component, product);
3472 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3473 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3474
3475 RegDeleteKeyA(prodkey, "");
3476 RegCloseKey(prodkey);
3477
3478 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3479 lstrcatA(keypath, prod_squashed);
3480
3481 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3482 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3483
3484 /* local classes product key exists */
3485 lstrcpyA(product, "prod");
3486 r = MsiGetProductCodeA(component, product);
3487 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3488 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3489
3490 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3491 RegCloseKey(prodkey);
3492
3493 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3494 lstrcatA(keypath, "Installer\\Managed\\");
3495 lstrcatA(keypath, usersid);
3496 lstrcatA(keypath, "\\Installer\\Products\\");
3497 lstrcatA(keypath, prod2_squashed);
3498
3499 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3500 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3501
3502 /* user managed product key of second product exists */
3503 lstrcpyA(product, "prod");
3504 r = MsiGetProductCodeA(component, product);
3505 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3506 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3507
3508 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3509 RegCloseKey(prodkey);
3510 RegDeleteValueA(compkey, prod_squashed);
3511 RegDeleteValueA(compkey, prod2_squashed);
3512 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3513 RegCloseKey(compkey);
3514
3515 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3516 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3517 lstrcatA(keypath, comp_squashed);
3518
3519 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3520 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3521
3522 /* local user component key exists */
3523 lstrcpyA(product, "prod");
3524 r = MsiGetProductCodeA(component, product);
3525 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3526 ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
3527
3528 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3529 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3530
3531 /* product value exists */
3532 lstrcpyA(product, "prod");
3533 r = MsiGetProductCodeA(component, product);
3534 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3535 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3536
3537 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3538 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3539
3540 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3541 lstrcatA(keypath, "Installer\\Managed\\");
3542 lstrcatA(keypath, usersid);
3543 lstrcatA(keypath, "\\Installer\\Products\\");
3544 lstrcatA(keypath, prod_squashed);
3545
3546 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3547 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3548
3549 /* user managed product key of first product exists */
3550 lstrcpyA(product, "prod");
3551 r = MsiGetProductCodeA(component, product);
3552 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3553 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3554
3555 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3556 RegCloseKey(prodkey);
3557
3558 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3559 lstrcatA(keypath, prod_squashed);
3560
3561 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3562 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3563
3564 /* user unmanaged product key exists */
3565 lstrcpyA(product, "prod");
3566 r = MsiGetProductCodeA(component, product);
3567 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3568 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3569
3570 RegDeleteKeyA(prodkey, "");
3571 RegCloseKey(prodkey);
3572
3573 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3574 lstrcatA(keypath, prod_squashed);
3575
3576 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3577 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3578
3579 /* local classes product key exists */
3580 lstrcpyA(product, "prod");
3581 r = MsiGetProductCodeA(component, product);
3582 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3583 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3584
3585 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3586 RegCloseKey(prodkey);
3587
3588 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3589 lstrcatA(keypath, "Installer\\Managed\\");
3590 lstrcatA(keypath, usersid);
3591 lstrcatA(keypath, "\\Installer\\Products\\");
3592 lstrcatA(keypath, prod2_squashed);
3593
3594 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3595 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3596
3597 /* user managed product key of second product exists */
3598 lstrcpyA(product, "prod");
3599 r = MsiGetProductCodeA(component, product);
3600 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3601 ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
3602
3603 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3604 RegCloseKey(prodkey);
3605 RegDeleteValueA(compkey, prod_squashed);
3606 RegDeleteValueA(compkey, prod2_squashed);
3607 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3608 RegCloseKey(compkey);
3609 LocalFree(usersid);
3610 }
3611
3612 static void test_MsiEnumClients(void)
3613 {
3614 HKEY compkey;
3615 CHAR prodcode[MAX_PATH];
3616 CHAR prod_squashed[MAX_PATH];
3617 CHAR prodcode2[MAX_PATH];
3618 CHAR prod2_squashed[MAX_PATH];
3619 CHAR component[MAX_PATH];
3620 CHAR comp_base85[MAX_PATH];
3621 CHAR comp_squashed[MAX_PATH];
3622 CHAR product[MAX_PATH];
3623 CHAR keypath[MAX_PATH];
3624 LPSTR usersid;
3625 LONG res;
3626 UINT r;
3627 REGSAM access = KEY_ALL_ACCESS;
3628
3629 create_test_guid(prodcode, prod_squashed);
3630 create_test_guid(prodcode2, prod2_squashed);
3631 compose_base85_guid(component, comp_base85, comp_squashed);
3632 usersid = get_user_sid();
3633
3634 if (is_wow64)
3635 access |= KEY_WOW64_64KEY;
3636
3637 /* NULL szComponent */
3638 product[0] = '\0';
3639 r = MsiEnumClientsA(NULL, 0, product);
3640 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3641 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3642
3643 /* empty szComponent */
3644 product[0] = '\0';
3645 r = MsiEnumClientsA("", 0, product);
3646 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3647 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3648
3649 /* NULL lpProductBuf */
3650 r = MsiEnumClientsA(component, 0, NULL);
3651 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3652
3653 /* all params correct, component missing */
3654 product[0] = '\0';
3655 r = MsiEnumClientsA(component, 0, product);
3656 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3657 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3658
3659 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3660 lstrcatA(keypath, "Installer\\UserData\\");
3661 lstrcatA(keypath, usersid);
3662 lstrcatA(keypath, "\\Components\\");
3663 lstrcatA(keypath, comp_squashed);
3664
3665 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3666 if (res == ERROR_ACCESS_DENIED)
3667 {
3668 skip("Not enough rights to perform tests\n");
3669 LocalFree(usersid);
3670 return;
3671 }
3672 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3673
3674 /* user unmanaged component key exists */
3675 product[0] = '\0';
3676 r = MsiEnumClientsA(component, 0, product);
3677 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3678 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3679
3680 /* index > 0, no products exist */
3681 product[0] = '\0';
3682 r = MsiEnumClientsA(component, 1, product);
3683 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3684 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3685
3686 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3687 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3688
3689 /* product value exists */
3690 r = MsiEnumClientsA(component, 0, product);
3691 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3692 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3693
3694 /* try index 0 again */
3695 product[0] = '\0';
3696 r = MsiEnumClientsA(component, 0, product);
3697 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3698 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3699
3700 /* try index 1, second product value does not exist */
3701 product[0] = '\0';
3702 r = MsiEnumClientsA(component, 1, product);
3703 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3704 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3705
3706 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3707 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3708
3709 /* try index 1, second product value does exist */
3710 product[0] = '\0';
3711 r = MsiEnumClientsA(component, 1, product);
3712 todo_wine
3713 {
3714 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3715 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3716 }
3717
3718 /* start the enumeration over */
3719 product[0] = '\0';
3720 r = MsiEnumClientsA(component, 0, product);
3721 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3722 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3723 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3724
3725 /* correctly query second product */
3726 product[0] = '\0';
3727 r = MsiEnumClientsA(component, 1, product);
3728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3729 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3730 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3731
3732 RegDeleteValueA(compkey, prod_squashed);
3733 RegDeleteValueA(compkey, prod2_squashed);
3734 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3735 RegCloseKey(compkey);
3736
3737 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3738 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3739 lstrcatA(keypath, comp_squashed);
3740
3741 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3742 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3743
3744 /* user local component key exists */
3745 product[0] = '\0';
3746 r = MsiEnumClientsA(component, 0, product);
3747 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3748 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3749
3750 /* index > 0, no products exist */
3751 product[0] = '\0';
3752 r = MsiEnumClientsA(component, 1, product);
3753 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3754 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3755
3756 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3757 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3758
3759 /* product value exists */
3760 product[0] = '\0';
3761 r = MsiEnumClientsA(component, 0, product);
3762 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3763 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3764
3765 /* try index 0 again */
3766 product[0] = '\0';
3767 r = MsiEnumClientsA(component, 0, product);
3768 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3769
3770 /* try index 1, second product value does not exist */
3771 product[0] = '\0';
3772 r = MsiEnumClientsA(component, 1, product);
3773 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3774 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3775
3776 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3777 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3778
3779 /* try index 1, second product value does exist */
3780 product[0] = '\0';
3781 r = MsiEnumClientsA(component, 1, product);
3782 todo_wine
3783 {
3784 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3785 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3786 }
3787
3788 /* start the enumeration over */
3789 product[0] = '\0';
3790 r = MsiEnumClientsA(component, 0, product);
3791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3792 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3793 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3794
3795 /* correctly query second product */
3796 product[0] = '\0';
3797 r = MsiEnumClientsA(component, 1, product);
3798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3799 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3800 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3801
3802 RegDeleteValueA(compkey, prod_squashed);
3803 RegDeleteValueA(compkey, prod2_squashed);
3804 delete_key(compkey, "", access & KEY_WOW64_64KEY);
3805 RegCloseKey(compkey);
3806 LocalFree(usersid);
3807 }
3808
3809 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
3810 LPSTR *langcheck, LPDWORD langchecksz)
3811 {
3812 LPSTR version;
3813 VS_FIXEDFILEINFO *ffi;
3814 DWORD size = GetFileVersionInfoSizeA(path, NULL);
3815 USHORT *lang;
3816
3817 version = HeapAlloc(GetProcessHeap(), 0, size);
3818 GetFileVersionInfoA(path, 0, size, version);
3819
3820 VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
3821 *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3822 sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
3823 LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
3824 LOWORD(ffi->dwFileVersionLS));
3825 *verchecksz = lstrlenA(*vercheck);
3826
3827 VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
3828 *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
3829 sprintf(*langcheck, "%d", *lang);
3830 *langchecksz = lstrlenA(*langcheck);
3831
3832 HeapFree(GetProcessHeap(), 0, version);
3833 }
3834
3835 static void test_MsiGetFileVersion(void)
3836 {
3837 UINT r;
3838 DWORD versz, langsz;
3839 char version[MAX_PATH];
3840 char lang[MAX_PATH];
3841 char path[MAX_PATH];
3842 LPSTR vercheck, langcheck;
3843 DWORD verchecksz, langchecksz;
3844
3845 /* NULL szFilePath */
3846 r = MsiGetFileVersionA(NULL, NULL, NULL, NULL, NULL);
3847 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3848
3849 versz = MAX_PATH;
3850 langsz = MAX_PATH;
3851 lstrcpyA(version, "version");
3852 lstrcpyA(lang, "lang");
3853 r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
3854 ok(r == ERROR_INVALID_PARAMETER,
3855 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3856 ok(!lstrcmpA(version, "version"),
3857 "Expected version to be unchanged, got %s\n", version);
3858 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3859 ok(!lstrcmpA(lang, "lang"),
3860 "Expected lang to be unchanged, got %s\n", lang);
3861 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3862
3863 /* empty szFilePath */
3864 r = MsiGetFileVersionA("", NULL, NULL, NULL, NULL);
3865 ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3866
3867 versz = MAX_PATH;
3868 langsz = MAX_PATH;
3869 lstrcpyA(version, "version");
3870 lstrcpyA(lang, "lang");
3871 r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
3872 ok(r == ERROR_FILE_NOT_FOUND,
3873 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3874 ok(!lstrcmpA(version, "version"),
3875 "Expected version to be unchanged, got %s\n", version);
3876 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3877 ok(!lstrcmpA(lang, "lang"),
3878 "Expected lang to be unchanged, got %s\n", lang);
3879 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3880
3881 /* nonexistent szFilePath */
3882 versz = MAX_PATH;
3883 langsz = MAX_PATH;
3884 lstrcpyA(version, "version");
3885 lstrcpyA(lang, "lang");
3886 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3887 ok(r == ERROR_FILE_NOT_FOUND,
3888 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3889 ok(!lstrcmpA(version, "version"),
3890 "Expected version to be unchanged, got %s\n", version);
3891 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3892 ok(!lstrcmpA(lang, "lang"),
3893 "Expected lang to be unchanged, got %s\n", lang);
3894 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3895
3896 /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
3897 versz = MAX_PATH;
3898 langsz = MAX_PATH;
3899 lstrcpyA(version, "version");
3900 lstrcpyA(lang, "lang");
3901 r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
3902 ok(r == ERROR_INVALID_PARAMETER,
3903 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3904 ok(!lstrcmpA(version, "version"),
3905 "Expected version to be unchanged, got %s\n", version);
3906 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3907 ok(!lstrcmpA(lang, "lang"),
3908 "Expected lang to be unchanged, got %s\n", lang);
3909 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3910
3911 /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
3912 versz = MAX_PATH;
3913 langsz = MAX_PATH;
3914 lstrcpyA(version, "version");
3915 lstrcpyA(lang, "lang");
3916 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
3917 ok(r == ERROR_INVALID_PARAMETER,
3918 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3919 ok(!lstrcmpA(version, "version"),
3920 "Expected version to be unchanged, got %s\n", version);
3921 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3922 ok(!lstrcmpA(lang, "lang"),
3923 "Expected lang to be unchanged, got %s\n", lang);
3924 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3925
3926 /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
3927 versz = 0;
3928 langsz = MAX_PATH;
3929 lstrcpyA(version, "version");
3930 lstrcpyA(lang, "lang");
3931 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3932 ok(r == ERROR_FILE_NOT_FOUND,
3933 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3934 ok(!lstrcmpA(version, "version"),
3935 "Expected version to be unchanged, got %s\n", version);
3936 ok(versz == 0, "Expected 0, got %d\n", versz);
3937 ok(!lstrcmpA(lang, "lang"),
3938 "Expected lang to be unchanged, got %s\n", lang);
3939 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3940
3941 /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
3942 versz = MAX_PATH;
3943 langsz = 0;
3944 lstrcpyA(version, "version");
3945 lstrcpyA(lang, "lang");
3946 r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
3947 ok(r == ERROR_FILE_NOT_FOUND,
3948 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3949 ok(!lstrcmpA(version, "version"),
3950 "Expected version to be unchanged, got %s\n", version);
3951 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3952 ok(!lstrcmpA(lang, "lang"),
3953 "Expected lang to be unchanged, got %s\n", lang);
3954 ok(langsz == 0, "Expected 0, got %d\n", langsz);
3955
3956 /* nonexistent szFilePath, rest NULL */
3957 r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
3958 ok(r == ERROR_FILE_NOT_FOUND,
3959 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3960
3961 create_file("ver.txt", "ver.txt", 20);
3962
3963 /* file exists, no version information */
3964 r = MsiGetFileVersionA("ver.txt", NULL, NULL, NULL, NULL);
3965 ok(r == ERROR_FILE_INVALID, "Expected ERROR_FILE_INVALID, got %d\n", r);
3966
3967 versz = MAX_PATH;
3968 langsz = MAX_PATH;
3969 lstrcpyA(version, "version");
3970 lstrcpyA(lang, "lang");
3971 r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
3972 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3973 ok(!lstrcmpA(version, "version"),
3974 "Expected version to be unchanged, got %s\n", version);
3975 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3976 ok(!lstrcmpA(lang, "lang"),
3977 "Expected lang to be unchanged, got %s\n", lang);
3978 ok(r == ERROR_FILE_INVALID,
3979 "Expected ERROR_FILE_INVALID, got %d\n", r);
3980
3981 DeleteFileA("ver.txt");
3982
3983 /* relative path, has version information */
3984 versz = MAX_PATH;
3985 langsz = MAX_PATH;
3986 lstrcpyA(version, "version");
3987 lstrcpyA(lang, "lang");
3988 r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
3989 todo_wine
3990 {
3991 ok(r == ERROR_FILE_NOT_FOUND,
3992 "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
3993 ok(!lstrcmpA(version, "version"),
3994 "Expected version to be unchanged, got %s\n", version);
3995 ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
3996 ok(!lstrcmpA(lang, "lang"),
3997 "Expected lang to be unchanged, got %s\n", lang);
3998 ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
3999 }
4000
4001 GetSystemDirectoryA(path, MAX_PATH);
4002 lstrcatA(path, "\\kernel32.dll");
4003
4004 get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
4005
4006 /* absolute path, has version information */
4007 versz = MAX_PATH;
4008 langsz = MAX_PATH;
4009 lstrcpyA(version, "version");
4010 lstrcpyA(lang, "lang");
4011 r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
4012 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4013 if (langchecksz && !langsz)
4014 {
4015 win_skip("broken MsiGetFileVersionA detected\n");
4016 HeapFree(GetProcessHeap(), 0, vercheck);
4017 HeapFree(GetProcessHeap(), 0, langcheck);
4018 return;
4019 }
4020 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4021 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4022 ok(!lstrcmpA(version, vercheck),
4023 "Expected %s, got %s\n", vercheck, version);
4024
4025 /* only check version */
4026 versz = MAX_PATH;
4027 lstrcpyA(version, "version");
4028 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4030 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4031 ok(!lstrcmpA(version, vercheck),
4032 "Expected %s, got %s\n", vercheck, version);
4033
4034 /* only check language */
4035 langsz = MAX_PATH;
4036 lstrcpyA(lang, "lang");
4037 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4038 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4039 ok(strstr(lang, langcheck) != NULL, "Expected \"%s\" in \"%s\"\n", langcheck, lang);
4040
4041 /* check neither version nor language */
4042 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4044
4045 /* get pcchVersionBuf */
4046 versz = MAX_PATH;
4047 r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
4048 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4049 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4050
4051 /* get pcchLangBuf */
4052 langsz = MAX_PATH;
4053 r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
4054 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4055 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4056
4057 /* pcchVersionBuf not big enough */
4058 versz = 5;
4059 lstrcpyA(version, "version");
4060 r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
4061 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4062 ok(!strncmp(version, vercheck, 4),
4063 "Expected first 4 characters of \"%s\", got \"%s\"\n", vercheck, version);
4064 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4065
4066 /* pcchLangBuf not big enough */
4067 langsz = 3;
4068 lstrcpyA(lang, "lang");
4069 r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
4070 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4071 ok(!strncmp(lang, langcheck, 2),
4072 "Expected first character of \"%s\", got \"%s\"\n", langcheck, lang);
4073 ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
4074
4075 /* pcchVersionBuf big enough, pcchLangBuf not big enough */
4076 versz = MAX_PATH;
4077 langsz = 0;
4078 lstrcpyA(version, "version");
4079 r = MsiGetFileVersionA(path, version, &versz, NULL, &langsz);
4080 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4081 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4082 ok(!lstrcmpA(version, vercheck), "Expected \"%s\", got \"%s\"\n", vercheck, version);
4083 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4084
4085 /* pcchVersionBuf not big enough, pcchLangBuf big enough */
4086 versz = 5;
4087 langsz = MAX_PATH;
4088 lstrcpyA(lang, "lang");
4089 r = MsiGetFileVersionA(path, NULL, &versz, lang, &langsz);
4090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4091 ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
4092 ok(langsz >= langchecksz && langsz < MAX_PATH, "Expected %d >= %d\n", langsz, langchecksz);
4093 ok(lstrcmpA(lang, "lang"), "lang buffer not modified\n");
4094
4095 /* NULL pcchVersionBuf and pcchLangBuf */
4096 r = MsiGetFileVersionA(path, version, NULL, lang, NULL);
4097 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4098
4099 /* All NULL except szFilePath */
4100 r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
4101 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4102
4103 HeapFree(GetProcessHeap(), 0, vercheck);
4104 HeapFree(GetProcessHeap(), 0, langcheck);
4105 }
4106
4107 static void test_MsiGetProductInfo(void)
4108 {
4109 UINT r;
4110 LONG res;
4111 HKEY propkey, source;
4112 HKEY prodkey, localkey;
4113 CHAR prodcode[MAX_PATH];
4114 CHAR prod_squashed[MAX_PATH];
4115 CHAR packcode[MAX_PATH];
4116 CHAR pack_squashed[MAX_PATH];
4117 CHAR buf[MAX_PATH];
4118 CHAR keypath[MAX_PATH];
4119 LPSTR usersid;
4120 DWORD sz, val = 42;
4121 REGSAM access = KEY_ALL_ACCESS;
4122
4123 create_test_guid(prodcode, prod_squashed);
4124 create_test_guid(packcode, pack_squashed);
4125 usersid = get_user_sid();
4126
4127 if (is_wow64)
4128 access |= KEY_WOW64_64KEY;
4129
4130 /* NULL szProduct */
4131 sz = MAX_PATH;
4132 lstrcpyA(buf, "apple");
4133 r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
4134 ok(r == ERROR_INVALID_PARAMETER,
4135 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4136 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4137 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4138
4139 /* empty szProduct */
4140 sz = MAX_PATH;
4141 lstrcpyA(buf, "apple");
4142 r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
4143 ok(r == ERROR_INVALID_PARAMETER,
4144 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4145 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4146 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4147
4148 /* garbage szProduct */
4149 sz = MAX_PATH;
4150 lstrcpyA(buf, "apple");
4151 r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
4152 ok(r == ERROR_INVALID_PARAMETER,
4153 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4154 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4155 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4156
4157 /* guid without brackets */
4158 sz = MAX_PATH;
4159 lstrcpyA(buf, "apple");
4160 r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
4161 INSTALLPROPERTY_HELPLINK, buf, &sz);
4162 ok(r == ERROR_INVALID_PARAMETER,
4163 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4164 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4165 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4166
4167 /* guid with brackets */
4168 sz = MAX_PATH;
4169 lstrcpyA(buf, "apple");
4170 r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
4171 INSTALLPROPERTY_HELPLINK, buf, &sz);
4172 ok(r == ERROR_UNKNOWN_PRODUCT,
4173 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4174 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4175 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4176
4177 /* same length as guid, but random */
4178 sz = MAX_PATH;
4179 lstrcpyA(buf, "apple");
4180 r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
4181 INSTALLPROPERTY_HELPLINK, buf, &sz);
4182 ok(r == ERROR_INVALID_PARAMETER,
4183 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4184 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4185 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4186
4187 /* not installed, NULL szAttribute */
4188 sz = MAX_PATH;
4189 lstrcpyA(buf, "apple");
4190 r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
4191 ok(r == ERROR_INVALID_PARAMETER,
4192 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4193 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4194 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4195
4196 /* not installed, NULL lpValueBuf */
4197 sz = MAX_PATH;
4198 lstrcpyA(buf, "apple");
4199 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
4200 ok(r == ERROR_UNKNOWN_PRODUCT,
4201 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4202 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4203 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4204
4205 /* not installed, NULL pcchValueBuf */
4206 sz = MAX_PATH;
4207 lstrcpyA(buf, "apple");
4208 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
4209 ok(r == ERROR_INVALID_PARAMETER,
4210 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4211 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4212 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4213
4214 /* created guid cannot possibly be an installed product code */
4215 sz = MAX_PATH;
4216 lstrcpyA(buf, "apple");
4217 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4218 ok(r == ERROR_UNKNOWN_PRODUCT,
4219 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4220 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4221 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4222
4223 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4224 lstrcatA(keypath, usersid);
4225 lstrcatA(keypath, "\\Installer\\Products\\");
4226 lstrcatA(keypath, prod_squashed);
4227
4228 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4229 if (res == ERROR_ACCESS_DENIED)
4230 {
4231 skip("Not enough rights to perform tests\n");
4232 LocalFree(usersid);
4233 return;
4234 }
4235 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4236
4237 /* managed product code exists */
4238 sz = MAX_PATH;
4239 lstrcpyA(buf, "apple");
4240 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4241 ok(r == ERROR_UNKNOWN_PROPERTY,
4242 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4243 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4244 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4245
4246 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4247 RegCloseKey(prodkey);
4248
4249 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4250 lstrcatA(keypath, usersid);
4251 lstrcatA(keypath, "\\Products\\");
4252 lstrcatA(keypath, prod_squashed);
4253
4254 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4255 if (res == ERROR_ACCESS_DENIED)
4256 {
4257 skip("Not enough rights to perform tests\n");
4258 LocalFree(usersid);
4259 return;
4260 }
4261 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4262
4263 /* local user product code exists */
4264 sz = MAX_PATH;
4265 lstrcpyA(buf, "apple");
4266 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4267 ok(r == ERROR_UNKNOWN_PRODUCT,
4268 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4269 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4270 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4271
4272 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4273 lstrcatA(keypath, usersid);
4274 lstrcatA(keypath, "\\Installer\\Products\\");
4275 lstrcatA(keypath, prod_squashed);
4276
4277 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4278 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4279
4280 /* both local and managed product code exist */
4281 sz = MAX_PATH;
4282 lstrcpyA(buf, "apple");
4283 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4284 ok(r == ERROR_UNKNOWN_PROPERTY,
4285 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4286 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4287 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4288
4289 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4290 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4291
4292 /* InstallProperties key exists */
4293 sz = MAX_PATH;
4294 lstrcpyA(buf, "apple");
4295 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4296 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4297 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4298 ok(sz == 0, "Expected 0, got %d\n", sz);
4299
4300 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4301 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4302
4303 /* HelpLink value exists */
4304 sz = MAX_PATH;
4305 lstrcpyA(buf, "apple");
4306 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4308 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4309 ok(sz == 4, "Expected 4, got %d\n", sz);
4310
4311 /* pcchBuf is NULL */
4312 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
4313 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4314
4315 /* lpValueBuf is NULL */
4316 sz = MAX_PATH;
4317 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
4318 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4319 ok(sz == 4, "Expected 4, got %d\n", sz);
4320
4321 /* lpValueBuf is NULL, pcchValueBuf is too small */
4322 sz = 2;
4323 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
4324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4325 ok(sz == 4, "Expected 4, got %d\n", sz);
4326
4327 /* lpValueBuf is non-NULL, pcchValueBuf is too small */
4328 sz = 2;
4329 lstrcpyA(buf, "apple");
4330 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4331 ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
4332 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4333 ok(sz == 4, "Expected 4, got %d\n", sz);
4334
4335 /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
4336 sz = 4;
4337 lstrcpyA(buf, "apple");
4338 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4339 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
4340 ok(!lstrcmpA(buf, "apple"),
4341 "Expected buf to remain unchanged, got \"%s\"\n", buf);
4342 ok(sz == 4, "Expected 4, got %d\n", sz);
4343
4344 res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
4345 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4346
4347 /* random property not supported by MSI, value exists */
4348 sz = MAX_PATH;
4349 lstrcpyA(buf, "apple");
4350 r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
4351 ok(r == ERROR_UNKNOWN_PROPERTY,
4352 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4353 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4354 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4355
4356 RegDeleteValueA(propkey, "IMadeThis");
4357 RegDeleteValueA(propkey, "HelpLink");
4358 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4359 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4360 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4361 RegCloseKey(propkey);
4362 RegCloseKey(localkey);
4363 RegCloseKey(prodkey);
4364
4365 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4366 lstrcatA(keypath, prod_squashed);
4367
4368 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4369 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4370
4371 /* user product key exists */
4372 sz = MAX_PATH;
4373 lstrcpyA(buf, "apple");
4374 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4375 ok(r == ERROR_UNKNOWN_PROPERTY,
4376 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4377 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4378 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4379
4380 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4381 lstrcatA(keypath, usersid);
4382 lstrcatA(keypath, "\\Products\\");
4383 lstrcatA(keypath, prod_squashed);
4384
4385 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4386 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4387
4388 /* local user product key exists */
4389 sz = MAX_PATH;
4390 lstrcpyA(buf, "apple");
4391 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4392 ok(r == ERROR_UNKNOWN_PROPERTY,
4393 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4394 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4395 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4396
4397 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4398 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4399
4400 /* InstallProperties key exists */
4401 sz = MAX_PATH;
4402 lstrcpyA(buf, "apple");
4403 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4404 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4405 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4406 ok(sz == 0, "Expected 0, got %d\n", sz);
4407
4408 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4410
4411 /* HelpLink value exists */
4412 sz = MAX_PATH;
4413 lstrcpyA(buf, "apple");
4414 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4415 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4416 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4417 ok(sz == 4, "Expected 4, got %d\n", sz);
4418
4419 RegDeleteValueA(propkey, "HelpLink");
4420 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4421 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4422 RegDeleteKeyA(prodkey, "");
4423 RegCloseKey(propkey);
4424 RegCloseKey(localkey);
4425 RegCloseKey(prodkey);
4426
4427 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
4428 lstrcatA(keypath, prod_squashed);
4429
4430 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4431 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4432
4433 /* classes product key exists */
4434 sz = MAX_PATH;
4435 lstrcpyA(buf, "apple");
4436 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4437 ok(r == ERROR_UNKNOWN_PROPERTY,
4438 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4439 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4440 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4441
4442 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4443 lstrcatA(keypath, usersid);
4444 lstrcatA(keypath, "\\Products\\");
4445 lstrcatA(keypath, prod_squashed);
4446
4447 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4448 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4449
4450 /* local user product key exists */
4451 sz = MAX_PATH;
4452 lstrcpyA(buf, "apple");
4453 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4454 ok(r == ERROR_UNKNOWN_PROPERTY,
4455 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4456 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4457 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4458
4459 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4460 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4461
4462 /* InstallProperties key exists */
4463 sz = MAX_PATH;
4464 lstrcpyA(buf, "apple");
4465 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4466 ok(r == ERROR_UNKNOWN_PROPERTY,
4467 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4468 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4469 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4470
4471 delete_key(propkey, "", access & KEY_WOW64_64KEY);
4472 delete_key(localkey, "", access & KEY_WOW64_64KEY);
4473 RegCloseKey(propkey);
4474 RegCloseKey(localkey);
4475
4476 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4477 lstrcatA(keypath, "S-1-5-18\\\\Products\\");
4478 lstrcatA(keypath, prod_squashed);
4479
4480 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4481 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4482
4483 /* Local System product key exists */
4484 sz = MAX_PATH;
4485 lstrcpyA(buf, "apple");
4486 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4487 ok(r == ERROR_UNKNOWN_PROPERTY,
4488 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4489 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4490 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4491
4492 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4493 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4494
4495 /* InstallProperties key exists */
4496 sz = MAX_PATH;
4497 lstrcpyA(buf, "apple");
4498 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4499 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4500 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4501 ok(sz == 0, "Expected 0, got %d\n", sz);
4502
4503 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4504 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4505
4506 /* HelpLink value exists */
4507 sz = MAX_PATH;
4508 lstrcpyA(buf, "apple");
4509 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4510 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4511 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4512 ok(sz == 4, "Expected 4, got %d\n", sz);
4513
4514 res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
4515 (const BYTE *)&val, sizeof(DWORD));
4516 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4517
4518 /* HelpLink type is REG_DWORD */
4519 sz = MAX_PATH;
4520 lstrcpyA(buf, "apple");
4521 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
4522 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4523 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4524 ok(sz == 2, "Expected 2, got %d\n", sz);
4525
4526 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4527 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4528
4529 /* DisplayName value exists */
4530 sz = MAX_PATH;
4531 lstrcpyA(buf, "apple");
4532 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4533 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4534 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4535 ok(sz == 4, "Expected 4, got %d\n", sz);
4536
4537 res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
4538 (const BYTE *)&val, sizeof(DWORD));
4539 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4540
4541 /* DisplayName type is REG_DWORD */
4542 sz = MAX_PATH;
4543 lstrcpyA(buf, "apple");
4544 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4545 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4546 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4547 ok(sz == 2, "Expected 2, got %d\n", sz);
4548
4549 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
4550 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4551
4552 /* DisplayVersion value exists */
4553 sz = MAX_PATH;
4554 lstrcpyA(buf, "apple");
4555 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4557 ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
4558 ok(sz == 5, "Expected 5, got %d\n", sz);
4559
4560 res = RegSetValueExA(propkey, "DisplayVersion", 0,
4561 REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
4562 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4563
4564 /* DisplayVersion type is REG_DWORD */
4565 sz = MAX_PATH;
4566 lstrcpyA(buf, "apple");
4567 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4568 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4569 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4570 ok(sz == 2, "Expected 2, got %d\n", sz);
4571
4572 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
4573 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4574
4575 /* HelpTelephone value exists */
4576 sz = MAX_PATH;
4577 lstrcpyA(buf, "apple");
4578 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4579 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4580 ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
4581 ok(sz == 4, "Expected 4, got %d\n", sz);
4582
4583 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
4584 (const BYTE *)&val, sizeof(DWORD));
4585 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4586
4587 /* HelpTelephone type is REG_DWORD */
4588 sz = MAX_PATH;
4589 lstrcpyA(buf, "apple");
4590 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4591 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4592 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4593 ok(sz == 2, "Expected 2, got %d\n", sz);
4594
4595 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4596 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4597
4598 /* InstallLocation value exists */
4599 sz = MAX_PATH;
4600 lstrcpyA(buf, "apple");
4601 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4602 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4603 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4604 ok(sz == 3, "Expected 3, got %d\n", sz);
4605
4606 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
4607 (const BYTE *)&val, sizeof(DWORD));
4608 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4609
4610 /* InstallLocation type is REG_DWORD */
4611 sz = MAX_PATH;
4612 lstrcpyA(buf, "apple");
4613 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4614 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4615 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4616 ok(sz == 2, "Expected 2, got %d\n", sz);
4617
4618 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4619 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4620
4621 /* InstallSource value exists */
4622 sz = MAX_PATH;
4623 lstrcpyA(buf, "apple");
4624 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4625 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4626 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4627 ok(sz == 6, "Expected 6, got %d\n", sz);
4628
4629 res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
4630 (const BYTE *)&val, sizeof(DWORD));
4631 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4632
4633 /* InstallSource type is REG_DWORD */
4634 sz = MAX_PATH;
4635 lstrcpyA(buf, "apple");
4636 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4637 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4638 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4639 ok(sz == 2, "Expected 2, got %d\n", sz);
4640
4641 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4642 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4643
4644 /* InstallDate value exists */
4645 sz = MAX_PATH;
4646 lstrcpyA(buf, "apple");
4647 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4648 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4649 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4650 ok(sz == 4, "Expected 4, got %d\n", sz);
4651
4652 res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
4653 (const BYTE *)&val, sizeof(DWORD));
4654 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4655
4656 /* InstallDate type is REG_DWORD */
4657 sz = MAX_PATH;
4658 lstrcpyA(buf, "apple");
4659 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4660 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4661 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4662 ok(sz == 2, "Expected 2, got %d\n", sz);
4663
4664 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4666
4667 /* Publisher value exists */
4668 sz = MAX_PATH;
4669 lstrcpyA(buf, "apple");
4670 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
4671 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4672 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4673 ok(sz == 3, "Expected 3, got %d\n", sz);
4674
4675 res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
4676 (const BYTE *)&val, sizeof(DWORD));
4677 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4678
4679 /* Publisher type is REG_DWORD */
4680 sz = MAX_PATH;
4681 lstrcpyA(buf, "apple");
4682 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
4683 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4684 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4685 ok(sz == 2, "Expected 2, got %d\n", sz);
4686
4687 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
4688 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4689
4690 /* LocalPackage value exists */
4691 sz = MAX_PATH;
4692 lstrcpyA(buf, "apple");
4693 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4694 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4695 ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
4696 ok(sz == 4, "Expected 4, got %d\n", sz);
4697
4698 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
4699 (const BYTE *)&val, sizeof(DWORD));
4700 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4701
4702 /* LocalPackage type is REG_DWORD */
4703 sz = MAX_PATH;
4704 lstrcpyA(buf, "apple");
4705 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4706 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4707 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4708 ok(sz == 2, "Expected 2, got %d\n", sz);
4709
4710 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4711 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4712
4713 /* UrlInfoAbout value exists */
4714 sz = MAX_PATH;
4715 lstrcpyA(buf, "apple");
4716 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4717 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4718 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4719 ok(sz == 5, "Expected 5, got %d\n", sz);
4720
4721 res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
4722 (const BYTE *)&val, sizeof(DWORD));
4723 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4724
4725 /* UrlInfoAbout type is REG_DWORD */
4726 sz = MAX_PATH;
4727 lstrcpyA(buf, "apple");
4728 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4730 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4731 ok(sz == 2, "Expected 2, got %d\n", sz);
4732
4733 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
4734 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4735
4736 /* UrlUpdateInfo value exists */
4737 sz = MAX_PATH;
4738 lstrcpyA(buf, "apple");
4739 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4740 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4741 ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
4742 ok(sz == 4, "Expected 4, got %d\n", sz);
4743
4744 res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
4745 (const BYTE *)&val, sizeof(DWORD));
4746 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4747
4748 /* UrlUpdateInfo type is REG_DWORD */
4749 sz = MAX_PATH;
4750 lstrcpyA(buf, "apple");
4751 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4752 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4753 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4754 ok(sz == 2, "Expected 2, got %d\n", sz);
4755
4756 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
4757 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4758
4759 /* VersionMinor value exists */
4760 sz = MAX_PATH;
4761 lstrcpyA(buf, "apple");
4762 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4763 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4764 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4765 ok(sz == 1, "Expected 1, got %d\n", sz);
4766
4767 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
4768 (const BYTE *)&val, sizeof(DWORD));
4769 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4770
4771 /* VersionMinor type is REG_DWORD */
4772 sz = MAX_PATH;
4773 lstrcpyA(buf, "apple");
4774 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4775 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4776 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4777 ok(sz == 2, "Expected 2, got %d\n", sz);
4778
4779 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
4780 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4781
4782 /* VersionMajor value exists */
4783 sz = MAX_PATH;
4784 lstrcpyA(buf, "apple");
4785 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4786 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4787 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4788 ok(sz == 1, "Expected 1, got %d\n", sz);
4789
4790 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
4791 (const BYTE *)&val, sizeof(DWORD));
4792 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4793
4794 /* VersionMajor type is REG_DWORD */
4795 sz = MAX_PATH;
4796 lstrcpyA(buf, "apple");
4797 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4798 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4799 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4800 ok(sz == 2, "Expected 2, got %d\n", sz);
4801
4802 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4803 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4804
4805 /* ProductID value exists */
4806 sz = MAX_PATH;
4807 lstrcpyA(buf, "apple");
4808 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
4809 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4810 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4811 ok(sz == 2, "Expected 2, got %d\n", sz);
4812
4813 res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
4814 (const BYTE *)&val, sizeof(DWORD));
4815 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4816
4817 /* ProductID type is REG_DWORD */
4818 sz = MAX_PATH;
4819 lstrcpyA(buf, "apple");
4820 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
4821 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4822 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4823 ok(sz == 2, "Expected 2, got %d\n", sz);
4824
4825 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4826 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4827
4828 /* RegCompany value exists */
4829 sz = MAX_PATH;
4830 lstrcpyA(buf, "apple");
4831 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4832 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4833 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4834 ok(sz == 4, "Expected 4, got %d\n", sz);
4835
4836 res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
4837 (const BYTE *)&val, sizeof(DWORD));
4838 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4839
4840 /* RegCompany type is REG_DWORD */
4841 sz = MAX_PATH;
4842 lstrcpyA(buf, "apple");
4843 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4844 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4845 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4846 ok(sz == 2, "Expected 2, got %d\n", sz);
4847
4848 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
4849 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4850
4851 /* RegOwner value exists */
4852 sz = MAX_PATH;
4853 lstrcpyA(buf, "apple");
4854 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
4855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4856 ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
4857 ok(sz == 3, "Expected 3, got %d\n", sz);
4858
4859 res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
4860 (const BYTE *)&val, sizeof(DWORD));
4861 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4862
4863 /* RegOwner type is REG_DWORD */
4864 sz = MAX_PATH;
4865 lstrcpyA(buf, "apple");
4866 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
4867 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4868 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4869 ok(sz == 2, "Expected 2, got %d\n", sz);
4870
4871 res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
4872 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4873
4874 /* InstanceType value exists */
4875 sz = MAX_PATH;
4876 lstrcpyA(buf, "apple");
4877 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
4878 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4879 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4880 ok(sz == 0, "Expected 0, got %d\n", sz);
4881
4882 res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
4883 (const BYTE *)&val, sizeof(DWORD));
4884 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4885
4886 /* InstanceType type is REG_DWORD */
4887 sz = MAX_PATH;
4888 lstrcpyA(buf, "apple");
4889 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
4890 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4891 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4892 ok(sz == 0, "Expected 0, got %d\n", sz);
4893
4894 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
4895 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4896
4897 /* InstanceType value exists */
4898 sz = MAX_PATH;
4899 lstrcpyA(buf, "apple");
4900 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
4901 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4902 ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
4903 ok(sz == 4, "Expected 4, got %d\n", sz);
4904
4905 res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
4906 (const BYTE *)&val, sizeof(DWORD));
4907 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4908
4909 /* InstanceType type is REG_DWORD */
4910 sz = MAX_PATH;
4911 lstrcpyA(buf, "apple");
4912 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
4913 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4914 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4915 ok(sz == 2, "Expected 2, got %d\n", sz);
4916
4917 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
4918 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4919
4920 /* Transforms value exists */
4921 sz = MAX_PATH;
4922 lstrcpyA(buf, "apple");
4923 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4924 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4925 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4926 ok(sz == 0, "Expected 0, got %d\n", sz);
4927
4928 res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
4929 (const BYTE *)&val, sizeof(DWORD));
4930 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4931
4932 /* Transforms type is REG_DWORD */
4933 sz = MAX_PATH;
4934 lstrcpyA(buf, "apple");
4935 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4936 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4937 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4938 ok(sz == 0, "Expected 0, got %d\n", sz);
4939
4940 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
4941 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4942
4943 /* Transforms value exists */
4944 sz = MAX_PATH;
4945 lstrcpyA(buf, "apple");
4946 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4947 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4948 ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
4949 ok(sz == 6, "Expected 6, got %d\n", sz);
4950
4951 res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
4952 (const BYTE *)&val, sizeof(DWORD));
4953 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4954
4955 /* Transforms type is REG_DWORD */
4956 sz = MAX_PATH;
4957 lstrcpyA(buf, "apple");
4958 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4959 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4960 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4961 ok(sz == 2, "Expected 2, got %d\n", sz);
4962
4963 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4964 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4965
4966 /* Language value exists */
4967 sz = MAX_PATH;
4968 lstrcpyA(buf, "apple");
4969 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
4970 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4971 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4972 ok(sz == 0, "Expected 0, got %d\n", sz);
4973
4974 res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
4975 (const BYTE *)&val, sizeof(DWORD));
4976 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4977
4978 /* Language type is REG_DWORD */
4979 sz = MAX_PATH;
4980 lstrcpyA(buf, "apple");
4981 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
4982 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4983 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4984 ok(sz == 0, "Expected 0, got %d\n", sz);
4985
4986 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4987 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4988
4989 /* Language value exists */
4990 sz = MAX_PATH;
4991 lstrcpyA(buf, "apple");
4992 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
4993 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4994 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4995 ok(sz == 4, "Expected 4, got %d\n", sz);
4996
4997 res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
4998 (const BYTE *)&val, sizeof(DWORD));
4999 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5000
5001 /* Language type is REG_DWORD */
5002 sz = MAX_PATH;
5003 lstrcpyA(buf, "apple");
5004 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
5005 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5006 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5007 ok(sz == 2, "Expected 2, got %d\n", sz);
5008
5009 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5010 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5011
5012 /* ProductName value exists */
5013 sz = MAX_PATH;
5014 lstrcpyA(buf, "apple");
5015 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5016 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5017 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5018 ok(sz == 0, "Expected 0, got %d\n", sz);
5019
5020 res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
5021 (const BYTE *)&val, sizeof(DWORD));
5022 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5023
5024 /* ProductName type is REG_DWORD */
5025 sz = MAX_PATH;
5026 lstrcpyA(buf, "apple");
5027 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5028 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5029 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5030 ok(sz == 0, "Expected 0, got %d\n", sz);
5031
5032 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5033 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5034
5035 /* ProductName value exists */
5036 sz = MAX_PATH;
5037 lstrcpyA(buf, "apple");
5038 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5039 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5040 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5041 ok(sz == 4, "Expected 4, got %d\n", sz);
5042
5043 res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
5044 (const BYTE *)&val, sizeof(DWORD));
5045 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5046
5047 /* ProductName type is REG_DWORD */
5048 sz = MAX_PATH;
5049 lstrcpyA(buf, "apple");
5050 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5051 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5052 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5053 ok(sz == 2, "Expected 2, got %d\n", sz);
5054
5055 res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5056 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5057
5058 /* Assignment value exists */
5059 sz = MAX_PATH;
5060 lstrcpyA(buf, "apple");
5061 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5062 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5063 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5064 ok(sz == 0, "Expected 0, got %d\n", sz);
5065
5066 res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
5067 (const BYTE *)&val, sizeof(DWORD));
5068 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5069
5070 /* Assignment type is REG_DWORD */
5071 sz = MAX_PATH;
5072 lstrcpyA(buf, "apple");
5073 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5074 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5075 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5076 ok(sz == 0, "Expected 0, got %d\n", sz);
5077
5078 res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
5079 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5080
5081 /* Assignment value exists */
5082 sz = MAX_PATH;
5083 lstrcpyA(buf, "apple");
5084 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5086 ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
5087 ok(sz == 2, "Expected 2, got %d\n", sz);
5088
5089 res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
5090 (const BYTE *)&val, sizeof(DWORD));
5091 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5092
5093 /* Assignment type is REG_DWORD */
5094 sz = MAX_PATH;
5095 lstrcpyA(buf, "apple");
5096 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5097 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5098 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5099 ok(sz == 2, "Expected 2, got %d\n", sz);
5100
5101 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5102 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5103
5104 /* PackageCode value exists */
5105 sz = MAX_PATH;
5106 lstrcpyA(buf, "apple");
5107 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5108 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5109 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5110 ok(sz == 0, "Expected 0, got %d\n", sz);
5111
5112 res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
5113 (const BYTE *)&val, sizeof(DWORD));
5114 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5115
5116 /* PackageCode type is REG_DWORD */
5117 sz = MAX_PATH;
5118 lstrcpyA(buf, "apple");
5119 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5121 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5122 ok(sz == 0, "Expected 0, got %d\n", sz);
5123
5124 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5125 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5126
5127 /* PackageCode value exists */
5128 sz = MAX_PATH;
5129 lstrcpyA(buf, "apple");
5130 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5131 ok(r == ERROR_BAD_CONFIGURATION,
5132 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5133 ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
5134 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5135
5136 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
5137 (const BYTE *)&val, sizeof(DWORD));
5138 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5139
5140 /* PackageCode type is REG_DWORD */
5141 sz = MAX_PATH;
5142 lstrcpyA(buf, "apple");
5143 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5144 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5145 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5146 ok(sz == 2, "Expected 2, got %d\n", sz);
5147
5148 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
5149 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5150
5151 /* PackageCode value exists */
5152 sz = MAX_PATH;
5153 lstrcpyA(buf, "apple");
5154 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5155 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5156 ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
5157 ok(sz == 38, "Expected 38, got %d\n", sz);
5158
5159 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5160 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5161
5162 /* Version value exists */
5163 sz = MAX_PATH;
5164 lstrcpyA(buf, "apple");
5165 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
5166 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5167 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5168 ok(sz == 0, "Expected 0, got %d\n", sz);
5169
5170 res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
5171 (const BYTE *)&val, sizeof(DWORD));
5172 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5173
5174 /* Version type is REG_DWORD */
5175 sz = MAX_PATH;
5176 lstrcpyA(buf, "apple");
5177 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
5178 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5179 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5180 ok(sz == 0, "Expected 0, got %d\n", sz);
5181
5182 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5183 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5184
5185 /* Version value exists */
5186 sz = MAX_PATH;
5187 lstrcpyA(buf, "apple");
5188 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
5189 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5190 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5191 ok(sz == 3, "Expected 3, got %d\n", sz);
5192
5193 res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
5194 (const BYTE *)&val, sizeof(DWORD));
5195 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5196
5197 /* Version type is REG_DWORD */
5198 sz = MAX_PATH;
5199 lstrcpyA(buf, "apple");
5200 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
5201 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5202 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5203 ok(sz == 2, "Expected 2, got %d\n", sz);
5204
5205 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5206 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5207
5208 /* ProductIcon value exists */
5209 sz = MAX_PATH;
5210 lstrcpyA(buf, "apple");
5211 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5212 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5213 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5214 ok(sz == 0, "Expected 0, got %d\n", sz);
5215
5216 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
5217 (const BYTE *)&val, sizeof(DWORD));
5218 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5219
5220 /* ProductIcon type is REG_DWORD */
5221 sz = MAX_PATH;
5222 lstrcpyA(buf, "apple");
5223 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5224 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5225 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5226 ok(sz == 0, "Expected 0, got %d\n", sz);
5227
5228 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
5229 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5230
5231 /* ProductIcon value exists */
5232 sz = MAX_PATH;
5233 lstrcpyA(buf, "apple");
5234 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5235 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5236 ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
5237 ok(sz == 3, "Expected 3, got %d\n", sz);
5238
5239 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
5240 (const BYTE *)&val, sizeof(DWORD));
5241 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5242
5243 /* ProductIcon type is REG_DWORD */
5244 sz = MAX_PATH;
5245 lstrcpyA(buf, "apple");
5246 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5247 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5248 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5249 ok(sz == 2, "Expected 2, got %d\n", sz);
5250
5251 /* SourceList key does not exist */
5252 sz = MAX_PATH;
5253 lstrcpyA(buf, "apple");
5254 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5255 ok(r == ERROR_UNKNOWN_PRODUCT,
5256 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5257 ok(!lstrcmpA(buf, "apple"),
5258 "Expected buf to be unchanged, got \"%s\"\n", buf);
5259 ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
5260
5261 res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
5262 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5263
5264 /* SourceList key exists, but PackageName val does not exist */
5265 sz = MAX_PATH;
5266 lstrcpyA(buf, "apple");
5267 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5268 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5269 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5270 ok(sz == 0, "Expected 0, got %d\n", sz);
5271
5272 res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
5273 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5274
5275 /* PackageName val exists */
5276 sz = MAX_PATH;
5277 lstrcpyA(buf, "apple");
5278 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5279 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5280 ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
5281 ok(sz == 8, "Expected 8, got %d\n", sz);
5282
5283 res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
5284 (const BYTE *)&val, sizeof(DWORD));
5285 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5286
5287 /* PackageName type is REG_DWORD */
5288 sz = MAX_PATH;
5289 lstrcpyA(buf, "apple");
5290 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5291 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5292 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5293 ok(sz == 2, "Expected 2, got %d\n", sz);
5294
5295 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5297
5298 /* Authorized value exists */
5299 sz = MAX_PATH;
5300 lstrcpyA(buf, "apple");
5301 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5302 if (r != ERROR_UNKNOWN_PROPERTY)
5303 {
5304 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5305 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5306 ok(sz == 0, "Expected 0, got %d\n", sz);
5307 }
5308
5309 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
5310 (const BYTE *)&val, sizeof(DWORD));
5311 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5312
5313 /* AuthorizedLUAApp type is REG_DWORD */
5314 sz = MAX_PATH;
5315 lstrcpyA(buf, "apple");
5316 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5317 if (r != ERROR_UNKNOWN_PROPERTY)
5318 {
5319 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5320 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5321 ok(sz == 0, "Expected 0, got %d\n", sz);
5322 }
5323
5324 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5325 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5326
5327 /* Authorized value exists */
5328 sz = MAX_PATH;
5329 lstrcpyA(buf, "apple");
5330 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5331 if (r != ERROR_UNKNOWN_PROPERTY)
5332 {
5333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5334 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5335 ok(sz == 4, "Expected 4, got %d\n", sz);
5336 }
5337
5338 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
5339 (const BYTE *)&val, sizeof(DWORD));
5340 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5341
5342 /* AuthorizedLUAApp type is REG_DWORD */
5343 sz = MAX_PATH;
5344 lstrcpyA(buf, "apple");
5345 r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5346 if (r != ERROR_UNKNOWN_PROPERTY)
5347 {
5348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5349 ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
5350 ok(sz == 2, "Expected 2, got %d\n", sz);
5351 }
5352
5353 RegDeleteValueA(propkey, "HelpLink");
5354 RegDeleteValueA(propkey, "DisplayName");
5355 RegDeleteValueA(propkey, "DisplayVersion");
5356 RegDeleteValueA(propkey, "HelpTelephone");
5357 RegDeleteValueA(propkey, "InstallLocation");
5358 RegDeleteValueA(propkey, "InstallSource");
5359 RegDeleteValueA(propkey, "InstallDate");
5360 RegDeleteValueA(propkey, "Publisher");
5361 RegDeleteValueA(propkey, "LocalPackage");
5362 RegDeleteValueA(propkey, "UrlInfoAbout");
5363 RegDeleteValueA(propkey, "UrlUpdateInfo");
5364 RegDeleteValueA(propkey, "VersionMinor");
5365 RegDeleteValueA(propkey, "VersionMajor");
5366 RegDeleteValueA(propkey, "ProductID");
5367 RegDeleteValueA(propkey, "RegCompany");
5368 RegDeleteValueA(propkey, "RegOwner");
5369 RegDeleteValueA(propkey, "InstanceType");
5370 RegDeleteValueA(propkey, "Transforms");
5371 RegDeleteValueA(propkey, "Language");
5372 RegDeleteValueA(propkey, "ProductName");
5373 RegDeleteValueA(propkey, "Assignment");
5374 RegDeleteValueA(propkey, "PackageCode");
5375 RegDeleteValueA(propkey, "Version");
5376 RegDeleteValueA(propkey, "ProductIcon");
5377 RegDeleteValueA(propkey, "AuthorizedLUAApp");
5378 delete_key(propkey, "", access & KEY_WOW64_64KEY);
5379 delete_key(localkey, "", access & KEY_WOW64_64KEY);
5380 RegDeleteValueA(prodkey, "InstanceType");
5381 RegDeleteValueA(prodkey, "Transforms");
5382 RegDeleteValueA(prodkey, "Language");
5383 RegDeleteValueA(prodkey, "ProductName");
5384 RegDeleteValueA(prodkey, "Assignment");
5385 RegDeleteValueA(prodkey, "PackageCode");
5386 RegDeleteValueA(prodkey, "Version");
5387 RegDeleteValueA(prodkey, "ProductIcon");
5388 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5389 RegDeleteValueA(source, "PackageName");
5390 delete_key(source, "", access & KEY_WOW64_64KEY);
5391 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5392 RegCloseKey(propkey);
5393 RegCloseKey(localkey);
5394 RegCloseKey(source);
5395 RegCloseKey(prodkey);
5396 LocalFree(usersid);
5397 }
5398
5399 static void test_MsiGetProductInfoEx(void)
5400 {
5401 UINT r;
5402 LONG res;
5403 HKEY propkey, userkey;
5404 HKEY prodkey, localkey;
5405 CHAR prodcode[MAX_PATH];
5406 CHAR prod_squashed[MAX_PATH];
5407 CHAR packcode[MAX_PATH];
5408 CHAR pack_squashed[MAX_PATH];
5409 CHAR buf[MAX_PATH];
5410 CHAR keypath[MAX_PATH];
5411 LPSTR usersid;
5412 DWORD sz;
5413 REGSAM access = KEY_ALL_ACCESS;
5414
5415 if (!pMsiGetProductInfoExA)
5416 {
5417 win_skip("MsiGetProductInfoExA is not available\n");
5418 return;
5419 }
5420
5421 create_test_guid(prodcode, prod_squashed);
5422 create_test_guid(packcode, pack_squashed);
5423 usersid = get_user_sid();
5424
5425 if (is_wow64)
5426 access |= KEY_WOW64_64KEY;
5427
5428 /* NULL szProductCode */
5429 sz = MAX_PATH;
5430 lstrcpyA(buf, "apple");
5431 r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5432 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5433 ok(r == ERROR_INVALID_PARAMETER,
5434 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5435 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5436 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5437
5438 /* empty szProductCode */
5439 sz = MAX_PATH;
5440 lstrcpyA(buf, "apple");
5441 r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5442 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5443 ok(r == ERROR_INVALID_PARAMETER,
5444 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5445 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5446 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5447
5448 /* garbage szProductCode */
5449 sz = MAX_PATH;
5450 lstrcpyA(buf, "apple");
5451 r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
5452 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5453 ok(r == ERROR_INVALID_PARAMETER,
5454 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5455 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5456 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5457
5458 /* guid without brackets */
5459 sz = MAX_PATH;
5460 lstrcpyA(buf, "apple");
5461 r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
5462 MSIINSTALLCONTEXT_USERUNMANAGED,
5463 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5464 ok(r == ERROR_INVALID_PARAMETER,
5465 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5466 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5467 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5468
5469 /* guid with brackets */
5470 sz = MAX_PATH;
5471 lstrcpyA(buf, "apple");
5472 r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
5473 MSIINSTALLCONTEXT_USERUNMANAGED,
5474 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5475 ok(r == ERROR_UNKNOWN_PRODUCT,
5476 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5477 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5478 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5479
5480 /* szValue is non-NULL while pcchValue is NULL */
5481 lstrcpyA(buf, "apple");
5482 r = pMsiGetProductInfoExA(prodcode, usersid,
5483 MSIINSTALLCONTEXT_USERUNMANAGED,
5484 INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
5485 ok(r == ERROR_INVALID_PARAMETER,
5486 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5487 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5488
5489 /* dwContext is out of range */
5490 sz = MAX_PATH;
5491 lstrcpyA(buf, "apple");
5492 r = pMsiGetProductInfoExA(prodcode, usersid, 42,
5493 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5494 ok(r == ERROR_INVALID_PARAMETER,
5495 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5496 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5497 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5498
5499 /* szProperty is NULL */
5500 sz = MAX_PATH;
5501 lstrcpyA(buf, "apple");
5502 r = pMsiGetProductInfoExA(prodcode, usersid,
5503 MSIINSTALLCONTEXT_USERUNMANAGED,
5504 NULL, buf, &sz);
5505 ok(r == ERROR_INVALID_PARAMETER,
5506 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5507 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5508 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5509
5510 /* szProperty is empty */
5511 sz = MAX_PATH;
5512 lstrcpyA(buf, "apple");
5513 r = pMsiGetProductInfoExA(prodcode, usersid,
5514 MSIINSTALLCONTEXT_USERUNMANAGED,
5515 "", buf, &sz);
5516 ok(r == ERROR_INVALID_PARAMETER,
5517 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5518 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5519 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5520
5521 /* szProperty is not a valid property */
5522 sz = MAX_PATH;
5523 lstrcpyA(buf, "apple");
5524 r = pMsiGetProductInfoExA(prodcode, usersid,
5525 MSIINSTALLCONTEXT_USERUNMANAGED,
5526 "notvalid", buf, &sz);
5527 ok(r == ERROR_UNKNOWN_PRODUCT,
5528 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5529 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5530 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5531
5532 /* same length as guid, but random */
5533 sz = MAX_PATH;
5534 lstrcpyA(buf, "apple");
5535 r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
5536 MSIINSTALLCONTEXT_USERUNMANAGED,
5537 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5538 ok(r == ERROR_INVALID_PARAMETER,
5539 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5540 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5541 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5542
5543 /* MSIINSTALLCONTEXT_USERUNMANAGED */
5544
5545 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5546 lstrcatA(keypath, usersid);
5547 lstrcatA(keypath, "\\Products\\");
5548 lstrcatA(keypath, prod_squashed);
5549
5550 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5551 if (res == ERROR_ACCESS_DENIED)
5552 {
5553 skip("Not enough rights to perform tests\n");
5554 LocalFree(usersid);
5555 return;
5556 }
5557 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5558
5559 /* local user product key exists */
5560 sz = MAX_PATH;
5561 lstrcpyA(buf, "apple");
5562 r = pMsiGetProductInfoExA(prodcode, usersid,
5563 MSIINSTALLCONTEXT_USERUNMANAGED,
5564 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5565 ok(r == ERROR_UNKNOWN_PRODUCT,
5566 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5567 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5568 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5569
5570 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5571 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5572
5573 /* InstallProperties key exists */
5574 sz = MAX_PATH;
5575 lstrcpyA(buf, "apple");
5576 r = pMsiGetProductInfoExA(prodcode, usersid,
5577 MSIINSTALLCONTEXT_USERUNMANAGED,
5578 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5579 ok(r == ERROR_UNKNOWN_PRODUCT,
5580 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5581 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5582 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5583
5584 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5585 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5586
5587 /* LocalPackage value exists */
5588 sz = MAX_PATH;
5589 lstrcpyA(buf, "apple");
5590 r = pMsiGetProductInfoExA(prodcode, usersid,
5591 MSIINSTALLCONTEXT_USERUNMANAGED,
5592 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5593 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5594 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5595 ok(sz == 1, "Expected 1, got %d\n", sz);
5596
5597 RegDeleteValueA(propkey, "LocalPackage");
5598
5599 /* LocalPackage value must exist */
5600 sz = MAX_PATH;
5601 lstrcpyA(buf, "apple");
5602 r = pMsiGetProductInfoExA(prodcode, usersid,
5603 MSIINSTALLCONTEXT_USERUNMANAGED,
5604 INSTALLPROPERTY_HELPLINK, buf, &sz);
5605 ok(r == ERROR_UNKNOWN_PRODUCT,
5606 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5607 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5608 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5609
5610 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5611 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5612
5613 /* LocalPackage exists, but HelpLink does not exist */
5614 sz = MAX_PATH;
5615 lstrcpyA(buf, "apple");
5616 r = pMsiGetProductInfoExA(prodcode, usersid,
5617 MSIINSTALLCONTEXT_USERUNMANAGED,
5618 INSTALLPROPERTY_HELPLINK, buf, &sz);
5619 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5620 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5621 ok(sz == 0, "Expected 0, got %d\n", sz);
5622
5623 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5624 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5625
5626 /* HelpLink value exists */
5627 sz = MAX_PATH;
5628 lstrcpyA(buf, "apple");
5629 r = pMsiGetProductInfoExA(prodcode, usersid,
5630 MSIINSTALLCONTEXT_USERUNMANAGED,
5631 INSTALLPROPERTY_HELPLINK, buf, &sz);
5632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5633 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5634 ok(sz == 4, "Expected 4, got %d\n", sz);
5635
5636 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5637 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5638
5639 /* HelpTelephone value exists */
5640 sz = MAX_PATH;
5641 lstrcpyA(buf, "apple");
5642 r = pMsiGetProductInfoExA(prodcode, usersid,
5643 MSIINSTALLCONTEXT_USERUNMANAGED,
5644 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5645 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5646 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5647 ok(sz == 5, "Expected 5, got %d\n", sz);
5648
5649 /* szValue and pcchValue are NULL */
5650 r = pMsiGetProductInfoExA(prodcode, usersid,
5651 MSIINSTALLCONTEXT_USERUNMANAGED,
5652 INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
5653 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5654
5655 /* pcchValue is exactly 5 */
5656 sz = 5;
5657 lstrcpyA(buf, "apple");
5658 r = pMsiGetProductInfoExA(prodcode, usersid,
5659 MSIINSTALLCONTEXT_USERUNMANAGED,
5660 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5661 ok(r == ERROR_MORE_DATA,
5662 "Expected ERROR_MORE_DATA, got %d\n", r);
5663 ok(sz == 10, "Expected 10, got %d\n", sz);
5664
5665 /* szValue is NULL, pcchValue is exactly 5 */
5666 sz = 5;
5667 r = pMsiGetProductInfoExA(prodcode, usersid,
5668 MSIINSTALLCONTEXT_USERUNMANAGED,
5669 INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
5670 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5671 ok(sz == 10, "Expected 10, got %d\n", sz);
5672
5673 /* szValue is NULL, pcchValue is MAX_PATH */
5674 sz = MAX_PATH;
5675 r = pMsiGetProductInfoExA(prodcode, usersid,
5676 MSIINSTALLCONTEXT_USERUNMANAGED,
5677 INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
5678 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5679 ok(sz == 10, "Expected 10, got %d\n", sz);
5680
5681 /* pcchValue is exactly 0 */
5682 sz = 0;
5683 lstrcpyA(buf, "apple");
5684 r = pMsiGetProductInfoExA(prodcode, usersid,
5685 MSIINSTALLCONTEXT_USERUNMANAGED,
5686 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5687 ok(r == ERROR_MORE_DATA,
5688 "Expected ERROR_MORE_DATA, got %d\n", r);
5689 ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
5690 ok(sz == 10, "Expected 10, got %d\n", sz);
5691
5692 res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
5693 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5694
5695 /* szProperty is not a valid property */
5696 sz = MAX_PATH;
5697 lstrcpyA(buf, "apple");
5698 r = pMsiGetProductInfoExA(prodcode, usersid,
5699 MSIINSTALLCONTEXT_USERUNMANAGED,
5700 "notvalid", buf, &sz);
5701 ok(r == ERROR_UNKNOWN_PROPERTY,
5702 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5703 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5704 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5705
5706 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5707 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5708
5709 /* InstallDate value exists */
5710 sz = MAX_PATH;
5711 lstrcpyA(buf, "apple");
5712 r = pMsiGetProductInfoExA(prodcode, usersid,
5713 MSIINSTALLCONTEXT_USERUNMANAGED,
5714 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5715 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5716 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5717 ok(sz == 4, "Expected 4, got %d\n", sz);
5718
5719 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5720 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5721
5722 /* DisplayName value exists */
5723 sz = MAX_PATH;
5724 lstrcpyA(buf, "apple");
5725 r = pMsiGetProductInfoExA(prodcode, usersid,
5726 MSIINSTALLCONTEXT_USERUNMANAGED,
5727 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5728 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5729 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5730 ok(sz == 4, "Expected 4, got %d\n", sz);
5731
5732 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5733 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5734
5735 /* InstallLocation value exists */
5736 sz = MAX_PATH;
5737 lstrcpyA(buf, "apple");
5738 r = pMsiGetProductInfoExA(prodcode, usersid,
5739 MSIINSTALLCONTEXT_USERUNMANAGED,
5740 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5741 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5742 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5743 ok(sz == 3, "Expected 3, got %d\n", sz);
5744
5745 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5746 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5747
5748 /* InstallSource value exists */
5749 sz = MAX_PATH;
5750 lstrcpyA(buf, "apple");
5751 r = pMsiGetProductInfoExA(prodcode, usersid,
5752 MSIINSTALLCONTEXT_USERUNMANAGED,
5753 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5754 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5755 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5756 ok(sz == 6, "Expected 6, got %d\n", sz);
5757
5758 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5759 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5760
5761 /* LocalPackage value exists */
5762 sz = MAX_PATH;
5763 lstrcpyA(buf, "apple");
5764 r = pMsiGetProductInfoExA(prodcode, usersid,
5765 MSIINSTALLCONTEXT_USERUNMANAGED,
5766 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5767 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5768 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5769 ok(sz == 5, "Expected 5, got %d\n", sz);
5770
5771 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5772 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5773
5774 /* Publisher value exists */
5775 sz = MAX_PATH;
5776 lstrcpyA(buf, "apple");
5777 r = pMsiGetProductInfoExA(prodcode, usersid,
5778 MSIINSTALLCONTEXT_USERUNMANAGED,
5779 INSTALLPROPERTY_PUBLISHER, buf, &sz);
5780 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5781 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5782 ok(sz == 3, "Expected 3, got %d\n", sz);
5783
5784 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5785 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5786
5787 /* URLInfoAbout value exists */
5788 sz = MAX_PATH;
5789 lstrcpyA(buf, "apple");
5790 r = pMsiGetProductInfoExA(prodcode, usersid,
5791 MSIINSTALLCONTEXT_USERUNMANAGED,
5792 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5793 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5794 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5795 ok(sz == 5, "Expected 5, got %d\n", sz);
5796
5797 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5798 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5799
5800 /* URLUpdateInfo value exists */
5801 sz = MAX_PATH;
5802 lstrcpyA(buf, "apple");
5803 r = pMsiGetProductInfoExA(prodcode, usersid,
5804 MSIINSTALLCONTEXT_USERUNMANAGED,
5805 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5806 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5807 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5808 ok(sz == 6, "Expected 6, got %d\n", sz);
5809
5810 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5811 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5812
5813 /* VersionMinor value exists */
5814 sz = MAX_PATH;
5815 lstrcpyA(buf, "apple");
5816 r = pMsiGetProductInfoExA(prodcode, usersid,
5817 MSIINSTALLCONTEXT_USERUNMANAGED,
5818 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5819 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5820 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5821 ok(sz == 1, "Expected 1, got %d\n", sz);
5822
5823 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5824 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5825
5826 /* VersionMajor value exists */
5827 sz = MAX_PATH;
5828 lstrcpyA(buf, "apple");
5829 r = pMsiGetProductInfoExA(prodcode, usersid,
5830 MSIINSTALLCONTEXT_USERUNMANAGED,
5831 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5832 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5833 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5834 ok(sz == 1, "Expected 1, got %d\n", sz);
5835
5836 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5837 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5838
5839 /* DisplayVersion value exists */
5840 sz = MAX_PATH;
5841 lstrcpyA(buf, "apple");
5842 r = pMsiGetProductInfoExA(prodcode, usersid,
5843 MSIINSTALLCONTEXT_USERUNMANAGED,
5844 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5845 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5846 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5847 ok(sz == 5, "Expected 5, got %d\n", sz);
5848
5849 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5850 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5851
5852 /* ProductID value exists */
5853 sz = MAX_PATH;
5854 lstrcpyA(buf, "apple");
5855 r = pMsiGetProductInfoExA(prodcode, usersid,
5856 MSIINSTALLCONTEXT_USERUNMANAGED,
5857 INSTALLPROPERTY_PRODUCTID, buf, &sz);
5858 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5859 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5860 ok(sz == 2, "Expected 2, got %d\n", sz);
5861
5862 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5863 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5864
5865 /* RegCompany value exists */
5866 sz = MAX_PATH;
5867 lstrcpyA(buf, "apple");
5868 r = pMsiGetProductInfoExA(prodcode, usersid,
5869 MSIINSTALLCONTEXT_USERUNMANAGED,
5870 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5871 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5872 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5873 ok(sz == 4, "Expected 4, got %d\n", sz);
5874
5875 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5876 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5877
5878 /* RegOwner value exists */
5879 sz = MAX_PATH;
5880 lstrcpyA(buf, "apple");
5881 r = pMsiGetProductInfoExA(prodcode, usersid,
5882 MSIINSTALLCONTEXT_USERUNMANAGED,
5883 INSTALLPROPERTY_REGOWNER, buf, &sz);
5884 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5885 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5886 ok(sz == 5, "Expected 5, got %d\n", sz);
5887
5888 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5889 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5890
5891 /* Transforms value exists */
5892 sz = MAX_PATH;
5893 lstrcpyA(buf, "apple");
5894 r = pMsiGetProductInfoExA(prodcode, usersid,
5895 MSIINSTALLCONTEXT_USERUNMANAGED,
5896 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5897 ok(r == ERROR_UNKNOWN_PRODUCT,
5898 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5899 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5900 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5901
5902 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5903 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5904
5905 /* Language value exists */
5906 sz = MAX_PATH;
5907 lstrcpyA(buf, "apple");
5908 r = pMsiGetProductInfoExA(prodcode, usersid,
5909 MSIINSTALLCONTEXT_USERUNMANAGED,
5910 INSTALLPROPERTY_LANGUAGE, buf, &sz);
5911 ok(r == ERROR_UNKNOWN_PRODUCT,
5912 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5913 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5914 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5915
5916 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5917 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5918
5919 /* ProductName value exists */
5920 sz = MAX_PATH;
5921 lstrcpyA(buf, "apple");
5922 r = pMsiGetProductInfoExA(prodcode, usersid,
5923 MSIINSTALLCONTEXT_USERUNMANAGED,
5924 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5925 ok(r == ERROR_UNKNOWN_PRODUCT,
5926 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5927 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5928 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5929
5930 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5931 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5932
5933 /* FIXME */
5934
5935 /* AssignmentType value exists */
5936 sz = MAX_PATH;
5937 lstrcpyA(buf, "apple");
5938 r = pMsiGetProductInfoExA(prodcode, usersid,
5939 MSIINSTALLCONTEXT_USERUNMANAGED,
5940 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5941 ok(r == ERROR_UNKNOWN_PRODUCT,
5942 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5943 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5944 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5945
5946 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5947 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5948
5949 /* PackageCode value exists */
5950 sz = MAX_PATH;
5951 lstrcpyA(buf, "apple");
5952 r = pMsiGetProductInfoExA(prodcode, usersid,
5953 MSIINSTALLCONTEXT_USERUNMANAGED,
5954 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5955 ok(r == ERROR_UNKNOWN_PRODUCT,
5956 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5957 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5958 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5959
5960 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5961 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5962
5963 /* Version value exists */
5964 sz = MAX_PATH;
5965 lstrcpyA(buf, "apple");
5966 r = pMsiGetProductInfoExA(prodcode, usersid,
5967 MSIINSTALLCONTEXT_USERUNMANAGED,
5968 INSTALLPROPERTY_VERSION, buf, &sz);
5969 ok(r == ERROR_UNKNOWN_PRODUCT,
5970 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5971 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5972 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5973
5974 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5975 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5976
5977 /* ProductIcon value exists */
5978 sz = MAX_PATH;
5979 lstrcpyA(buf, "apple");
5980 r = pMsiGetProductInfoExA(prodcode, usersid,
5981 MSIINSTALLCONTEXT_USERUNMANAGED,
5982 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5983 ok(r == ERROR_UNKNOWN_PRODUCT,
5984 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5985 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5986 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5987
5988 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5989 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5990
5991 /* PackageName value exists */
5992 sz = MAX_PATH;
5993 lstrcpyA(buf, "apple");
5994 r = pMsiGetProductInfoExA(prodcode, usersid,
5995 MSIINSTALLCONTEXT_USERUNMANAGED,
5996 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5997 ok(r == ERROR_UNKNOWN_PRODUCT,
5998 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5999 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6000 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6001
6002 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6003 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6004
6005 /* AuthorizedLUAApp value exists */
6006 sz = MAX_PATH;
6007 lstrcpyA(buf, "apple");
6008 r = pMsiGetProductInfoExA(prodcode, usersid,
6009 MSIINSTALLCONTEXT_USERUNMANAGED,
6010 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6011 ok(r == ERROR_UNKNOWN_PRODUCT,
6012 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6013 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6014 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6015
6016 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6017 RegDeleteValueA(propkey, "PackageName");
6018 RegDeleteValueA(propkey, "ProductIcon");
6019 RegDeleteValueA(propkey, "Version");
6020 RegDeleteValueA(propkey, "PackageCode");
6021 RegDeleteValueA(propkey, "AssignmentType");
6022 RegDeleteValueA(propkey, "ProductName");
6023 RegDeleteValueA(propkey, "Language");
6024 RegDeleteValueA(propkey, "Transforms");
6025 RegDeleteValueA(propkey, "RegOwner");
6026 RegDeleteValueA(propkey, "RegCompany");
6027 RegDeleteValueA(propkey, "ProductID");
6028 RegDeleteValueA(propkey, "DisplayVersion");
6029 RegDeleteValueA(propkey, "VersionMajor");
6030 RegDeleteValueA(propkey, "VersionMinor");
6031 RegDeleteValueA(propkey, "URLUpdateInfo");
6032 RegDeleteValueA(propkey, "URLInfoAbout");
6033 RegDeleteValueA(propkey, "Publisher");
6034 RegDeleteValueA(propkey, "LocalPackage");
6035 RegDeleteValueA(propkey, "InstallSource");
6036 RegDeleteValueA(propkey, "InstallLocation");
6037 RegDeleteValueA(propkey, "DisplayName");
6038 RegDeleteValueA(propkey, "InstallDate");
6039 RegDeleteValueA(propkey, "HelpTelephone");
6040 RegDeleteValueA(propkey, "HelpLink");
6041 RegDeleteValueA(propkey, "LocalPackage");
6042 RegDeleteKeyA(propkey, "");
6043 RegCloseKey(propkey);
6044 RegDeleteKeyA(localkey, "");
6045 RegCloseKey(localkey);
6046
6047 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6048 lstrcatA(keypath, usersid);
6049 lstrcatA(keypath, "\\Installer\\Products\\");
6050 lstrcatA(keypath, prod_squashed);
6051
6052 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6053 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6054
6055 /* user product key exists */
6056 sz = MAX_PATH;
6057 lstrcpyA(buf, "apple");
6058 r = pMsiGetProductInfoExA(prodcode, usersid,
6059 MSIINSTALLCONTEXT_USERUNMANAGED,
6060 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6061 ok(r == ERROR_UNKNOWN_PRODUCT,
6062 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6063 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6064 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6065
6066 RegDeleteKeyA(userkey, "");
6067 RegCloseKey(userkey);
6068
6069 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6070 lstrcatA(keypath, prod_squashed);
6071
6072 res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6073 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6074
6075 sz = MAX_PATH;
6076 lstrcpyA(buf, "apple");
6077 r = pMsiGetProductInfoExA(prodcode, usersid,
6078 MSIINSTALLCONTEXT_USERUNMANAGED,
6079 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6080 ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
6081 if (r == ERROR_UNKNOWN_PRODUCT)
6082 {
6083 win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
6084 delete_key(prodkey, "", access);
6085 RegCloseKey(prodkey);
6086 return;
6087 }
6088 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6089 ok(sz == 1, "Expected 1, got %d\n", sz);
6090
6091 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6092 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6093
6094 /* HelpLink value exists */
6095 sz = MAX_PATH;
6096 lstrcpyA(buf, "apple");
6097 r = pMsiGetProductInfoExA(prodcode, usersid,
6098 MSIINSTALLCONTEXT_USERUNMANAGED,
6099 INSTALLPROPERTY_HELPLINK, buf, &sz);
6100 ok(r == ERROR_UNKNOWN_PROPERTY,
6101 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6102 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6103 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6104
6105 res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6106 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6107
6108 /* HelpTelephone value exists */
6109 sz = MAX_PATH;
6110 lstrcpyA(buf, "apple");
6111 r = pMsiGetProductInfoExA(prodcode, usersid,
6112 MSIINSTALLCONTEXT_USERUNMANAGED,
6113 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6114 ok(r == ERROR_UNKNOWN_PROPERTY,
6115 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6116 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6117 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6118
6119 res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6120 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6121
6122 /* InstallDate value exists */
6123 sz = MAX_PATH;
6124 lstrcpyA(buf, "apple");
6125 r = pMsiGetProductInfoExA(prodcode, usersid,
6126 MSIINSTALLCONTEXT_USERUNMANAGED,
6127 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6128 ok(r == ERROR_UNKNOWN_PROPERTY,
6129 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6130 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6131 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6132
6133 res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6134 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6135
6136 /* DisplayName value exists */
6137 sz = MAX_PATH;
6138 lstrcpyA(buf, "apple");
6139 r = pMsiGetProductInfoExA(prodcode, usersid,
6140 MSIINSTALLCONTEXT_USERUNMANAGED,
6141 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6142 ok(r == ERROR_UNKNOWN_PROPERTY,
6143 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6144 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6145 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6146
6147 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6148 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6149
6150 /* InstallLocation value exists */
6151 sz = MAX_PATH;
6152 lstrcpyA(buf, "apple");
6153 r = pMsiGetProductInfoExA(prodcode, usersid,
6154 MSIINSTALLCONTEXT_USERUNMANAGED,
6155 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6156 ok(r == ERROR_UNKNOWN_PROPERTY,
6157 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6158 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6159 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6160
6161 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6162 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6163
6164 /* InstallSource value exists */
6165 sz = MAX_PATH;
6166 lstrcpyA(buf, "apple");
6167 r = pMsiGetProductInfoExA(prodcode, usersid,
6168 MSIINSTALLCONTEXT_USERUNMANAGED,
6169 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6170 ok(r == ERROR_UNKNOWN_PROPERTY,
6171 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6172 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6173 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6174
6175 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6176 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6177
6178 /* LocalPackage value exists */
6179 sz = MAX_PATH;
6180 lstrcpyA(buf, "apple");
6181 r = pMsiGetProductInfoExA(prodcode, usersid,
6182 MSIINSTALLCONTEXT_USERUNMANAGED,
6183 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6184 ok(r == ERROR_UNKNOWN_PROPERTY,
6185 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6186 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6187 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6188
6189 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6190 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6191
6192 /* Publisher value exists */
6193 sz = MAX_PATH;
6194 lstrcpyA(buf, "apple");
6195 r = pMsiGetProductInfoExA(prodcode, usersid,
6196 MSIINSTALLCONTEXT_USERUNMANAGED,
6197 INSTALLPROPERTY_PUBLISHER, buf, &sz);
6198 ok(r == ERROR_UNKNOWN_PROPERTY,
6199 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6200 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6201 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6202
6203 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6204 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6205
6206 /* URLInfoAbout value exists */
6207 sz = MAX_PATH;
6208 lstrcpyA(buf, "apple");
6209 r = pMsiGetProductInfoExA(prodcode, usersid,
6210 MSIINSTALLCONTEXT_USERUNMANAGED,
6211 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6212 ok(r == ERROR_UNKNOWN_PROPERTY,
6213 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6214 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6215 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6216
6217 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6218 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6219
6220 /* URLUpdateInfo value exists */
6221 sz = MAX_PATH;
6222 lstrcpyA(buf, "apple");
6223 r = pMsiGetProductInfoExA(prodcode, usersid,
6224 MSIINSTALLCONTEXT_USERUNMANAGED,
6225 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6226 ok(r == ERROR_UNKNOWN_PROPERTY,
6227 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6228 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6229 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6230
6231 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6232 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6233
6234 /* VersionMinor value exists */
6235 sz = MAX_PATH;
6236 lstrcpyA(buf, "apple");
6237 r = pMsiGetProductInfoExA(prodcode, usersid,
6238 MSIINSTALLCONTEXT_USERUNMANAGED,
6239 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6240 ok(r == ERROR_UNKNOWN_PROPERTY,
6241 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6242 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6243 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6244
6245 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6246 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6247
6248 /* VersionMajor value exists */
6249 sz = MAX_PATH;
6250 lstrcpyA(buf, "apple");
6251 r = pMsiGetProductInfoExA(prodcode, usersid,
6252 MSIINSTALLCONTEXT_USERUNMANAGED,
6253 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6254 ok(r == ERROR_UNKNOWN_PROPERTY,
6255 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6256 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6257 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6258
6259 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6260 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6261
6262 /* DisplayVersion value exists */
6263 sz = MAX_PATH;
6264 lstrcpyA(buf, "apple");
6265 r = pMsiGetProductInfoExA(prodcode, usersid,
6266 MSIINSTALLCONTEXT_USERUNMANAGED,
6267 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6268 ok(r == ERROR_UNKNOWN_PROPERTY,
6269 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6270 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6271 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6272
6273 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6274 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6275
6276 /* ProductID value exists */
6277 sz = MAX_PATH;
6278 lstrcpyA(buf, "apple");
6279 r = pMsiGetProductInfoExA(prodcode, usersid,
6280 MSIINSTALLCONTEXT_USERUNMANAGED,
6281 INSTALLPROPERTY_PRODUCTID, buf, &sz);
6282 ok(r == ERROR_UNKNOWN_PROPERTY,
6283 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6284 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6285 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6286
6287 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6288 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6289
6290 /* RegCompany value exists */
6291 sz = MAX_PATH;
6292 lstrcpyA(buf, "apple");
6293 r = pMsiGetProductInfoExA(prodcode, usersid,
6294 MSIINSTALLCONTEXT_USERUNMANAGED,
6295 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6296 ok(r == ERROR_UNKNOWN_PROPERTY,
6297 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6298 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6299 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6300
6301 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6302 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6303
6304 /* RegOwner value exists */
6305 sz = MAX_PATH;
6306 lstrcpyA(buf, "apple");
6307 r = pMsiGetProductInfoExA(prodcode, usersid,
6308 MSIINSTALLCONTEXT_USERUNMANAGED,
6309 INSTALLPROPERTY_REGOWNER, buf, &sz);
6310 ok(r == ERROR_UNKNOWN_PROPERTY,
6311 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6312 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6313 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6314
6315 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6316 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6317
6318 /* Transforms value exists */
6319 sz = MAX_PATH;
6320 lstrcpyA(buf, "apple");
6321 r = pMsiGetProductInfoExA(prodcode, usersid,
6322 MSIINSTALLCONTEXT_USERUNMANAGED,
6323 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6324 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6325 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6326 ok(sz == 5, "Expected 5, got %d\n", sz);
6327
6328 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6330
6331 /* Language value exists */
6332 sz = MAX_PATH;
6333 lstrcpyA(buf, "apple");
6334 r = pMsiGetProductInfoExA(prodcode, usersid,
6335 MSIINSTALLCONTEXT_USERUNMANAGED,
6336 INSTALLPROPERTY_LANGUAGE, buf, &sz);
6337 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6338 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6339 ok(sz == 4, "Expected 4, got %d\n", sz);
6340
6341 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6342 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6343
6344 /* ProductName value exists */
6345 sz = MAX_PATH;
6346 lstrcpyA(buf, "apple");
6347 r = pMsiGetProductInfoExA(prodcode, usersid,
6348 MSIINSTALLCONTEXT_USERUNMANAGED,
6349 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6350 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6351 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6352 ok(sz == 4, "Expected 4, got %d\n", sz);
6353
6354 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6355 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6356
6357 /* FIXME */
6358
6359 /* AssignmentType value exists */
6360 sz = MAX_PATH;
6361 lstrcpyA(buf, "apple");
6362 r = pMsiGetProductInfoExA(prodcode, usersid,
6363 MSIINSTALLCONTEXT_USERUNMANAGED,
6364 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6365 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6366 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6367 ok(sz == 0, "Expected 0, got %d\n", sz);
6368
6369 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6370 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6371
6372 /* FIXME */
6373
6374 /* PackageCode value exists */
6375 sz = MAX_PATH;
6376 lstrcpyA(buf, "apple");
6377 r = pMsiGetProductInfoExA(prodcode, usersid,
6378 MSIINSTALLCONTEXT_USERUNMANAGED,
6379 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6380 todo_wine
6381 {
6382 ok(r == ERROR_BAD_CONFIGURATION,
6383 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6384 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6385 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6386 }
6387
6388 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6390
6391 /* Version value exists */
6392 sz = MAX_PATH;
6393 lstrcpyA(buf, "apple");
6394 r = pMsiGetProductInfoExA(prodcode, usersid,
6395 MSIINSTALLCONTEXT_USERUNMANAGED,
6396 INSTALLPROPERTY_VERSION, buf, &sz);
6397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6398 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6399 ok(sz == 3, "Expected 3, got %d\n", sz);
6400
6401 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6402 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6403
6404 /* ProductIcon value exists */
6405 sz = MAX_PATH;
6406 lstrcpyA(buf, "apple");
6407 r = pMsiGetProductInfoExA(prodcode, usersid,
6408 MSIINSTALLCONTEXT_USERUNMANAGED,
6409 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6411 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6412 ok(sz == 4, "Expected 4, got %d\n", sz);
6413
6414 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6415 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6416
6417 /* PackageName value exists */
6418 sz = MAX_PATH;
6419 lstrcpyA(buf, "apple");
6420 r = pMsiGetProductInfoExA(prodcode, usersid,
6421 MSIINSTALLCONTEXT_USERUNMANAGED,
6422 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6423 todo_wine
6424 {
6425 ok(r == ERROR_UNKNOWN_PRODUCT,
6426 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6427 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6428 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6429 }
6430
6431 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6432 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6433
6434 /* AuthorizedLUAApp value exists */
6435 sz = MAX_PATH;
6436 lstrcpyA(buf, "apple");
6437 r = pMsiGetProductInfoExA(prodcode, usersid,
6438 MSIINSTALLCONTEXT_USERUNMANAGED,
6439 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6440 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6441 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6442 ok(sz == 4, "Expected 4, got %d\n", sz);
6443
6444 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6445 RegDeleteValueA(prodkey, "PackageName");
6446 RegDeleteValueA(prodkey, "ProductIcon");
6447 RegDeleteValueA(prodkey, "Version");
6448 RegDeleteValueA(prodkey, "PackageCode");
6449 RegDeleteValueA(prodkey, "AssignmentType");
6450 RegDeleteValueA(prodkey, "ProductName");
6451 RegDeleteValueA(prodkey, "Language");
6452 RegDeleteValueA(prodkey, "Transforms");
6453 RegDeleteValueA(prodkey, "RegOwner");
6454 RegDeleteValueA(prodkey, "RegCompany");
6455 RegDeleteValueA(prodkey, "ProductID");
6456 RegDeleteValueA(prodkey, "DisplayVersion");
6457 RegDeleteValueA(prodkey, "VersionMajor");
6458 RegDeleteValueA(prodkey, "VersionMinor");
6459 RegDeleteValueA(prodkey, "URLUpdateInfo");
6460 RegDeleteValueA(prodkey, "URLInfoAbout");
6461 RegDeleteValueA(prodkey, "Publisher");
6462 RegDeleteValueA(prodkey, "LocalPackage");
6463 RegDeleteValueA(prodkey, "InstallSource");
6464 RegDeleteValueA(prodkey, "InstallLocation");
6465 RegDeleteValueA(prodkey, "DisplayName");
6466 RegDeleteValueA(prodkey, "InstallDate");
6467 RegDeleteValueA(prodkey, "HelpTelephone");
6468 RegDeleteValueA(prodkey, "HelpLink");
6469 RegDeleteValueA(prodkey, "LocalPackage");
6470 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6471 RegCloseKey(prodkey);
6472
6473 /* MSIINSTALLCONTEXT_USERMANAGED */
6474
6475 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
6476 lstrcatA(keypath, usersid);
6477 lstrcatA(keypath, "\\Products\\");
6478 lstrcatA(keypath, prod_squashed);
6479
6480 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6481 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6482
6483 /* local user product key exists */
6484 sz = MAX_PATH;
6485 lstrcpyA(buf, "apple");
6486 r = pMsiGetProductInfoExA(prodcode, usersid,
6487 MSIINSTALLCONTEXT_USERMANAGED,
6488 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6489 ok(r == ERROR_UNKNOWN_PRODUCT,
6490 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6491 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6492 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6493
6494 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6496
6497 /* InstallProperties key exists */
6498 sz = MAX_PATH;
6499 lstrcpyA(buf, "apple");
6500 r = pMsiGetProductInfoExA(prodcode, usersid,
6501 MSIINSTALLCONTEXT_USERMANAGED,
6502 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6503 ok(r == ERROR_UNKNOWN_PRODUCT,
6504 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6505 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6506 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6507
6508 res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6509 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6510
6511 /* ManagedLocalPackage value exists */
6512 sz = MAX_PATH;
6513 lstrcpyA(buf, "apple");
6514 r = pMsiGetProductInfoExA(prodcode, usersid,
6515 MSIINSTALLCONTEXT_USERMANAGED,
6516 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6517 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6518 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6519 ok(sz == 1, "Expected 1, got %d\n", sz);
6520
6521 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6523
6524 /* HelpLink value exists */
6525 sz = MAX_PATH;
6526 lstrcpyA(buf, "apple");
6527 r = pMsiGetProductInfoExA(prodcode, usersid,
6528 MSIINSTALLCONTEXT_USERMANAGED,
6529 INSTALLPROPERTY_HELPLINK, buf, &sz);
6530 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6531 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6532 ok(sz == 4, "Expected 4, got %d\n", sz);
6533
6534 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6535 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6536
6537 /* HelpTelephone value exists */
6538 sz = MAX_PATH;
6539 lstrcpyA(buf, "apple");
6540 r = pMsiGetProductInfoExA(prodcode, usersid,
6541 MSIINSTALLCONTEXT_USERMANAGED,
6542 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6544 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6545 ok(sz == 5, "Expected 5, got %d\n", sz);
6546
6547 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6548 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6549
6550 /* InstallDate value exists */
6551 sz = MAX_PATH;
6552 lstrcpyA(buf, "apple");
6553 r = pMsiGetProductInfoExA(prodcode, usersid,
6554 MSIINSTALLCONTEXT_USERMANAGED,
6555 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6556 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6557 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6558 ok(sz == 4, "Expected 4, got %d\n", sz);
6559
6560 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6561 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6562
6563 /* DisplayName value exists */
6564 sz = MAX_PATH;
6565 lstrcpyA(buf, "apple");
6566 r = pMsiGetProductInfoExA(prodcode, usersid,
6567 MSIINSTALLCONTEXT_USERMANAGED,
6568 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6569 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6570 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6571 ok(sz == 4, "Expected 4, got %d\n", sz);
6572
6573 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6574 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6575
6576 /* InstallLocation value exists */
6577 sz = MAX_PATH;
6578 lstrcpyA(buf, "apple");
6579 r = pMsiGetProductInfoExA(prodcode, usersid,
6580 MSIINSTALLCONTEXT_USERMANAGED,
6581 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6582 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6583 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6584 ok(sz == 3, "Expected 3, got %d\n", sz);
6585
6586 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6587 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6588
6589 /* InstallSource value exists */
6590 sz = MAX_PATH;
6591 lstrcpyA(buf, "apple");
6592 r = pMsiGetProductInfoExA(prodcode, usersid,
6593 MSIINSTALLCONTEXT_USERMANAGED,
6594 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6595 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6596 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6597 ok(sz == 6, "Expected 6, got %d\n", sz);
6598
6599 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6600 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6601
6602 /* LocalPackage value exists */
6603 sz = MAX_PATH;
6604 lstrcpyA(buf, "apple");
6605 r = pMsiGetProductInfoExA(prodcode, usersid,
6606 MSIINSTALLCONTEXT_USERMANAGED,
6607 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6608 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6609 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6610 ok(sz == 5, "Expected 5, got %d\n", sz);
6611
6612 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6613 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6614
6615 /* Publisher value exists */
6616 sz = MAX_PATH;
6617 lstrcpyA(buf, "apple");
6618 r = pMsiGetProductInfoExA(prodcode, usersid,
6619 MSIINSTALLCONTEXT_USERMANAGED,
6620 INSTALLPROPERTY_PUBLISHER, buf, &sz);
6621 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6622 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6623 ok(sz == 3, "Expected 3, got %d\n", sz);
6624
6625 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6626 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6627
6628 /* URLInfoAbout value exists */
6629 sz = MAX_PATH;
6630 lstrcpyA(buf, "apple");
6631 r = pMsiGetProductInfoExA(prodcode, usersid,
6632 MSIINSTALLCONTEXT_USERMANAGED,
6633 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6634 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6635 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6636 ok(sz == 5, "Expected 5, got %d\n", sz);
6637
6638 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6639 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6640
6641 /* URLUpdateInfo value exists */
6642 sz = MAX_PATH;
6643 lstrcpyA(buf, "apple");
6644 r = pMsiGetProductInfoExA(prodcode, usersid,
6645 MSIINSTALLCONTEXT_USERMANAGED,
6646 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6647 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6648 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6649 ok(sz == 6, "Expected 6, got %d\n", sz);
6650
6651 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6652 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6653
6654 /* VersionMinor value exists */
6655 sz = MAX_PATH;
6656 lstrcpyA(buf, "apple");
6657 r = pMsiGetProductInfoExA(prodcode, usersid,
6658 MSIINSTALLCONTEXT_USERMANAGED,
6659 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6660 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6661 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6662 ok(sz == 1, "Expected 1, got %d\n", sz);
6663
6664 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6665 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6666
6667 /* VersionMajor value exists */
6668 sz = MAX_PATH;
6669 lstrcpyA(buf, "apple");
6670 r = pMsiGetProductInfoExA(prodcode, usersid,
6671 MSIINSTALLCONTEXT_USERMANAGED,
6672 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6673 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6674 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6675 ok(sz == 1, "Expected 1, got %d\n", sz);
6676
6677 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6678 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6679
6680 /* DisplayVersion value exists */
6681 sz = MAX_PATH;
6682 lstrcpyA(buf, "apple");
6683 r = pMsiGetProductInfoExA(prodcode, usersid,
6684 MSIINSTALLCONTEXT_USERMANAGED,
6685 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6686 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6687 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6688 ok(sz == 5, "Expected 5, got %d\n", sz);
6689
6690 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6691 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6692
6693 /* ProductID value exists */
6694 sz = MAX_PATH;
6695 lstrcpyA(buf, "apple");
6696 r = pMsiGetProductInfoExA(prodcode, usersid,
6697 MSIINSTALLCONTEXT_USERMANAGED,
6698 INSTALLPROPERTY_PRODUCTID, buf, &sz);
6699 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6700 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6701 ok(sz == 2, "Expected 2, got %d\n", sz);
6702
6703 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6704 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6705
6706 /* RegCompany value exists */
6707 sz = MAX_PATH;
6708 lstrcpyA(buf, "apple");
6709 r = pMsiGetProductInfoExA(prodcode, usersid,
6710 MSIINSTALLCONTEXT_USERMANAGED,
6711 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6712 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6713 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6714 ok(sz == 4, "Expected 4, got %d\n", sz);
6715
6716 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6717 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6718
6719 /* RegOwner value exists */
6720 sz = MAX_PATH;
6721 lstrcpyA(buf, "apple");
6722 r = pMsiGetProductInfoExA(prodcode, usersid,
6723 MSIINSTALLCONTEXT_USERMANAGED,
6724 INSTALLPROPERTY_REGOWNER, buf, &sz);
6725 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6726 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6727 ok(sz == 5, "Expected 5, got %d\n", sz);
6728
6729 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6730 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6731
6732 /* Transforms value exists */
6733 sz = MAX_PATH;
6734 lstrcpyA(buf, "apple");
6735 r = pMsiGetProductInfoExA(prodcode, usersid,
6736 MSIINSTALLCONTEXT_USERMANAGED,
6737 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6738 ok(r == ERROR_UNKNOWN_PRODUCT,
6739 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6740 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6741 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6742
6743 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6744 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6745
6746 /* Language value exists */
6747 sz = MAX_PATH;
6748 lstrcpyA(buf, "apple");
6749 r = pMsiGetProductInfoExA(prodcode, usersid,
6750 MSIINSTALLCONTEXT_USERMANAGED,
6751 INSTALLPROPERTY_LANGUAGE, buf, &sz);
6752 ok(r == ERROR_UNKNOWN_PRODUCT,
6753 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6754 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6755 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6756
6757 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6758 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6759
6760 /* ProductName value exists */
6761 sz = MAX_PATH;
6762 lstrcpyA(buf, "apple");
6763 r = pMsiGetProductInfoExA(prodcode, usersid,
6764 MSIINSTALLCONTEXT_USERMANAGED,
6765 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6766 ok(r == ERROR_UNKNOWN_PRODUCT,
6767 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6768 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6769 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6770
6771 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6772 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6773
6774 /* FIXME */
6775
6776 /* AssignmentType value exists */
6777 sz = MAX_PATH;
6778 lstrcpyA(buf, "apple");
6779 r = pMsiGetProductInfoExA(prodcode, usersid,
6780 MSIINSTALLCONTEXT_USERMANAGED,
6781 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6782 ok(r == ERROR_UNKNOWN_PRODUCT,
6783 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6784 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6785 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6786
6787 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6788 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6789
6790 /* PackageCode value exists */
6791 sz = MAX_PATH;
6792 lstrcpyA(buf, "apple");
6793 r = pMsiGetProductInfoExA(prodcode, usersid,
6794 MSIINSTALLCONTEXT_USERMANAGED,
6795 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6796 ok(r == ERROR_UNKNOWN_PRODUCT,
6797 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6798 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6799 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6800
6801 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6802 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6803
6804 /* Version value exists */
6805 sz = MAX_PATH;
6806 lstrcpyA(buf, "apple");
6807 r = pMsiGetProductInfoExA(prodcode, usersid,
6808 MSIINSTALLCONTEXT_USERMANAGED,
6809 INSTALLPROPERTY_VERSION, buf, &sz);
6810 ok(r == ERROR_UNKNOWN_PRODUCT,
6811 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6812 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6813 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6814
6815 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6816 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6817
6818 /* ProductIcon value exists */
6819 sz = MAX_PATH;
6820 lstrcpyA(buf, "apple");
6821 r = pMsiGetProductInfoExA(prodcode, usersid,
6822 MSIINSTALLCONTEXT_USERMANAGED,
6823 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6824 ok(r == ERROR_UNKNOWN_PRODUCT,
6825 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6826 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6827 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6828
6829 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6830 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6831
6832 /* PackageName value exists */
6833 sz = MAX_PATH;
6834 lstrcpyA(buf, "apple");
6835 r = pMsiGetProductInfoExA(prodcode, usersid,
6836 MSIINSTALLCONTEXT_USERMANAGED,
6837 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6838 ok(r == ERROR_UNKNOWN_PRODUCT,
6839 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6840 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6841 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6842
6843 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6844 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6845
6846 /* AuthorizedLUAApp value exists */
6847 sz = MAX_PATH;
6848 lstrcpyA(buf, "apple");
6849 r = pMsiGetProductInfoExA(prodcode, usersid,
6850 MSIINSTALLCONTEXT_USERMANAGED,
6851 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6852 ok(r == ERROR_UNKNOWN_PRODUCT,
6853 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6854 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6855 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6856
6857 RegDeleteValueA(propkey, "AuthorizedLUAApp");
6858 RegDeleteValueA(propkey, "PackageName");
6859 RegDeleteValueA(propkey, "ProductIcon");
6860 RegDeleteValueA(propkey, "Version");
6861 RegDeleteValueA(propkey, "PackageCode");
6862 RegDeleteValueA(propkey, "AssignmentType");
6863 RegDeleteValueA(propkey, "ProductName");
6864 RegDeleteValueA(propkey, "Language");
6865 RegDeleteValueA(propkey, "Transforms");
6866 RegDeleteValueA(propkey, "RegOwner");
6867 RegDeleteValueA(propkey, "RegCompany");
6868 RegDeleteValueA(propkey, "ProductID");
6869 RegDeleteValueA(propkey, "DisplayVersion");
6870 RegDeleteValueA(propkey, "VersionMajor");
6871 RegDeleteValueA(propkey, "VersionMinor");
6872 RegDeleteValueA(propkey, "URLUpdateInfo");
6873 RegDeleteValueA(propkey, "URLInfoAbout");
6874 RegDeleteValueA(propkey, "Publisher");
6875 RegDeleteValueA(propkey, "LocalPackage");
6876 RegDeleteValueA(propkey, "InstallSource");
6877 RegDeleteValueA(propkey, "InstallLocation");
6878 RegDeleteValueA(propkey, "DisplayName");
6879 RegDeleteValueA(propkey, "InstallDate");
6880 RegDeleteValueA(propkey, "HelpTelephone");
6881 RegDeleteValueA(propkey, "HelpLink");
6882 RegDeleteValueA(propkey, "ManagedLocalPackage");
6883 delete_key(propkey, "", access & KEY_WOW64_64KEY);
6884 RegCloseKey(propkey);
6885 delete_key(localkey, "", access & KEY_WOW64_64KEY);
6886 RegCloseKey(localkey);
6887
6888 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6889 lstrcatA(keypath, usersid);
6890 lstrcatA(keypath, "\\Installer\\Products\\");
6891 lstrcatA(keypath, prod_squashed);
6892
6893 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6894 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6895
6896 /* user product key exists */
6897 sz = MAX_PATH;
6898 lstrcpyA(buf, "apple");
6899 r = pMsiGetProductInfoExA(prodcode, usersid,
6900 MSIINSTALLCONTEXT_USERMANAGED,
6901 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6902 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6903 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6904 ok(sz == 1, "Expected 1, got %d\n", sz);
6905
6906 delete_key(userkey, "", access & KEY_WOW64_64KEY);
6907 RegCloseKey(userkey);
6908
6909 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6910 lstrcatA(keypath, prod_squashed);
6911
6912 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6913 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6914
6915 /* current user product key exists */
6916 sz = MAX_PATH;
6917 lstrcpyA(buf, "apple");
6918 r = pMsiGetProductInfoExA(prodcode, usersid,
6919 MSIINSTALLCONTEXT_USERMANAGED,
6920 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6921 ok(r == ERROR_UNKNOWN_PRODUCT,
6922 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6923 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6924 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6925
6926 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6927 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6928
6929 /* HelpLink value exists, user product key does not exist */
6930 sz = MAX_PATH;
6931 lstrcpyA(buf, "apple");
6932 r = pMsiGetProductInfoExA(prodcode, usersid,
6933 MSIINSTALLCONTEXT_USERMANAGED,
6934 INSTALLPROPERTY_HELPLINK, buf, &sz);
6935 ok(r == ERROR_UNKNOWN_PRODUCT,
6936 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6937 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6938 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6939
6940 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6941 lstrcatA(keypath, usersid);
6942 lstrcatA(keypath, "\\Installer\\Products\\");
6943 lstrcatA(keypath, prod_squashed);
6944
6945 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
6946 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6947
6948 res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6949 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6950
6951 /* HelpLink value exists, user product key does exist */
6952 sz = MAX_PATH;
6953 lstrcpyA(buf, "apple");
6954 r = pMsiGetProductInfoExA(prodcode, usersid,
6955 MSIINSTALLCONTEXT_USERMANAGED,
6956 INSTALLPROPERTY_HELPLINK, buf, &sz);
6957 ok(r == ERROR_UNKNOWN_PROPERTY,
6958 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6959 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6960 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6961
6962 res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6963 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6964
6965 /* HelpTelephone value exists */
6966 sz = MAX_PATH;
6967 lstrcpyA(buf, "apple");
6968 r = pMsiGetProductInfoExA(prodcode, usersid,
6969 MSIINSTALLCONTEXT_USERMANAGED,
6970 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6971 ok(r == ERROR_UNKNOWN_PROPERTY,
6972 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6973 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6974 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6975
6976 res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6977 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6978
6979 /* InstallDate value exists */
6980 sz = MAX_PATH;
6981 lstrcpyA(buf, "apple");
6982 r = pMsiGetProductInfoExA(prodcode, usersid,
6983 MSIINSTALLCONTEXT_USERMANAGED,
6984 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6985 ok(r == ERROR_UNKNOWN_PROPERTY,
6986 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6987 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6988 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6989
6990 res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6991 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6992
6993 /* DisplayName value exists */
6994 sz = MAX_PATH;
6995 lstrcpyA(buf, "apple");
6996 r = pMsiGetProductInfoExA(prodcode, usersid,
6997 MSIINSTALLCONTEXT_USERMANAGED,
6998 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6999 ok(r == ERROR_UNKNOWN_PROPERTY,
7000 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7001 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7002 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7003
7004 res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7005 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7006
7007 /* InstallLocation value exists */
7008 sz = MAX_PATH;
7009 lstrcpyA(buf, "apple");
7010 r = pMsiGetProductInfoExA(prodcode, usersid,
7011 MSIINSTALLCONTEXT_USERMANAGED,
7012 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
7013 ok(r == ERROR_UNKNOWN_PROPERTY,
7014 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7015 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7016 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7017
7018 res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7019 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7020
7021 /* InstallSource value exists */
7022 sz = MAX_PATH;
7023 lstrcpyA(buf, "apple");
7024 r = pMsiGetProductInfoExA(prodcode, usersid,
7025 MSIINSTALLCONTEXT_USERMANAGED,
7026 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
7027 ok(r == ERROR_UNKNOWN_PROPERTY,
7028 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7029 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7030 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7031
7032 res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7033 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7034
7035 /* LocalPackage value exists */
7036 sz = MAX_PATH;
7037 lstrcpyA(buf, "apple");
7038 r = pMsiGetProductInfoExA(prodcode, usersid,
7039 MSIINSTALLCONTEXT_USERMANAGED,
7040 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
7041 ok(r == ERROR_UNKNOWN_PROPERTY,
7042 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7043 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7044 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7045
7046 res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7047 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7048
7049 /* Publisher value exists */
7050 sz = MAX_PATH;
7051 lstrcpyA(buf, "apple");
7052 r = pMsiGetProductInfoExA(prodcode, usersid,
7053 MSIINSTALLCONTEXT_USERMANAGED,
7054 INSTALLPROPERTY_PUBLISHER, buf, &sz);
7055 ok(r == ERROR_UNKNOWN_PROPERTY,
7056 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7057 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7058 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7059
7060 res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7061 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7062
7063 /* URLInfoAbout value exists */
7064 sz = MAX_PATH;
7065 lstrcpyA(buf, "apple");
7066 r = pMsiGetProductInfoExA(prodcode, usersid,
7067 MSIINSTALLCONTEXT_USERMANAGED,
7068 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
7069 ok(r == ERROR_UNKNOWN_PROPERTY,
7070 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7071 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7072 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7073
7074 res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7075 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7076
7077 /* URLUpdateInfo value exists */
7078 sz = MAX_PATH;
7079 lstrcpyA(buf, "apple");
7080 r = pMsiGetProductInfoExA(prodcode, usersid,
7081 MSIINSTALLCONTEXT_USERMANAGED,
7082 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
7083 ok(r == ERROR_UNKNOWN_PROPERTY,
7084 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7085 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7086 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7087
7088 res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7089 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7090
7091 /* VersionMinor value exists */
7092 sz = MAX_PATH;
7093 lstrcpyA(buf, "apple");
7094 r = pMsiGetProductInfoExA(prodcode, usersid,
7095 MSIINSTALLCONTEXT_USERMANAGED,
7096 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
7097 ok(r == ERROR_UNKNOWN_PROPERTY,
7098 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7099 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7100 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7101
7102 res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7103 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7104
7105 /* VersionMajor value exists */
7106 sz = MAX_PATH;
7107 lstrcpyA(buf, "apple");
7108 r = pMsiGetProductInfoExA(prodcode, usersid,
7109 MSIINSTALLCONTEXT_USERMANAGED,
7110 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
7111 ok(r == ERROR_UNKNOWN_PROPERTY,
7112 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7113 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7114 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7115
7116 res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7117 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7118
7119 /* DisplayVersion value exists */
7120 sz = MAX_PATH;
7121 lstrcpyA(buf, "apple");
7122 r = pMsiGetProductInfoExA(prodcode, usersid,
7123 MSIINSTALLCONTEXT_USERMANAGED,
7124 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
7125 ok(r == ERROR_UNKNOWN_PROPERTY,
7126 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7127 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7128 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7129
7130 res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7131 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7132
7133 /* ProductID value exists */
7134 sz = MAX_PATH;
7135 lstrcpyA(buf, "apple");
7136 r = pMsiGetProductInfoExA(prodcode, usersid,
7137 MSIINSTALLCONTEXT_USERMANAGED,
7138 INSTALLPROPERTY_PRODUCTID, buf, &sz);
7139 ok(r == ERROR_UNKNOWN_PROPERTY,
7140 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7141 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7142 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7143
7144 res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7145 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7146
7147 /* RegCompany value exists */
7148 sz = MAX_PATH;
7149 lstrcpyA(buf, "apple");
7150 r = pMsiGetProductInfoExA(prodcode, usersid,
7151 MSIINSTALLCONTEXT_USERMANAGED,
7152 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
7153 ok(r == ERROR_UNKNOWN_PROPERTY,
7154 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7155 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7156 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7157
7158 res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7159 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7160
7161 /* RegOwner value exists */
7162 sz = MAX_PATH;
7163 lstrcpyA(buf, "apple");
7164 r = pMsiGetProductInfoExA(prodcode, usersid,
7165 MSIINSTALLCONTEXT_USERMANAGED,
7166 INSTALLPROPERTY_REGOWNER, buf, &sz);
7167 ok(r == ERROR_UNKNOWN_PROPERTY,
7168 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7169 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7170 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7171
7172 res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7173 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7174
7175 /* Transforms value exists */
7176 sz = MAX_PATH;
7177 lstrcpyA(buf, "apple");
7178 r = pMsiGetProductInfoExA(prodcode, usersid,
7179 MSIINSTALLCONTEXT_USERMANAGED,
7180 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
7181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7182 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
7183 ok(sz == 5, "Expected 5, got %d\n", sz);
7184
7185 res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7186 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7187
7188 /* Language value exists */
7189 sz = MAX_PATH;
7190 lstrcpyA(buf, "apple");
7191 r = pMsiGetProductInfoExA(prodcode, usersid,
7192 MSIINSTALLCONTEXT_USERMANAGED,
7193 INSTALLPROPERTY_LANGUAGE, buf, &sz);
7194 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7195 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
7196 ok(sz == 4, "Expected 4, got %d\n", sz);
7197
7198 res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7199 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7200
7201 /* ProductName value exists */
7202 sz = MAX_PATH;
7203 lstrcpyA(buf, "apple");
7204 r = pMsiGetProductInfoExA(prodcode, usersid,
7205 MSIINSTALLCONTEXT_USERMANAGED,
7206 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
7207 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7208 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7209 ok(sz == 4, "Expected 4, got %d\n", sz);
7210
7211 res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7212 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7213
7214 /* FIXME */
7215
7216 /* AssignmentType value exists */
7217 sz = MAX_PATH;
7218 lstrcpyA(buf, "apple");
7219 r = pMsiGetProductInfoExA(prodcode, usersid,
7220 MSIINSTALLCONTEXT_USERMANAGED,
7221 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
7222 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7223 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
7224 ok(sz == 0, "Expected 0, got %d\n", sz);
7225
7226 res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7227 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7228
7229 /* FIXME */
7230
7231 /* PackageCode value exists */
7232 sz = MAX_PATH;
7233 lstrcpyA(buf, "apple");
7234 r = pMsiGetProductInfoExA(prodcode, usersid,
7235 MSIINSTALLCONTEXT_USERMANAGED,
7236 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
7237 todo_wine
7238 {
7239 ok(r == ERROR_BAD_CONFIGURATION,
7240 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7241 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7242 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7243 }
7244
7245 res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7246 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7247
7248 /* Version value exists */
7249 sz = MAX_PATH;
7250 lstrcpyA(buf, "apple");
7251 r = pMsiGetProductInfoExA(prodcode, usersid,
7252 MSIINSTALLCONTEXT_USERMANAGED,
7253 INSTALLPROPERTY_VERSION, buf, &sz);
7254 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7255 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
7256 ok(sz == 3, "Expected 3, got %d\n", sz);
7257
7258 res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7259 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7260
7261 /* ProductIcon value exists */
7262 sz = MAX_PATH;
7263 lstrcpyA(buf, "apple");
7264 r = pMsiGetProductInfoExA(prodcode, usersid,
7265 MSIINSTALLCONTEXT_USERMANAGED,
7266 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
7267 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7268 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
7269 ok(sz == 4, "Expected 4, got %d\n", sz);
7270
7271 res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7272 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7273
7274 /* PackageName value exists */
7275 sz = MAX_PATH;
7276 lstrcpyA(buf, "apple");
7277 r = pMsiGetProductInfoExA(prodcode, usersid,
7278 MSIINSTALLCONTEXT_USERMANAGED,
7279 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
7280 todo_wine
7281 {
7282 ok(r == ERROR_UNKNOWN_PRODUCT,
7283 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7284 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7285 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7286 }
7287
7288 res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7289 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7290
7291 /* AuthorizedLUAApp value exists */
7292 sz = MAX_PATH;
7293 lstrcpyA(buf, "apple");
7294 r = pMsiGetProductInfoExA(prodcode, usersid,
7295 MSIINSTALLCONTEXT_USERMANAGED,
7296 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7297 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7298 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
7299 ok(sz == 4, "Expected 4, got %d\n", sz);
7300
7301 RegDeleteValueA(userkey, "AuthorizedLUAApp");
7302 RegDeleteValueA(userkey, "PackageName");
7303 RegDeleteValueA(userkey, "ProductIcon");
7304 RegDeleteValueA(userkey, "Version");
7305 RegDeleteValueA(userkey, "PackageCode");
7306 RegDeleteValueA(userkey, "AssignmentType");
7307 RegDeleteValueA(userkey, "ProductName");
7308 RegDeleteValueA(userkey, "Language");
7309 RegDeleteValueA(userkey, "Transforms");
7310 RegDeleteValueA(userkey, "RegOwner");
7311 RegDeleteValueA(userkey, "RegCompany");
7312 RegDeleteValueA(userkey, "ProductID");
7313 RegDeleteValueA(userkey, "DisplayVersion");
7314 RegDeleteValueA(userkey, "VersionMajor");
7315 RegDeleteValueA(userkey, "VersionMinor");
7316 RegDeleteValueA(userkey, "URLUpdateInfo");
7317 RegDeleteValueA(userkey, "URLInfoAbout");
7318 RegDeleteValueA(userkey, "Publisher");
7319 RegDeleteValueA(userkey, "LocalPackage");
7320 RegDeleteValueA(userkey, "InstallSource");
7321 RegDeleteValueA(userkey, "InstallLocation");
7322 RegDeleteValueA(userkey, "DisplayName");
7323 RegDeleteValueA(userkey, "InstallDate");
7324 RegDeleteValueA(userkey, "HelpTelephone");
7325 RegDeleteValueA(userkey, "HelpLink");
7326 delete_key(userkey, "", access & KEY_WOW64_64KEY);
7327 RegCloseKey(userkey);
7328 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7329 RegCloseKey(prodkey);
7330
7331 /* MSIINSTALLCONTEXT_MACHINE */
7332
7333 /* szUserSid is non-NULL */
7334 sz = MAX_PATH;
7335 lstrcpyA(buf, "apple");
7336 r = pMsiGetProductInfoExA(prodcode, usersid,
7337 MSIINSTALLCONTEXT_MACHINE,
7338 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
7339 ok(r == ERROR_INVALID_PARAMETER,
7340 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7341 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7342 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7343
7344 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
7345 lstrcatA(keypath, prod_squashed);
7346
7347 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
7348 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7349
7350 /* local system product key exists */
7351 sz = MAX_PATH;
7352 lstrcpyA(buf, "apple");
7353 r = pMsiGetProductInfoExA(prodcode, NULL,
7354 MSIINSTALLCONTEXT_MACHINE,
7355 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
7356 ok(r == ERROR_UNKNOWN_PRODUCT,
7357 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7358 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7359 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7360
7361 res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
7362 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7363
7364 /* InstallProperties key exists */
7365 sz = MAX_PATH;
7366 lstrcpyA(buf, "apple");
7367 r = pMsiGetProductInfoExA(prodcode, NULL,
7368 MSIINSTALLCONTEXT_MACHINE,
7369 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
7370 ok(r == ERROR_UNKNOWN_PRODUCT,
7371 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7372 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7373 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7374
7375 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7376 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7377
7378 /* LocalPackage value exists */
7379 sz = MAX_PATH;
7380 lstrcpyA(buf, "apple");
7381 r = pMsiGetProductInfoExA(prodcode, NULL,
7382 MSIINSTALLCONTEXT_MACHINE,
7383 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
7384 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7385 ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
7386 ok(sz == 1, "Expected 1, got %d\n", sz);
7387
7388 res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7390
7391 /* HelpLink value exists */
7392 sz = MAX_PATH;
7393 lstrcpyA(buf, "apple");
7394 r = pMsiGetProductInfoExA(prodcode, NULL,
7395 MSIINSTALLCONTEXT_MACHINE,
7396 INSTALLPROPERTY_HELPLINK, buf, &sz);
7397 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7398 ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
7399 ok(sz == 4, "Expected 4, got %d\n", sz);
7400
7401 res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7402 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7403
7404 /* HelpTelephone value exists */
7405 sz = MAX_PATH;
7406 lstrcpyA(buf, "apple");
7407 r = pMsiGetProductInfoExA(prodcode, NULL,
7408 MSIINSTALLCONTEXT_MACHINE,
7409 INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
7410 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7411 ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
7412 ok(sz == 5, "Expected 5, got %d\n", sz);
7413
7414 res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7415 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7416
7417 /* InstallDate value exists */
7418 sz = MAX_PATH;
7419 lstrcpyA(buf, "apple");
7420 r = pMsiGetProductInfoExA(prodcode, NULL,
7421 MSIINSTALLCONTEXT_MACHINE,
7422 INSTALLPROPERTY_INSTALLDATE, buf, &sz);
7423 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7424 ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
7425 ok(sz == 4, "Expected 4, got %d\n", sz);
7426
7427 res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7428 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7429
7430 /* DisplayName value exists */
7431 sz = MAX_PATH;
7432 lstrcpyA(buf, "apple");
7433 r = pMsiGetProductInfoExA(prodcode, NULL,
7434 MSIINSTALLCONTEXT_MACHINE,
7435 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
7436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7437 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
7438 ok(sz == 4, "Expected 4, got %d\n", sz);
7439
7440 res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7441 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7442
7443 /* InstallLocation value exists */
7444 sz = MAX_PATH;
7445 lstrcpyA(buf, "apple");
7446 r = pMsiGetProductInfoExA(prodcode, NULL,
7447 MSIINSTALLCONTEXT_MACHINE,
7448 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
7449 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7450 ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
7451 ok(sz == 3, "Expected 3, got %d\n", sz);
7452
7453 res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7454 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7455
7456 /* InstallSource value exists */
7457 sz = MAX_PATH;
7458 lstrcpyA(buf, "apple");
7459 r = pMsiGetProductInfoExA(prodcode, NULL,
7460 MSIINSTALLCONTEXT_MACHINE,
7461 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
7462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7463 ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
7464 ok(sz == 6, "Expected 6, got %d\n", sz);
7465
7466 res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7467 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7468
7469 /* LocalPackage value exists */
7470 sz = MAX_PATH;
7471 lstrcpyA(buf, "apple");
7472 r = pMsiGetProductInfoExA(prodcode, NULL,
7473 MSIINSTALLCONTEXT_MACHINE,
7474 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
7475 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7476 ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
7477 ok(sz == 5, "Expected 5, got %d\n", sz);
7478
7479 res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7481
7482 /* Publisher value exists */
7483 sz = MAX_PATH;
7484 lstrcpyA(buf, "apple");
7485 r = pMsiGetProductInfoExA(prodcode, NULL,
7486 MSIINSTALLCONTEXT_MACHINE,
7487 INSTALLPROPERTY_PUBLISHER, buf, &sz);
7488 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7489 ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
7490 ok(sz == 3, "Expected 3, got %d\n", sz);
7491
7492 res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7493 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7494
7495 /* URLInfoAbout value exists */
7496 sz = MAX_PATH;
7497 lstrcpyA(buf, "apple");
7498 r = pMsiGetProductInfoExA(prodcode, NULL,
7499 MSIINSTALLCONTEXT_MACHINE,
7500 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
7501 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7502 ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
7503 ok(sz == 5, "Expected 5, got %d\n", sz);
7504
7505 res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7506 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7507
7508 /* URLUpdateInfo value exists */
7509 sz = MAX_PATH;
7510 lstrcpyA(buf, "apple");
7511 r = pMsiGetProductInfoExA(prodcode, NULL,
7512 MSIINSTALLCONTEXT_MACHINE,
7513 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
7514 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7515 ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
7516 ok(sz == 6, "Expected 6, got %d\n", sz);
7517
7518 res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7519 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7520
7521 /* VersionMinor value exists */
7522 sz = MAX_PATH;
7523 lstrcpyA(buf, "apple");
7524 r = pMsiGetProductInfoExA(prodcode, NULL,
7525 MSIINSTALLCONTEXT_MACHINE,
7526 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
7527 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7528 ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
7529 ok(sz == 1, "Expected 1, got %d\n", sz);
7530
7531 res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7532 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7533
7534 /* VersionMajor value exists */
7535 sz = MAX_PATH;
7536 lstrcpyA(buf, "apple");
7537 r = pMsiGetProductInfoExA(prodcode, NULL,
7538 MSIINSTALLCONTEXT_MACHINE,
7539 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
7540 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7541 ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
7542 ok(sz == 1, "Expected 1, got %d\n", sz);
7543
7544 res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7545 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7546
7547 /* DisplayVersion value exists */
7548 sz = MAX_PATH;
7549 lstrcpyA(buf, "apple");
7550 r = pMsiGetProductInfoExA(prodcode, NULL,
7551 MSIINSTALLCONTEXT_MACHINE,
7552 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
7553 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7554 ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
7555 ok(sz == 5, "Expected 5, got %d\n", sz);
7556
7557 res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7558 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7559
7560 /* ProductID value exists */
7561 sz = MAX_PATH;
7562 lstrcpyA(buf, "apple");
7563 r = pMsiGetProductInfoExA(prodcode, NULL,
7564 MSIINSTALLCONTEXT_MACHINE,
7565 INSTALLPROPERTY_PRODUCTID, buf, &sz);
7566 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7567 ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
7568 ok(sz == 2, "Expected 2, got %d\n", sz);
7569
7570 res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7571 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7572
7573 /* RegCompany value exists */
7574 sz = MAX_PATH;
7575 lstrcpyA(buf, "apple");
7576 r = pMsiGetProductInfoExA(prodcode, NULL,
7577 MSIINSTALLCONTEXT_MACHINE,
7578 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
7579 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7580 ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
7581 ok(sz == 4, "Expected 4, got %d\n", sz);
7582
7583 res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7584 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7585
7586 /* RegOwner value exists */
7587 sz = MAX_PATH;
7588 lstrcpyA(buf, "apple");
7589 r = pMsiGetProductInfoExA(prodcode, NULL,
7590 MSIINSTALLCONTEXT_MACHINE,
7591 INSTALLPROPERTY_REGOWNER, buf, &sz);
7592 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7593 ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
7594 ok(sz == 5, "Expected 5, got %d\n", sz);
7595
7596 res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7597 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7598
7599 /* Transforms value exists */
7600 sz = MAX_PATH;
7601 lstrcpyA(buf, "apple");
7602 r = pMsiGetProductInfoExA(prodcode, NULL,
7603 MSIINSTALLCONTEXT_MACHINE,
7604 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
7605 ok(r == ERROR_UNKNOWN_PRODUCT,
7606 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7607 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7608 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7609
7610 res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
7611 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7612
7613 /* Language value exists */
7614 sz = MAX_PATH;
7615 lstrcpyA(buf, "apple");
7616 r = pMsiGetProductInfoExA(prodcode, NULL,
7617 MSIINSTALLCONTEXT_MACHINE,
7618 INSTALLPROPERTY_LANGUAGE, buf, &sz);
7619 ok(r == ERROR_UNKNOWN_PRODUCT,
7620 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7621 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7622 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7623
7624 res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
7625 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7626
7627 /* ProductName value exists */
7628 sz = MAX_PATH;
7629 lstrcpyA(buf, "apple");
7630 r = pMsiGetProductInfoExA(prodcode, NULL,
7631 MSIINSTALLCONTEXT_MACHINE,
7632 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
7633 ok(r == ERROR_UNKNOWN_PRODUCT,
7634 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7635 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7636 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7637
7638 res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
7639 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7640
7641 /* FIXME */
7642
7643 /* AssignmentType value exists */
7644 sz = MAX_PATH;
7645 lstrcpyA(buf, "apple");
7646 r = pMsiGetProductInfoExA(prodcode, NULL,
7647 MSIINSTALLCONTEXT_MACHINE,
7648 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
7649 ok(r == ERROR_UNKNOWN_PRODUCT,
7650 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7651 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7652 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7653
7654 res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
7655 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7656
7657 /* PackageCode value exists */
7658 sz = MAX_PATH;
7659 lstrcpyA(buf, "apple");
7660 r = pMsiGetProductInfoExA(prodcode, NULL,
7661 MSIINSTALLCONTEXT_MACHINE,
7662 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
7663 ok(r == ERROR_UNKNOWN_PRODUCT,
7664 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7665 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7666 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7667
7668 res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
7669 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7670
7671 /* Version value exists */
7672 sz = MAX_PATH;
7673 lstrcpyA(buf, "apple");
7674 r = pMsiGetProductInfoExA(prodcode, NULL,
7675 MSIINSTALLCONTEXT_MACHINE,
7676 INSTALLPROPERTY_VERSION, buf, &sz);
7677 ok(r == ERROR_UNKNOWN_PRODUCT,
7678 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7679 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7680 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7681
7682 res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
7683 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7684
7685 /* ProductIcon value exists */
7686 sz = MAX_PATH;
7687 lstrcpyA(buf, "apple");
7688 r = pMsiGetProductInfoExA(prodcode, NULL,
7689 MSIINSTALLCONTEXT_MACHINE,
7690 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
7691 ok(r == ERROR_UNKNOWN_PRODUCT,
7692 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7693 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7694 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7695
7696 res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
7697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7698
7699 /* PackageName value exists */
7700 sz = MAX_PATH;
7701 lstrcpyA(buf, "apple");
7702 r = pMsiGetProductInfoExA(prodcode, NULL,
7703 MSIINSTALLCONTEXT_MACHINE,
7704 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
7705 ok(r == ERROR_UNKNOWN_PRODUCT,
7706 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7707 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7708 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7709
7710 res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
7711 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7712
7713 /* AuthorizedLUAApp value exists */
7714 sz = MAX_PATH;
7715 lstrcpyA(buf, "apple");
7716 r = pMsiGetProductInfoExA(prodcode, NULL,
7717 MSIINSTALLCONTEXT_MACHINE,
7718 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
7719 ok(r == ERROR_UNKNOWN_PRODUCT,
7720 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7721 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7722 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7723
7724 RegDeleteValueA(propkey, "AuthorizedLUAApp");
7725 RegDeleteValueA(propkey, "PackageName");
7726 RegDeleteValueA(propkey, "ProductIcon");
7727 RegDeleteValueA(propkey, "Version");
7728 RegDeleteValueA(propkey, "PackageCode");
7729 RegDeleteValueA(propkey, "AssignmentType");
7730 RegDeleteValueA(propkey, "ProductName");
7731 RegDeleteValueA(propkey, "Language");
7732 RegDeleteValueA(propkey, "Transforms");
7733 RegDeleteValueA(propkey, "RegOwner");
7734 RegDeleteValueA(propkey, "RegCompany");
7735 RegDeleteValueA(propkey, "ProductID");
7736 RegDeleteValueA(propkey, "DisplayVersion");
7737 RegDeleteValueA(propkey, "VersionMajor");
7738 RegDeleteValueA(propkey, "VersionMinor");
7739 RegDeleteValueA(propkey, "URLUpdateInfo");
7740 RegDeleteValueA(propkey, "URLInfoAbout");
7741 RegDeleteValueA(propkey, "Publisher");
7742 RegDeleteValueA(propkey, "LocalPackage");
7743 RegDeleteValueA(propkey, "InstallSource");
7744 RegDeleteValueA(propkey, "InstallLocation");
7745 RegDeleteValueA(propkey, "DisplayName");
7746 RegDeleteValueA(propkey, "InstallDate");
7747 RegDeleteValueA(propkey, "HelpTelephone");
7748 RegDeleteValueA(propkey, "HelpLink");
7749 RegDeleteValueA(propkey, "LocalPackage");
7750 delete_key(propkey, "", access & KEY_WOW64_64KEY);
7751 RegCloseKey(propkey);
7752 delete_key(localkey, "", access & KEY_WOW64_64KEY);
7753 RegCloseKey(localkey);
7754
7755 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7756 lstrcatA(keypath, prod_squashed);
7757
7758 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7759 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7760
7761 /* local classes product key exists */
7762 sz = MAX_PATH;
7763 lstrcpyA(buf, "apple");
7764 r = pMsiGetProductInfoExA(prodcode, NULL,
7765 MSIINSTALLCONTEXT_MACHINE,
7766 INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
7767 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7768 ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
7769 ok(sz == 1, "Expected 1, got %d\n", sz);
7770
7771 res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
7772 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7773
7774 /* HelpLink value exists */
7775 sz = MAX_PATH;
7776 lstrcpyA(buf, "apple");
7777 r = pMsiGetProductInfoExA(prodcode, NULL,
7778 MSIINSTALLCONTEXT_MACHINE,
7779 INSTALLPROPERTY_HELPLINK, 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(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
7786 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7787
7788 /* HelpTelephone value exists */
7789 sz = MAX_PATH;
7790 lstrcpyA(buf, "apple");
7791 r = pMsiGetProductInfoExA(prodcode, NULL,
7792 MSIINSTALLCONTEXT_MACHINE,
7793 INSTALLPROPERTY_HELPTELEPHONE, 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(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
7800 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7801
7802 /* InstallDate value exists */
7803 sz = MAX_PATH;
7804 lstrcpyA(buf, "apple");
7805 r = pMsiGetProductInfoExA(prodcode, NULL,
7806 MSIINSTALLCONTEXT_MACHINE,
7807 INSTALLPROPERTY_INSTALLDATE, 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(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
7814 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7815
7816 /* DisplayName value exists */
7817 sz = MAX_PATH;
7818 lstrcpyA(buf, "apple");
7819 r = pMsiGetProductInfoExA(prodcode, NULL,
7820 MSIINSTALLCONTEXT_MACHINE,
7821 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
7822 ok(r == ERROR_UNKNOWN_PROPERTY,
7823 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7824 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7825 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7826
7827 res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
7828 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7829
7830 /* InstallLocation value exists */
7831 sz = MAX_PATH;
7832 lstrcpyA(buf, "apple");
7833 r = pMsiGetProductInfoExA(prodcode, NULL,
7834 MSIINSTALLCONTEXT_MACHINE,
7835 INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
7836 ok(r == ERROR_UNKNOWN_PROPERTY,
7837 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7838 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7839 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7840
7841 res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
7842 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7843
7844 /* InstallSource value exists */
7845 sz = MAX_PATH;
7846 lstrcpyA(buf, "apple");
7847 r = pMsiGetProductInfoExA(prodcode, NULL,
7848 MSIINSTALLCONTEXT_MACHINE,
7849 INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
7850 ok(r == ERROR_UNKNOWN_PROPERTY,
7851 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7852 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7853 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7854
7855 res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
7856 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7857
7858 /* LocalPackage value exists */
7859 sz = MAX_PATH;
7860 lstrcpyA(buf, "apple");
7861 r = pMsiGetProductInfoExA(prodcode, NULL,
7862 MSIINSTALLCONTEXT_MACHINE,
7863 INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
7864 ok(r == ERROR_UNKNOWN_PROPERTY,
7865 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7866 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7867 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7868
7869 res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
7870 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7871
7872 /* Publisher value exists */
7873 sz = MAX_PATH;
7874 lstrcpyA(buf, "apple");
7875 r = pMsiGetProductInfoExA(prodcode, NULL,
7876 MSIINSTALLCONTEXT_MACHINE,
7877 INSTALLPROPERTY_PUBLISHER, buf, &sz);
7878 ok(r == ERROR_UNKNOWN_PROPERTY,
7879 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7880 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7881 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7882
7883 res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
7884 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7885
7886 /* URLInfoAbout value exists */
7887 sz = MAX_PATH;
7888 lstrcpyA(buf, "apple");
7889 r = pMsiGetProductInfoExA(prodcode, NULL,
7890 MSIINSTALLCONTEXT_MACHINE,
7891 INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
7892 ok(r == ERROR_UNKNOWN_PROPERTY,
7893 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7894 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7895 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7896
7897 res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
7898 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7899
7900 /* URLUpdateInfo value exists */
7901 sz = MAX_PATH;
7902 lstrcpyA(buf, "apple");
7903 r = pMsiGetProductInfoExA(prodcode, NULL,
7904 MSIINSTALLCONTEXT_MACHINE,
7905 INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
7906 ok(r == ERROR_UNKNOWN_PROPERTY,
7907 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7908 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7909 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7910
7911 res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
7912 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7913
7914 /* VersionMinor value exists */
7915 sz = MAX_PATH;
7916 lstrcpyA(buf, "apple");
7917 r = pMsiGetProductInfoExA(prodcode, NULL,
7918 MSIINSTALLCONTEXT_MACHINE,
7919 INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
7920 ok(r == ERROR_UNKNOWN_PROPERTY,
7921 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7922 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7923 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7924
7925 res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
7926 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7927
7928 /* VersionMajor value exists */
7929 sz = MAX_PATH;
7930 lstrcpyA(buf, "apple");
7931 r = pMsiGetProductInfoExA(prodcode, NULL,
7932 MSIINSTALLCONTEXT_MACHINE,
7933 INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
7934 ok(r == ERROR_UNKNOWN_PROPERTY,
7935 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7936 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7937 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7938
7939 res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
7940 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7941
7942 /* DisplayVersion value exists */
7943 sz = MAX_PATH;
7944 lstrcpyA(buf, "apple");
7945 r = pMsiGetProductInfoExA(prodcode, NULL,
7946 MSIINSTALLCONTEXT_MACHINE,
7947 INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
7948 ok(r == ERROR_UNKNOWN_PROPERTY,
7949 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7950 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7951 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7952
7953 res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
7954 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7955
7956 /* ProductID value exists */
7957 sz = MAX_PATH;
7958 lstrcpyA(buf, "apple");
7959 r = pMsiGetProductInfoExA(prodcode, NULL,
7960 MSIINSTALLCONTEXT_MACHINE,
7961 INSTALLPROPERTY_PRODUCTID, buf, &sz);
7962 ok(r == ERROR_UNKNOWN_PROPERTY,
7963 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7964 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7965 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7966
7967 res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
7968 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7969
7970 /* RegCompany value exists */
7971 sz = MAX_PATH;
7972 lstrcpyA(buf, "apple");
7973 r = pMsiGetProductInfoExA(prodcode, NULL,
7974 MSIINSTALLCONTEXT_MACHINE,
7975 INSTALLPROPERTY_REGCOMPANY, buf, &sz);
7976 ok(r == ERROR_UNKNOWN_PROPERTY,
7977 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7978 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7979 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7980
7981 res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7982 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7983
7984 /* RegOwner value exists */
7985 sz = MAX_PATH;
7986 lstrcpyA(buf, "apple");
7987 r = pMsiGetProductInfoExA(prodcode, NULL,
7988 MSIINSTALLCONTEXT_MACHINE,
7989 INSTALLPROPERTY_REGOWNER, buf, &sz);
7990 ok(r == ERROR_UNKNOWN_PROPERTY,
7991 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
7992 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
7993 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
7994
7995 res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
7996 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7997
7998 /* Transforms value exists */
7999 sz = MAX_PATH;
8000 lstrcpyA(buf, "apple");
8001 r = pMsiGetProductInfoExA(prodcode, NULL,
8002 MSIINSTALLCONTEXT_MACHINE,
8003 INSTALLPROPERTY_TRANSFORMS, buf, &sz);
8004 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8005 ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
8006 ok(sz == 5, "Expected 5, got %d\n", sz);
8007
8008 res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
8009 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8010
8011 /* Language value exists */
8012 sz = MAX_PATH;
8013 lstrcpyA(buf, "apple");
8014 r = pMsiGetProductInfoExA(prodcode, NULL,
8015 MSIINSTALLCONTEXT_MACHINE,
8016 INSTALLPROPERTY_LANGUAGE, buf, &sz);
8017 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8018 ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
8019 ok(sz == 4, "Expected 4, got %d\n", sz);
8020
8021 res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
8022 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8023
8024 /* ProductName value exists */
8025 sz = MAX_PATH;
8026 lstrcpyA(buf, "apple");
8027 r = pMsiGetProductInfoExA(prodcode, NULL,
8028 MSIINSTALLCONTEXT_MACHINE,
8029 INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
8030 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8031 ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
8032 ok(sz == 4, "Expected 4, got %d\n", sz);
8033
8034 res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
8035 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8036
8037 /* FIXME */
8038
8039 /* AssignmentType value exists */
8040 sz = MAX_PATH;
8041 lstrcpyA(buf, "apple");
8042 r = pMsiGetProductInfoExA(prodcode, NULL,
8043 MSIINSTALLCONTEXT_MACHINE,
8044 INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
8045 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8046 ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
8047 ok(sz == 0, "Expected 0, got %d\n", sz);
8048
8049 res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
8050 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8051
8052 /* FIXME */
8053
8054 /* PackageCode value exists */
8055 sz = MAX_PATH;
8056 lstrcpyA(buf, "apple");
8057 r = pMsiGetProductInfoExA(prodcode, NULL,
8058 MSIINSTALLCONTEXT_MACHINE,
8059 INSTALLPROPERTY_PACKAGECODE, buf, &sz);
8060 todo_wine
8061 {
8062 ok(r == ERROR_BAD_CONFIGURATION,
8063 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8064 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8065 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8066 }
8067
8068 res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
8069 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8070
8071 /* Version value exists */
8072 sz = MAX_PATH;
8073 lstrcpyA(buf, "apple");
8074 r = pMsiGetProductInfoExA(prodcode, NULL,
8075 MSIINSTALLCONTEXT_MACHINE,
8076 INSTALLPROPERTY_VERSION, buf, &sz);
8077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8078 ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
8079 ok(sz == 3, "Expected 3, got %d\n", sz);
8080
8081 res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
8082 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8083
8084 /* ProductIcon value exists */
8085 sz = MAX_PATH;
8086 lstrcpyA(buf, "apple");
8087 r = pMsiGetProductInfoExA(prodcode, NULL,
8088 MSIINSTALLCONTEXT_MACHINE,
8089 INSTALLPROPERTY_PRODUCTICON, buf, &sz);
8090 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8091 ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
8092 ok(sz == 4, "Expected 4, got %d\n", sz);
8093
8094 res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
8095 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8096
8097 /* PackageName value exists */
8098 sz = MAX_PATH;
8099 lstrcpyA(buf, "apple");
8100 r = pMsiGetProductInfoExA(prodcode, NULL,
8101 MSIINSTALLCONTEXT_MACHINE,
8102 INSTALLPROPERTY_PACKAGENAME, buf, &sz);
8103 todo_wine
8104 {
8105 ok(r == ERROR_UNKNOWN_PRODUCT,
8106 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8107 ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
8108 ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
8109 }
8110
8111 res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
8112 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8113
8114 /* AuthorizedLUAApp value exists */
8115 sz = MAX_PATH;
8116 lstrcpyA(buf, "apple");
8117 r = pMsiGetProductInfoExA(prodcode, NULL,
8118 MSIINSTALLCONTEXT_MACHINE,
8119 INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
8120 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8121 ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
8122 ok(sz == 4, "Expected 4, got %d\n", sz);
8123
8124 RegDeleteValueA(prodkey, "AuthorizedLUAApp");
8125 RegDeleteValueA(prodkey, "PackageName");
8126 RegDeleteValueA(prodkey, "ProductIcon");
8127 RegDeleteValueA(prodkey, "Version");
8128 RegDeleteValueA(prodkey, "PackageCode");
8129 RegDeleteValueA(prodkey, "AssignmentType");
8130 RegDeleteValueA(prodkey, "ProductName");
8131 RegDeleteValueA(prodkey, "Language");
8132 RegDeleteValueA(prodkey, "Transforms");
8133 RegDeleteValueA(prodkey, "RegOwner");
8134 RegDeleteValueA(prodkey, "RegCompany");
8135 RegDeleteValueA(prodkey, "ProductID");
8136 RegDeleteValueA(prodkey, "DisplayVersion");
8137 RegDeleteValueA(prodkey, "VersionMajor");
8138 RegDeleteValueA(prodkey, "VersionMinor");
8139 RegDeleteValueA(prodkey, "URLUpdateInfo");
8140 RegDeleteValueA(prodkey, "URLInfoAbout");
8141 RegDeleteValueA(prodkey, "Publisher");
8142 RegDeleteValueA(prodkey, "LocalPackage");
8143 RegDeleteValueA(prodkey, "InstallSource");
8144 RegDeleteValueA(prodkey, "InstallLocation");
8145 RegDeleteValueA(prodkey, "DisplayName");
8146 RegDeleteValueA(prodkey, "InstallDate");
8147 RegDeleteValueA(prodkey, "HelpTelephone");
8148 RegDeleteValueA(prodkey, "HelpLink");
8149 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8150 RegCloseKey(prodkey);
8151 LocalFree(usersid);
8152 }
8153
8154 #define INIT_USERINFO() \
8155 lstrcpyA(user, "apple"); \
8156 lstrcpyA(org, "orange"); \
8157 lstrcpyA(serial, "banana"); \
8158 usersz = orgsz = serialsz = MAX_PATH;
8159
8160 static void test_MsiGetUserInfo(void)
8161 {
8162 USERINFOSTATE state;
8163 CHAR user[MAX_PATH];
8164 CHAR org[MAX_PATH];
8165 CHAR serial[MAX_PATH];
8166 DWORD usersz, orgsz, serialsz;
8167 CHAR keypath[MAX_PATH * 2];
8168 CHAR prodcode[MAX_PATH];
8169 CHAR prod_squashed[MAX_PATH];
8170 HKEY prodkey, userprod, props;
8171 LPSTR usersid;
8172 LONG res;
8173 REGSAM access = KEY_ALL_ACCESS;
8174
8175 create_test_guid(prodcode, prod_squashed);
8176 usersid = get_user_sid();
8177
8178 if (is_wow64)
8179 access |= KEY_WOW64_64KEY;
8180
8181 /* NULL szProduct */
8182 INIT_USERINFO();
8183 state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
8184 ok(state == USERINFOSTATE_INVALIDARG,
8185 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8186 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8187 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8188 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8189 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8190 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8191 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8192
8193 /* empty szProductCode */
8194 INIT_USERINFO();
8195 state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
8196 ok(state == USERINFOSTATE_INVALIDARG,
8197 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8198 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8199 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8200 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8201 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8202 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8203 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8204
8205 /* garbage szProductCode */
8206 INIT_USERINFO();
8207 state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
8208 ok(state == USERINFOSTATE_INVALIDARG,
8209 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8210 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8211 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8212 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8213 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8214 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8215 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8216
8217 /* guid without brackets */
8218 INIT_USERINFO();
8219 state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
8220 user, &usersz, org, &orgsz, serial, &serialsz);
8221 ok(state == USERINFOSTATE_INVALIDARG,
8222 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8223 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8224 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8225 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8226 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8227 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8228 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8229
8230 /* guid with brackets */
8231 INIT_USERINFO();
8232 state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
8233 user, &usersz, org, &orgsz, serial, &serialsz);
8234 ok(state == USERINFOSTATE_UNKNOWN,
8235 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8236 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8237 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8238 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8239 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8240 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8241 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8242
8243 /* NULL lpUserNameBuf */
8244 INIT_USERINFO();
8245 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8246 ok(state == USERINFOSTATE_UNKNOWN,
8247 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8248 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8249 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8250 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8251 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8252 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8253
8254 /* NULL pcchUserNameBuf */
8255 INIT_USERINFO();
8256 state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
8257 ok(state == USERINFOSTATE_INVALIDARG,
8258 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8259 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8260 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8261 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8262 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8263 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8264
8265 /* both lpUserNameBuf and pcchUserNameBuf NULL */
8266 INIT_USERINFO();
8267 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8268 ok(state == USERINFOSTATE_UNKNOWN,
8269 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8270 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8271 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8272 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8273 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8274
8275 /* NULL lpOrgNameBuf */
8276 INIT_USERINFO();
8277 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
8278 ok(state == USERINFOSTATE_UNKNOWN,
8279 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8280 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8281 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8282 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8283 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8284 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8285
8286 /* NULL pcchOrgNameBuf */
8287 INIT_USERINFO();
8288 state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
8289 ok(state == USERINFOSTATE_INVALIDARG,
8290 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8291 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8292 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8293 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8294 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8295 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8296
8297 /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
8298 INIT_USERINFO();
8299 state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
8300 ok(state == USERINFOSTATE_UNKNOWN,
8301 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8302 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8303 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8304 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8305 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8306
8307 /* NULL lpSerialBuf */
8308 INIT_USERINFO();
8309 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
8310 ok(state == USERINFOSTATE_UNKNOWN,
8311 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8312 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8313 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8314 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8315 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8316 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8317
8318 /* NULL pcchSerialBuf */
8319 INIT_USERINFO();
8320 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
8321 ok(state == USERINFOSTATE_INVALIDARG,
8322 "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
8323 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8324 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8325 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8326 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8327 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8328
8329 /* both lpSerialBuf and pcchSerialBuf NULL */
8330 INIT_USERINFO();
8331 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
8332 ok(state == USERINFOSTATE_UNKNOWN,
8333 "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
8334 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8335 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8336 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8337 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8338
8339 /* MSIINSTALLCONTEXT_USERMANAGED */
8340
8341 /* create local system product key */
8342 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
8343 lstrcatA(keypath, usersid);
8344 lstrcatA(keypath, "\\Installer\\Products\\");
8345 lstrcatA(keypath, prod_squashed);
8346
8347 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8348 if (res == ERROR_ACCESS_DENIED)
8349 {
8350 skip("Not enough rights to perform tests\n");
8351 LocalFree(usersid);
8352 return;
8353 }
8354 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8355
8356 /* managed product key exists */
8357 INIT_USERINFO();
8358 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8359 ok(state == USERINFOSTATE_ABSENT,
8360 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8361 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8362 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8363 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8364 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8365 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8366 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8367
8368 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8369 lstrcatA(keypath, "Installer\\UserData\\");
8370 lstrcatA(keypath, usersid);
8371 lstrcatA(keypath, "\\Products\\");
8372 lstrcatA(keypath, prod_squashed);
8373
8374 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8375 if (res == ERROR_ACCESS_DENIED)
8376 {
8377 skip("Not enough rights to perform tests\n");
8378 LocalFree(usersid);
8379 return;
8380 }
8381 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8382
8383 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8384 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8385
8386 /* InstallProperties key exists */
8387 INIT_USERINFO();
8388 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8389 ok(state == USERINFOSTATE_ABSENT,
8390 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8391 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8392 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8393 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8394 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8395 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8396 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8397
8398 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8399 INIT_USERINFO();
8400 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8401 ok(state == USERINFOSTATE_ABSENT,
8402 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8403 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8404 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8405 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8406 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8407
8408 /* RegOwner, RegCompany don't exist, out params are NULL */
8409 INIT_USERINFO();
8410 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8411 ok(state == USERINFOSTATE_ABSENT,
8412 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8413 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8414 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8415
8416 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8417 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8418
8419 /* RegOwner value exists */
8420 INIT_USERINFO();
8421 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8422 ok(state == USERINFOSTATE_ABSENT,
8423 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8424 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8425 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8426 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8427 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8428 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8429 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8430
8431 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8432 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8433
8434 /* RegCompany value exists */
8435 INIT_USERINFO();
8436 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8437 ok(state == USERINFOSTATE_ABSENT,
8438 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8439 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8440 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8441 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8442 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8443 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8444 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8445
8446 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8447 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8448
8449 /* ProductID value exists */
8450 INIT_USERINFO();
8451 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8452 ok(state == USERINFOSTATE_PRESENT,
8453 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8454 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8455 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8456 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8457 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8458 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8459 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8460
8461 /* pcchUserNameBuf is too small */
8462 INIT_USERINFO();
8463 usersz = 0;
8464 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8465 ok(state == USERINFOSTATE_MOREDATA,
8466 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8467 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8468 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8469 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8470 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8471 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8472 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8473
8474 /* pcchUserNameBuf has no room for NULL terminator */
8475 INIT_USERINFO();
8476 usersz = 5;
8477 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8478 ok(state == USERINFOSTATE_MOREDATA,
8479 "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
8480 todo_wine
8481 {
8482 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8483 }
8484 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8485 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8486 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8487 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8488 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8489
8490 /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
8491 INIT_USERINFO();
8492 usersz = 0;
8493 state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
8494 ok(state == USERINFOSTATE_PRESENT,
8495 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8496 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8497 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8498 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8499 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8500 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8501 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8502
8503 RegDeleteValueA(props, "ProductID");
8504 RegDeleteValueA(props, "RegCompany");
8505 RegDeleteValueA(props, "RegOwner");
8506 delete_key(props, "", access & KEY_WOW64_64KEY);
8507 RegCloseKey(props);
8508 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8509 RegCloseKey(userprod);
8510 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8511 RegCloseKey(prodkey);
8512
8513 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8514
8515 /* create local system product key */
8516 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8517 lstrcatA(keypath, prod_squashed);
8518
8519 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8520 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8521
8522 /* product key exists */
8523 INIT_USERINFO();
8524 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8525 ok(state == USERINFOSTATE_ABSENT,
8526 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8527 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8528 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8529 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8530 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8531 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8532 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8533
8534 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8535 lstrcatA(keypath, "Installer\\UserData\\");
8536 lstrcatA(keypath, usersid);
8537 lstrcatA(keypath, "\\Products\\");
8538 lstrcatA(keypath, prod_squashed);
8539
8540 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8541 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8542
8543 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8544 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8545
8546 /* InstallProperties key exists */
8547 INIT_USERINFO();
8548 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8549 ok(state == USERINFOSTATE_ABSENT,
8550 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8551 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8552 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8553 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8554 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8555 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8556 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8557
8558 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8559 INIT_USERINFO();
8560 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8561 ok(state == USERINFOSTATE_ABSENT,
8562 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8563 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8564 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8565 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8566 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8567
8568 /* RegOwner, RegCompany don't exist, out params are NULL */
8569 INIT_USERINFO();
8570 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8571 ok(state == USERINFOSTATE_ABSENT,
8572 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8573 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8574 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8575
8576 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8577 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8578
8579 /* RegOwner value exists */
8580 INIT_USERINFO();
8581 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8582 ok(state == USERINFOSTATE_ABSENT,
8583 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8584 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8585 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8586 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8587 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8588 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8589 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8590
8591 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8592 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8593
8594 /* RegCompany value exists */
8595 INIT_USERINFO();
8596 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8597 ok(state == USERINFOSTATE_ABSENT,
8598 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8599 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8600 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8601 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8602 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8603 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8604 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8605
8606 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8607 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8608
8609 /* ProductID value exists */
8610 INIT_USERINFO();
8611 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8612 ok(state == USERINFOSTATE_PRESENT,
8613 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8614 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8615 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8616 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8617 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8618 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8619 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8620
8621 RegDeleteValueA(props, "ProductID");
8622 RegDeleteValueA(props, "RegCompany");
8623 RegDeleteValueA(props, "RegOwner");
8624 delete_key(props, "", access & KEY_WOW64_64KEY);
8625 RegCloseKey(props);
8626 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8627 RegCloseKey(userprod);
8628 RegDeleteKeyA(prodkey, "");
8629 RegCloseKey(prodkey);
8630
8631 /* MSIINSTALLCONTEXT_MACHINE */
8632
8633 /* create local system product key */
8634 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8635 lstrcatA(keypath, prod_squashed);
8636
8637 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8638 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8639
8640 /* product key exists */
8641 INIT_USERINFO();
8642 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8643 ok(state == USERINFOSTATE_ABSENT,
8644 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8645 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8646 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8647 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8648 ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
8649 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8650 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8651
8652 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8653 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
8654 lstrcatA(keypath, "\\Products\\");
8655 lstrcatA(keypath, prod_squashed);
8656
8657 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
8658 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8659
8660 res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8661 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8662
8663 /* InstallProperties key exists */
8664 INIT_USERINFO();
8665 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8666 ok(state == USERINFOSTATE_ABSENT,
8667 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8668 ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
8669 ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
8670 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8671 ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
8672 ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
8673 ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
8674
8675 /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
8676 INIT_USERINFO();
8677 state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
8678 ok(state == USERINFOSTATE_ABSENT,
8679 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8680 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8681 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8682 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8683 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8684
8685 /* RegOwner, RegCompany don't exist, out params are NULL */
8686 INIT_USERINFO();
8687 state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
8688 ok(state == USERINFOSTATE_ABSENT,
8689 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8690 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8691 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8692
8693 res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
8694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8695
8696 /* RegOwner value exists */
8697 INIT_USERINFO();
8698 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8699 ok(state == USERINFOSTATE_ABSENT,
8700 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8701 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8702 ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
8703 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8704 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8705 ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
8706 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8707
8708 res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
8709 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8710
8711 /* RegCompany value exists */
8712 INIT_USERINFO();
8713 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8714 ok(state == USERINFOSTATE_ABSENT,
8715 "Expected USERINFOSTATE_ABSENT, got %d\n", state);
8716 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8717 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8718 ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
8719 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8720 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8721 ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
8722
8723 res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
8724 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8725
8726 /* ProductID value exists */
8727 INIT_USERINFO();
8728 state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
8729 ok(state == USERINFOSTATE_PRESENT,
8730 "Expected USERINFOSTATE_PRESENT, got %d\n", state);
8731 ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
8732 ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
8733 ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
8734 ok(usersz == 5, "Expected 5, got %d\n", usersz);
8735 ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
8736 ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
8737
8738 RegDeleteValueA(props, "ProductID");
8739 RegDeleteValueA(props, "RegCompany");
8740 RegDeleteValueA(props, "RegOwner");
8741 delete_key(props, "", access & KEY_WOW64_64KEY);
8742 RegCloseKey(props);
8743 delete_key(userprod, "", access & KEY_WOW64_64KEY);
8744 RegCloseKey(userprod);
8745 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8746 RegCloseKey(prodkey);
8747 LocalFree(usersid);
8748 }
8749
8750 static void test_MsiOpenProduct(void)
8751 {
8752 MSIHANDLE hprod, hdb;
8753 CHAR val[MAX_PATH];
8754 CHAR path[MAX_PATH];
8755 CHAR keypath[MAX_PATH*2];
8756 CHAR prodcode[MAX_PATH];
8757 CHAR prod_squashed[MAX_PATH];
8758 HKEY prodkey, userkey, props;
8759 LPSTR usersid;
8760 DWORD size;
8761 LONG res;
8762 UINT r;
8763 REGSAM access = KEY_ALL_ACCESS;
8764
8765 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
8766
8767 GetCurrentDirectoryA(MAX_PATH, path);
8768 lstrcatA(path, "\\");
8769
8770 create_test_guid(prodcode, prod_squashed);
8771 usersid = get_user_sid();
8772
8773 if (is_wow64)
8774 access |= KEY_WOW64_64KEY;
8775
8776 hdb = create_package_db(prodcode);
8777 MsiCloseHandle(hdb);
8778
8779 /* NULL szProduct */
8780 hprod = 0xdeadbeef;
8781 r = MsiOpenProductA(NULL, &hprod);
8782 ok(r == ERROR_INVALID_PARAMETER,
8783 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8784 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8785
8786 /* empty szProduct */
8787 hprod = 0xdeadbeef;
8788 r = MsiOpenProductA("", &hprod);
8789 ok(r == ERROR_INVALID_PARAMETER,
8790 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8791 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8792
8793 /* garbage szProduct */
8794 hprod = 0xdeadbeef;
8795 r = MsiOpenProductA("garbage", &hprod);
8796 ok(r == ERROR_INVALID_PARAMETER,
8797 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8798 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8799
8800 /* guid without brackets */
8801 hprod = 0xdeadbeef;
8802 r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
8803 ok(r == ERROR_INVALID_PARAMETER,
8804 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8805 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8806
8807 /* guid with brackets */
8808 hprod = 0xdeadbeef;
8809 r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
8810 ok(r == ERROR_UNKNOWN_PRODUCT,
8811 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8812 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8813
8814 /* same length as guid, but random */
8815 hprod = 0xdeadbeef;
8816 r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
8817 ok(r == ERROR_INVALID_PARAMETER,
8818 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8819 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8820
8821 /* hProduct is NULL */
8822 hprod = 0xdeadbeef;
8823 r = MsiOpenProductA(prodcode, NULL);
8824 ok(r == ERROR_INVALID_PARAMETER,
8825 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8826 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8827
8828 /* MSIINSTALLCONTEXT_USERMANAGED */
8829
8830 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8831 lstrcatA(keypath, "Installer\\Managed\\");
8832 lstrcatA(keypath, usersid);
8833 lstrcatA(keypath, "\\Installer\\Products\\");
8834 lstrcatA(keypath, prod_squashed);
8835
8836 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8837 if (res == ERROR_ACCESS_DENIED)
8838 {
8839 skip("Not enough rights to perform tests\n");
8840 LocalFree(usersid);
8841 return;
8842 }
8843 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8844
8845 /* managed product key exists */
8846 hprod = 0xdeadbeef;
8847 r = MsiOpenProductA(prodcode, &hprod);
8848 ok(r == ERROR_UNKNOWN_PRODUCT,
8849 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8850 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8851
8852 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8853 lstrcatA(keypath, "Installer\\UserData\\");
8854 lstrcatA(keypath, usersid);
8855 lstrcatA(keypath, "\\Products\\");
8856 lstrcatA(keypath, prod_squashed);
8857
8858 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8859 if (res == ERROR_ACCESS_DENIED)
8860 {
8861 skip("Not enough rights to perform tests\n");
8862 LocalFree(usersid);
8863 return;
8864 }
8865 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8866
8867 /* user product key exists */
8868 hprod = 0xdeadbeef;
8869 r = MsiOpenProductA(prodcode, &hprod);
8870 ok(r == ERROR_UNKNOWN_PRODUCT,
8871 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8872 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8873
8874 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8875 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8876
8877 /* InstallProperties key exists */
8878 hprod = 0xdeadbeef;
8879 r = MsiOpenProductA(prodcode, &hprod);
8880 ok(r == ERROR_UNKNOWN_PRODUCT,
8881 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8882 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8883
8884 lstrcpyA(val, path);
8885 lstrcatA(val, "\\winetest.msi");
8886 res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
8887 (const BYTE *)val, lstrlenA(val) + 1);
8888 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8889
8890 /* ManagedLocalPackage value exists */
8891 hprod = 0xdeadbeef;
8892 r = MsiOpenProductA(prodcode, &hprod);
8893 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8894 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8895
8896 size = MAX_PATH;
8897 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8898 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8899 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8900 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
8901
8902 MsiCloseHandle(hprod);
8903
8904 RegDeleteValueA(props, "ManagedLocalPackage");
8905 delete_key(props, "", access & KEY_WOW64_64KEY);
8906 RegCloseKey(props);
8907 delete_key(userkey, "", access & KEY_WOW64_64KEY);
8908 RegCloseKey(userkey);
8909 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8910 RegCloseKey(prodkey);
8911
8912 /* MSIINSTALLCONTEXT_USERUNMANAGED */
8913
8914 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8915 lstrcatA(keypath, prod_squashed);
8916
8917 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8918 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8919
8920 /* unmanaged product key exists */
8921 hprod = 0xdeadbeef;
8922 r = MsiOpenProductA(prodcode, &hprod);
8923 ok(r == ERROR_UNKNOWN_PRODUCT,
8924 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8925 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8926
8927 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8928 lstrcatA(keypath, "Installer\\UserData\\");
8929 lstrcatA(keypath, usersid);
8930 lstrcatA(keypath, "\\Products\\");
8931 lstrcatA(keypath, prod_squashed);
8932
8933 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8934 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8935
8936 /* user product key exists */
8937 hprod = 0xdeadbeef;
8938 r = MsiOpenProductA(prodcode, &hprod);
8939 ok(r == ERROR_UNKNOWN_PRODUCT,
8940 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8941 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8942
8943 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
8944 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8945
8946 /* InstallProperties key exists */
8947 hprod = 0xdeadbeef;
8948 r = MsiOpenProductA(prodcode, &hprod);
8949 ok(r == ERROR_UNKNOWN_PRODUCT,
8950 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8951 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8952
8953 lstrcpyA(val, path);
8954 lstrcatA(val, "\\winetest.msi");
8955 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
8956 (const BYTE *)val, lstrlenA(val) + 1);
8957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8958
8959 /* LocalPackage value exists */
8960 hprod = 0xdeadbeef;
8961 r = MsiOpenProductA(prodcode, &hprod);
8962 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8963 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
8964
8965 size = MAX_PATH;
8966 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
8967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8968 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
8969 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
8970
8971 MsiCloseHandle(hprod);
8972
8973 RegDeleteValueA(props, "LocalPackage");
8974 delete_key(props, "", access & KEY_WOW64_64KEY);
8975 RegCloseKey(props);
8976 delete_key(userkey, "", access & KEY_WOW64_64KEY);
8977 RegCloseKey(userkey);
8978 RegDeleteKeyA(prodkey, "");
8979 RegCloseKey(prodkey);
8980
8981 /* MSIINSTALLCONTEXT_MACHINE */
8982
8983 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8984 lstrcatA(keypath, prod_squashed);
8985
8986 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8987 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8988
8989 /* managed product key exists */
8990 hprod = 0xdeadbeef;
8991 r = MsiOpenProductA(prodcode, &hprod);
8992 ok(r == ERROR_UNKNOWN_PRODUCT,
8993 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
8994 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
8995
8996 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8997 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8998 lstrcatA(keypath, prod_squashed);
8999
9000 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9001 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9002
9003 /* user product key exists */
9004 hprod = 0xdeadbeef;
9005 r = MsiOpenProductA(prodcode, &hprod);
9006 ok(r == ERROR_UNKNOWN_PRODUCT,
9007 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9008 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9009
9010 res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
9011 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9012
9013 /* InstallProperties key exists */
9014 hprod = 0xdeadbeef;
9015 r = MsiOpenProductA(prodcode, &hprod);
9016 ok(r == ERROR_UNKNOWN_PRODUCT,
9017 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9018 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9019
9020 lstrcpyA(val, path);
9021 lstrcatA(val, "\\winetest.msi");
9022 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9023 (const BYTE *)val, lstrlenA(val) + 1);
9024 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9025
9026 /* LocalPackage value exists */
9027 hprod = 0xdeadbeef;
9028 r = MsiOpenProductA(prodcode, &hprod);
9029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9030 ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
9031
9032 size = MAX_PATH;
9033 r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
9034 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9035 ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
9036 ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
9037
9038 MsiCloseHandle(hprod);
9039
9040 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9041 (const BYTE *)"winetest.msi", 13);
9042 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9043
9044 lstrcpyA(val, path);
9045 lstrcatA(val, "\\winetest.msi");
9046 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
9047 (const BYTE *)val, lstrlenA(val) + 1);
9048 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9049
9050 DeleteFileA(msifile);
9051
9052 /* local package does not exist */
9053 hprod = 0xdeadbeef;
9054 r = MsiOpenProductA(prodcode, &hprod);
9055 ok(r == ERROR_UNKNOWN_PRODUCT,
9056 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9057 ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
9058
9059 RegDeleteValueA(props, "LocalPackage");
9060 delete_key(props, "", access & KEY_WOW64_64KEY);
9061 RegCloseKey(props);
9062 delete_key(userkey, "", access & KEY_WOW64_64KEY);
9063 RegCloseKey(userkey);
9064 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9065 RegCloseKey(prodkey);
9066
9067 DeleteFileA(msifile);
9068 LocalFree(usersid);
9069 }
9070
9071 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
9072 {
9073 MSIINSTALLCONTEXT context;
9074 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9075 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9076 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9077 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9078 HKEY prodkey, patches, udprod, udpatch, hpatch;
9079 DWORD size, data;
9080 LONG res;
9081 UINT r;
9082 REGSAM access = KEY_ALL_ACCESS;
9083
9084 create_test_guid(prodcode, prod_squashed);
9085 create_test_guid(patch, patch_squashed);
9086
9087 if (is_wow64)
9088 access |= KEY_WOW64_64KEY;
9089
9090 /* MSIPATCHSTATE_APPLIED */
9091
9092 lstrcpyA(patchcode, "apple");
9093 lstrcpyA(targetprod, "banana");
9094 context = 0xdeadbeef;
9095 lstrcpyA(targetsid, "kiwi");
9096 size = MAX_PATH;
9097 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9098 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9099 &context, targetsid, &size);
9100 if (r == ERROR_ACCESS_DENIED)
9101 {
9102 skip("Not enough rights to perform tests\n");
9103 return;
9104 }
9105 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9106 ok(!lstrcmpA(patchcode, "apple"),
9107 "Expected patchcode to be unchanged, got %s\n", patchcode);
9108 ok(!lstrcmpA(targetprod, "banana"),
9109 "Expected targetprod to be unchanged, got %s\n", targetprod);
9110 ok(context == 0xdeadbeef,
9111 "Expected context to be unchanged, got %d\n", context);
9112 ok(!lstrcmpA(targetsid, "kiwi"),
9113 "Expected targetsid to be unchanged, got %s\n", targetsid);
9114 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9115
9116 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9117 lstrcatA(keypath, expectedsid);
9118 lstrcatA(keypath, "\\Installer\\Products\\");
9119 lstrcatA(keypath, prod_squashed);
9120
9121 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9122 if (res == ERROR_ACCESS_DENIED)
9123 {
9124 skip("Not enough rights to perform tests\n");
9125 return;
9126 }
9127 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9128
9129 /* managed product key exists */
9130 lstrcpyA(patchcode, "apple");
9131 lstrcpyA(targetprod, "banana");
9132 context = 0xdeadbeef;
9133 lstrcpyA(targetsid, "kiwi");
9134 size = MAX_PATH;
9135 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9136 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9137 &context, targetsid, &size);
9138 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9139 ok(!lstrcmpA(patchcode, "apple"),
9140 "Expected patchcode to be unchanged, got %s\n", patchcode);
9141 ok(!lstrcmpA(targetprod, "banana"),
9142 "Expected targetprod to be unchanged, got %s\n", targetprod);
9143 ok(context == 0xdeadbeef,
9144 "Expected context to be unchanged, got %d\n", context);
9145 ok(!lstrcmpA(targetsid, "kiwi"),
9146 "Expected targetsid to be unchanged, got %s\n", targetsid);
9147 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9148
9149 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9150 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9151
9152 /* patches key exists */
9153 lstrcpyA(patchcode, "apple");
9154 lstrcpyA(targetprod, "banana");
9155 context = 0xdeadbeef;
9156 lstrcpyA(targetsid, "kiwi");
9157 size = MAX_PATH;
9158 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9159 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9160 &context, targetsid, &size);
9161 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9162 ok(!lstrcmpA(patchcode, "apple"),
9163 "Expected patchcode to be unchanged, got %s\n", patchcode);
9164 ok(!lstrcmpA(targetprod, "banana"),
9165 "Expected targetprod to be unchanged, got %s\n", targetprod);
9166 ok(context == 0xdeadbeef,
9167 "Expected context to be unchanged, got %d\n", context);
9168 ok(!lstrcmpA(targetsid, "kiwi"),
9169 "Expected targetsid to be unchanged, got %s\n", targetsid);
9170 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9171
9172 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9173 (const BYTE *)patch_squashed,
9174 lstrlenA(patch_squashed) + 1);
9175 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9176
9177 /* Patches value exists, is not REG_MULTI_SZ */
9178 lstrcpyA(patchcode, "apple");
9179 lstrcpyA(targetprod, "banana");
9180 context = 0xdeadbeef;
9181 lstrcpyA(targetsid, "kiwi");
9182 size = MAX_PATH;
9183 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9184 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9185 &context, targetsid, &size);
9186 ok(r == ERROR_BAD_CONFIGURATION,
9187 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9188 ok(!lstrcmpA(patchcode, "apple"),
9189 "Expected patchcode to be unchanged, got %s\n", patchcode);
9190 ok(!lstrcmpA(targetprod, "banana"),
9191 "Expected targetprod to be unchanged, got %s\n", targetprod);
9192 ok(context == 0xdeadbeef,
9193 "Expected context to be unchanged, got %d\n", context);
9194 ok(!lstrcmpA(targetsid, "kiwi"),
9195 "Expected targetsid to be unchanged, got %s\n", targetsid);
9196 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9197
9198 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9199 (const BYTE *)"a\0b\0c\0\0", 7);
9200 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9201
9202 /* Patches value exists, is not a squashed guid */
9203 lstrcpyA(patchcode, "apple");
9204 lstrcpyA(targetprod, "banana");
9205 context = 0xdeadbeef;
9206 lstrcpyA(targetsid, "kiwi");
9207 size = MAX_PATH;
9208 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9209 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9210 &context, targetsid, &size);
9211 ok(r == ERROR_BAD_CONFIGURATION,
9212 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9213 ok(!lstrcmpA(patchcode, "apple"),
9214 "Expected patchcode to be unchanged, got %s\n", patchcode);
9215 ok(!lstrcmpA(targetprod, "banana"),
9216 "Expected targetprod to be unchanged, got %s\n", targetprod);
9217 ok(context == 0xdeadbeef,
9218 "Expected context to be unchanged, got %d\n", context);
9219 ok(!lstrcmpA(targetsid, "kiwi"),
9220 "Expected targetsid to be unchanged, got %s\n", targetsid);
9221 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9222
9223 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9224 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9225 (const BYTE *)patch_squashed,
9226 lstrlenA(patch_squashed) + 2);
9227 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9228
9229 /* Patches value exists */
9230 lstrcpyA(patchcode, "apple");
9231 lstrcpyA(targetprod, "banana");
9232 context = 0xdeadbeef;
9233 lstrcpyA(targetsid, "kiwi");
9234 size = MAX_PATH;
9235 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9236 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9237 &context, targetsid, &size);
9238 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9239 ok(!lstrcmpA(patchcode, "apple"),
9240 "Expected patchcode to be unchanged, got %s\n", patchcode);
9241 ok(!lstrcmpA(targetprod, "banana"),
9242 "Expected targetprod to be unchanged, got %s\n", targetprod);
9243 ok(context == 0xdeadbeef,
9244 "Expected context to be unchanged, got %d\n", context);
9245 ok(!lstrcmpA(targetsid, "kiwi"),
9246 "Expected targetsid to be unchanged, got %s\n", targetsid);
9247 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9248
9249 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9250 (const BYTE *)"whatever", 9);
9251 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9252
9253 /* patch squashed value exists */
9254 lstrcpyA(patchcode, "apple");
9255 lstrcpyA(targetprod, "banana");
9256 context = 0xdeadbeef;
9257 lstrcpyA(targetsid, "kiwi");
9258 size = MAX_PATH;
9259 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9260 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9261 &context, targetsid, &size);
9262 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9263 ok(!lstrcmpA(patchcode, patch),
9264 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9265 ok(!lstrcmpA(targetprod, prodcode),
9266 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9267 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9268 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9269 ok(!lstrcmpA(targetsid, expectedsid),
9270 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9271 ok(size == lstrlenA(expectedsid),
9272 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9273
9274 /* increase the index */
9275 lstrcpyA(patchcode, "apple");
9276 lstrcpyA(targetprod, "banana");
9277 context = 0xdeadbeef;
9278 lstrcpyA(targetsid, "kiwi");
9279 size = MAX_PATH;
9280 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9281 MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
9282 &context, targetsid, &size);
9283 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9284 ok(!lstrcmpA(patchcode, "apple"),
9285 "Expected patchcode to be unchanged, got %s\n", patchcode);
9286 ok(!lstrcmpA(targetprod, "banana"),
9287 "Expected targetprod to be unchanged, got %s\n", targetprod);
9288 ok(context == 0xdeadbeef,
9289 "Expected context to be unchanged, got %d\n", context);
9290 ok(!lstrcmpA(targetsid, "kiwi"),
9291 "Expected targetsid to be unchanged, got %s\n", targetsid);
9292 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9293
9294 /* increase again */
9295 lstrcpyA(patchcode, "apple");
9296 lstrcpyA(targetprod, "banana");
9297 context = 0xdeadbeef;
9298 lstrcpyA(targetsid, "kiwi");
9299 size = MAX_PATH;
9300 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9301 MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
9302 &context, targetsid, &size);
9303 ok(r == ERROR_INVALID_PARAMETER,
9304 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9305 ok(!lstrcmpA(patchcode, "apple"),
9306 "Expected patchcode to be unchanged, got %s\n", patchcode);
9307 ok(!lstrcmpA(targetprod, "banana"),
9308 "Expected targetprod to be unchanged, got %s\n", targetprod);
9309 ok(context == 0xdeadbeef,
9310 "Expected context to be unchanged, got %d\n", context);
9311 ok(!lstrcmpA(targetsid, "kiwi"),
9312 "Expected targetsid to be unchanged, got %s\n", targetsid);
9313 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9314
9315 /* szPatchCode is NULL */
9316 lstrcpyA(targetprod, "banana");
9317 context = 0xdeadbeef;
9318 lstrcpyA(targetsid, "kiwi");
9319 size = MAX_PATH;
9320 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9321 MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
9322 &context, targetsid, &size);
9323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9324 ok(!lstrcmpA(targetprod, prodcode),
9325 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9326 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9327 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9328 ok(!lstrcmpA(targetsid, expectedsid),
9329 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9330 ok(size == lstrlenA(expectedsid),
9331 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9332
9333 /* szTargetProductCode is NULL */
9334 lstrcpyA(patchcode, "apple");
9335 context = 0xdeadbeef;
9336 lstrcpyA(targetsid, "kiwi");
9337 size = MAX_PATH;
9338 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9339 MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
9340 &context, targetsid, &size);
9341 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9342 ok(!lstrcmpA(patchcode, patch),
9343 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9344 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9345 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9346 ok(!lstrcmpA(targetsid, expectedsid),
9347 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9348 ok(size == lstrlenA(expectedsid),
9349 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9350
9351 /* pdwTargetProductContext is NULL */
9352 lstrcpyA(patchcode, "apple");
9353 lstrcpyA(targetprod, "banana");
9354 lstrcpyA(targetsid, "kiwi");
9355 size = MAX_PATH;
9356 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9357 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9358 NULL, targetsid, &size);
9359 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9360 ok(!lstrcmpA(patchcode, patch),
9361 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9362 ok(!lstrcmpA(targetprod, prodcode),
9363 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9364 ok(!lstrcmpA(targetsid, expectedsid),
9365 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9366 ok(size == lstrlenA(expectedsid),
9367 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9368
9369 /* szTargetUserSid is NULL */
9370 lstrcpyA(patchcode, "apple");
9371 lstrcpyA(targetprod, "banana");
9372 context = 0xdeadbeef;
9373 size = MAX_PATH;
9374 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9375 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9376 &context, NULL, &size);
9377 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9378 ok(!lstrcmpA(patchcode, patch),
9379 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9380 ok(!lstrcmpA(targetprod, prodcode),
9381 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9382 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9383 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9384 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
9385 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
9386
9387 /* pcchTargetUserSid is exactly the length of szTargetUserSid */
9388 lstrcpyA(patchcode, "apple");
9389 lstrcpyA(targetprod, "banana");
9390 context = 0xdeadbeef;
9391 lstrcpyA(targetsid, "kiwi");
9392 size = lstrlenA(expectedsid);
9393 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9394 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9395 &context, targetsid, &size);
9396 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9397 ok(!lstrcmpA(patchcode, patch),
9398 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9399 ok(!lstrcmpA(targetprod, prodcode),
9400 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9401 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9402 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9403 ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
9404 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9405 ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
9406 "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
9407
9408 /* pcchTargetUserSid has enough room for NULL terminator */
9409 lstrcpyA(patchcode, "apple");
9410 lstrcpyA(targetprod, "banana");
9411 context = 0xdeadbeef;
9412 lstrcpyA(targetsid, "kiwi");
9413 size = lstrlenA(expectedsid) + 1;
9414 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9415 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9416 &context, targetsid, &size);
9417 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9418 ok(!lstrcmpA(patchcode, patch),
9419 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9420 ok(!lstrcmpA(targetprod, prodcode),
9421 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9422 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9423 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9424 ok(!lstrcmpA(targetsid, expectedsid),
9425 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9426 ok(size == lstrlenA(expectedsid),
9427 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9428
9429 /* both szTargetuserSid and pcchTargetUserSid are NULL */
9430 lstrcpyA(patchcode, "apple");
9431 lstrcpyA(targetprod, "banana");
9432 context = 0xdeadbeef;
9433 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9434 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9435 &context, NULL, NULL);
9436 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9437 ok(!lstrcmpA(patchcode, patch),
9438 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9439 ok(!lstrcmpA(targetprod, prodcode),
9440 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9441 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9442 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9443
9444 /* MSIPATCHSTATE_SUPERSEDED */
9445
9446 lstrcpyA(patchcode, "apple");
9447 lstrcpyA(targetprod, "banana");
9448 context = 0xdeadbeef;
9449 lstrcpyA(targetsid, "kiwi");
9450 size = MAX_PATH;
9451 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9452 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9453 &context, targetsid, &size);
9454 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9455 ok(!lstrcmpA(patchcode, "apple"),
9456 "Expected patchcode to be unchanged, got %s\n", patchcode);
9457 ok(!lstrcmpA(targetprod, "banana"),
9458 "Expected targetprod to be unchanged, got %s\n", targetprod);
9459 ok(context == 0xdeadbeef,
9460 "Expected context to be unchanged, got %d\n", context);
9461 ok(!lstrcmpA(targetsid, "kiwi"),
9462 "Expected targetsid to be unchanged, got %s\n", targetsid);
9463 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9464
9465 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9466 lstrcatA(keypath, expectedsid);
9467 lstrcatA(keypath, "\\Products\\");
9468 lstrcatA(keypath, prod_squashed);
9469
9470 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9471 if (res == ERROR_ACCESS_DENIED)
9472 {
9473 skip("Not enough rights to perform tests\n");
9474 return;
9475 }
9476 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9477
9478 /* UserData product key exists */
9479 lstrcpyA(patchcode, "apple");
9480 lstrcpyA(targetprod, "banana");
9481 context = 0xdeadbeef;
9482 lstrcpyA(targetsid, "kiwi");
9483 size = MAX_PATH;
9484 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9485 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9486 &context, targetsid, &size);
9487 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9488 ok(!lstrcmpA(patchcode, "apple"),
9489 "Expected patchcode to be unchanged, got %s\n", patchcode);
9490 ok(!lstrcmpA(targetprod, "banana"),
9491 "Expected targetprod to be unchanged, got %s\n", targetprod);
9492 ok(context == 0xdeadbeef,
9493 "Expected context to be unchanged, got %d\n", context);
9494 ok(!lstrcmpA(targetsid, "kiwi"),
9495 "Expected targetsid to be unchanged, got %s\n", targetsid);
9496 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9497
9498 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9499 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9500
9501 /* UserData patches key exists */
9502 lstrcpyA(patchcode, "apple");
9503 lstrcpyA(targetprod, "banana");
9504 context = 0xdeadbeef;
9505 lstrcpyA(targetsid, "kiwi");
9506 size = MAX_PATH;
9507 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9508 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9509 &context, targetsid, &size);
9510 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9511 ok(!lstrcmpA(patchcode, "apple"),
9512 "Expected patchcode to be unchanged, got %s\n", patchcode);
9513 ok(!lstrcmpA(targetprod, "banana"),
9514 "Expected targetprod to be unchanged, got %s\n", targetprod);
9515 ok(context == 0xdeadbeef,
9516 "Expected context to be unchanged, got %d\n", context);
9517 ok(!lstrcmpA(targetsid, "kiwi"),
9518 "Expected targetsid to be unchanged, got %s\n", targetsid);
9519 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9520
9521 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9522 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9523
9524 /* specific UserData patch key exists */
9525 lstrcpyA(patchcode, "apple");
9526 lstrcpyA(targetprod, "banana");
9527 context = 0xdeadbeef;
9528 lstrcpyA(targetsid, "kiwi");
9529 size = MAX_PATH;
9530 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9531 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9532 &context, targetsid, &size);
9533 ok(r == ERROR_BAD_CONFIGURATION,
9534 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9535 ok(!lstrcmpA(patchcode, "apple"),
9536 "Expected patchcode to be unchanged, got %s\n", patchcode);
9537 ok(!lstrcmpA(targetprod, "banana"),
9538 "Expected targetprod to be unchanged, got %s\n", targetprod);
9539 ok(context == 0xdeadbeef,
9540 "Expected context to be unchanged, got %d\n", context);
9541 ok(!lstrcmpA(targetsid, "kiwi"),
9542 "Expected targetsid to be unchanged, got %s\n", targetsid);
9543 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9544
9545 data = MSIPATCHSTATE_SUPERSEDED;
9546 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9547 (const BYTE *)&data, sizeof(DWORD));
9548 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9549
9550 /* State value exists */
9551 lstrcpyA(patchcode, "apple");
9552 lstrcpyA(targetprod, "banana");
9553 context = 0xdeadbeef;
9554 lstrcpyA(targetsid, "kiwi");
9555 size = MAX_PATH;
9556 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9557 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9558 &context, targetsid, &size);
9559 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9560 ok(!lstrcmpA(patchcode, patch),
9561 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9562 ok(!lstrcmpA(targetprod, prodcode),
9563 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9564 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9565 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9566 ok(!lstrcmpA(targetsid, expectedsid),
9567 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9568 ok(size == lstrlenA(expectedsid),
9569 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9570
9571 /* MSIPATCHSTATE_OBSOLETED */
9572
9573 lstrcpyA(patchcode, "apple");
9574 lstrcpyA(targetprod, "banana");
9575 context = 0xdeadbeef;
9576 lstrcpyA(targetsid, "kiwi");
9577 size = MAX_PATH;
9578 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9579 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9580 &context, targetsid, &size);
9581 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9582 ok(!lstrcmpA(patchcode, "apple"),
9583 "Expected patchcode to be unchanged, got %s\n", patchcode);
9584 ok(!lstrcmpA(targetprod, "banana"),
9585 "Expected targetprod to be unchanged, got %s\n", targetprod);
9586 ok(context == 0xdeadbeef,
9587 "Expected context to be unchanged, got %d\n", context);
9588 ok(!lstrcmpA(targetsid, "kiwi"),
9589 "Expected targetsid to be unchanged, got %s\n", targetsid);
9590 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9591
9592 data = MSIPATCHSTATE_OBSOLETED;
9593 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9594 (const BYTE *)&data, sizeof(DWORD));
9595 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9596
9597 /* State value is obsoleted */
9598 lstrcpyA(patchcode, "apple");
9599 lstrcpyA(targetprod, "banana");
9600 context = 0xdeadbeef;
9601 lstrcpyA(targetsid, "kiwi");
9602 size = MAX_PATH;
9603 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9604 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9605 &context, targetsid, &size);
9606 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9607 ok(!lstrcmpA(patchcode, patch),
9608 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9609 ok(!lstrcmpA(targetprod, prodcode),
9610 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9611 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9612 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9613 ok(!lstrcmpA(targetsid, expectedsid),
9614 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9615 ok(size == lstrlenA(expectedsid),
9616 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9617
9618 /* MSIPATCHSTATE_REGISTERED */
9619 /* FIXME */
9620
9621 /* MSIPATCHSTATE_ALL */
9622
9623 /* 1st */
9624 lstrcpyA(patchcode, "apple");
9625 lstrcpyA(targetprod, "banana");
9626 context = 0xdeadbeef;
9627 lstrcpyA(targetsid, "kiwi");
9628 size = MAX_PATH;
9629 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9630 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9631 &context, targetsid, &size);
9632 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9633 ok(!lstrcmpA(patchcode, patch),
9634 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9635 ok(!lstrcmpA(targetprod, prodcode),
9636 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9637 ok(context == MSIINSTALLCONTEXT_USERMANAGED,
9638 "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
9639 ok(!lstrcmpA(targetsid, expectedsid),
9640 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9641 ok(size == lstrlenA(expectedsid),
9642 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9643
9644 /* same patch in multiple places, only one is enumerated */
9645 lstrcpyA(patchcode, "apple");
9646 lstrcpyA(targetprod, "banana");
9647 context = 0xdeadbeef;
9648 lstrcpyA(targetsid, "kiwi");
9649 size = MAX_PATH;
9650 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
9651 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9652 &context, targetsid, &size);
9653 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9654 ok(!lstrcmpA(patchcode, "apple"),
9655 "Expected patchcode to be unchanged, got %s\n", patchcode);
9656 ok(!lstrcmpA(targetprod, "banana"),
9657 "Expected targetprod to be unchanged, got %s\n", targetprod);
9658 ok(context == 0xdeadbeef,
9659 "Expected context to be unchanged, got %d\n", context);
9660 ok(!lstrcmpA(targetsid, "kiwi"),
9661 "Expected targetsid to be unchanged, got %s\n", targetsid);
9662 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9663
9664 RegDeleteValueA(hpatch, "State");
9665 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9666 RegCloseKey(hpatch);
9667 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9668 RegCloseKey(udpatch);
9669 delete_key(udprod, "", access & KEY_WOW64_64KEY);
9670 RegCloseKey(udprod);
9671 RegDeleteValueA(patches, "Patches");
9672 delete_key(patches, "", access & KEY_WOW64_64KEY);
9673 RegCloseKey(patches);
9674 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9675 RegCloseKey(prodkey);
9676 }
9677
9678 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
9679 {
9680 MSIINSTALLCONTEXT context;
9681 CHAR keypath[MAX_PATH], patch[MAX_PATH];
9682 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
9683 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9684 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9685 HKEY prodkey, patches, udprod, udpatch;
9686 HKEY userkey, hpatch;
9687 DWORD size, data;
9688 LONG res;
9689 UINT r;
9690 REGSAM access = KEY_ALL_ACCESS;
9691
9692 create_test_guid(prodcode, prod_squashed);
9693 create_test_guid(patch, patch_squashed);
9694
9695 if (is_wow64)
9696 access |= KEY_WOW64_64KEY;
9697
9698 /* MSIPATCHSTATE_APPLIED */
9699
9700 lstrcpyA(patchcode, "apple");
9701 lstrcpyA(targetprod, "banana");
9702 context = 0xdeadbeef;
9703 lstrcpyA(targetsid, "kiwi");
9704 size = MAX_PATH;
9705 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9706 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9707 &context, targetsid, &size);
9708 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9709 ok(!lstrcmpA(patchcode, "apple"),
9710 "Expected patchcode to be unchanged, got %s\n", patchcode);
9711 ok(!lstrcmpA(targetprod, "banana"),
9712 "Expected targetprod to be unchanged, got %s\n", targetprod);
9713 ok(context == 0xdeadbeef,
9714 "Expected context to be unchanged, got %d\n", context);
9715 ok(!lstrcmpA(targetsid, "kiwi"),
9716 "Expected targetsid to be unchanged, got %s\n", targetsid);
9717 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9718
9719 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9720 lstrcatA(keypath, prod_squashed);
9721
9722 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9723 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9724
9725 /* current user product key exists */
9726 lstrcpyA(patchcode, "apple");
9727 lstrcpyA(targetprod, "banana");
9728 context = 0xdeadbeef;
9729 lstrcpyA(targetsid, "kiwi");
9730 size = MAX_PATH;
9731 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9732 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9733 &context, targetsid, &size);
9734 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9735 ok(!lstrcmpA(patchcode, "apple"),
9736 "Expected patchcode to be unchanged, got %s\n", patchcode);
9737 ok(!lstrcmpA(targetprod, "banana"),
9738 "Expected targetprod to be unchanged, got %s\n", targetprod);
9739 ok(context == 0xdeadbeef,
9740 "Expected context to be unchanged, got %d\n", context);
9741 ok(!lstrcmpA(targetsid, "kiwi"),
9742 "Expected targetsid to be unchanged, got %s\n", targetsid);
9743 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9744
9745 res = RegCreateKeyA(prodkey, "Patches", &patches);
9746 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9747
9748 /* Patches key exists */
9749 lstrcpyA(patchcode, "apple");
9750 lstrcpyA(targetprod, "banana");
9751 context = 0xdeadbeef;
9752 lstrcpyA(targetsid, "kiwi");
9753 size = MAX_PATH;
9754 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9755 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9756 &context, targetsid, &size);
9757 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9758 ok(!lstrcmpA(patchcode, "apple"),
9759 "Expected patchcode to be unchanged, got %s\n", patchcode);
9760 ok(!lstrcmpA(targetprod, "banana"),
9761 "Expected targetprod to be unchanged, got %s\n", targetprod);
9762 ok(context == 0xdeadbeef,
9763 "Expected context to be unchanged, got %d\n", context);
9764 ok(!lstrcmpA(targetsid, "kiwi"),
9765 "Expected targetsid to be unchanged, got %s\n", targetsid);
9766 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9767
9768 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9769 (const BYTE *)patch_squashed,
9770 lstrlenA(patch_squashed) + 1);
9771 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9772
9773 /* Patches value exists, is not REG_MULTI_SZ */
9774 lstrcpyA(patchcode, "apple");
9775 lstrcpyA(targetprod, "banana");
9776 context = 0xdeadbeef;
9777 lstrcpyA(targetsid, "kiwi");
9778 size = MAX_PATH;
9779 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9780 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9781 &context, targetsid, &size);
9782 ok(r == ERROR_BAD_CONFIGURATION,
9783 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9784 ok(!lstrcmpA(patchcode, "apple"),
9785 "Expected patchcode to be unchanged, got %s\n", patchcode);
9786 ok(!lstrcmpA(targetprod, "banana"),
9787 "Expected targetprod to be unchanged, got %s\n", targetprod);
9788 ok(context == 0xdeadbeef,
9789 "Expected context to be unchanged, got %d\n", context);
9790 ok(!lstrcmpA(targetsid, "kiwi"),
9791 "Expected targetsid to be unchanged, got %s\n", targetsid);
9792 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9793
9794 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9795 (const BYTE *)"a\0b\0c\0\0", 7);
9796 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9797
9798 /* Patches value exists, is not a squashed guid */
9799 lstrcpyA(patchcode, "apple");
9800 lstrcpyA(targetprod, "banana");
9801 context = 0xdeadbeef;
9802 lstrcpyA(targetsid, "kiwi");
9803 size = MAX_PATH;
9804 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9805 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9806 &context, targetsid, &size);
9807 ok(r == ERROR_BAD_CONFIGURATION,
9808 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9809 ok(!lstrcmpA(patchcode, "apple"),
9810 "Expected patchcode to be unchanged, got %s\n", patchcode);
9811 ok(!lstrcmpA(targetprod, "banana"),
9812 "Expected targetprod to be unchanged, got %s\n", targetprod);
9813 ok(context == 0xdeadbeef,
9814 "Expected context to be unchanged, got %d\n", context);
9815 ok(!lstrcmpA(targetsid, "kiwi"),
9816 "Expected targetsid to be unchanged, got %s\n", targetsid);
9817 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9818
9819 patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
9820 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9821 (const BYTE *)patch_squashed,
9822 lstrlenA(patch_squashed) + 2);
9823 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9824
9825 /* Patches value exists */
9826 lstrcpyA(patchcode, "apple");
9827 lstrcpyA(targetprod, "banana");
9828 context = 0xdeadbeef;
9829 lstrcpyA(targetsid, "kiwi");
9830 size = MAX_PATH;
9831 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9832 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9833 &context, targetsid, &size);
9834 ok(r == ERROR_NO_MORE_ITEMS ||
9835 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
9836 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9837 ok(!lstrcmpA(patchcode, "apple"),
9838 "Expected patchcode to be unchanged, got %s\n", patchcode);
9839 ok(!lstrcmpA(targetprod, "banana"),
9840 "Expected targetprod to be unchanged, got %s\n", targetprod);
9841 ok(context == 0xdeadbeef,
9842 "Expected context to be unchanged, got %d\n", context);
9843 ok(!lstrcmpA(targetsid, "kiwi"),
9844 "Expected targetsid to be unchanged, got %s\n", targetsid);
9845 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9846
9847 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9848 (const BYTE *)"whatever", 9);
9849 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9850
9851 /* patch code value exists */
9852 lstrcpyA(patchcode, "apple");
9853 lstrcpyA(targetprod, "banana");
9854 context = 0xdeadbeef;
9855 lstrcpyA(targetsid, "kiwi");
9856 size = MAX_PATH;
9857 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9858 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9859 &context, targetsid, &size);
9860 ok(r == ERROR_NO_MORE_ITEMS ||
9861 broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
9862 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9863 ok(!lstrcmpA(patchcode, "apple"),
9864 "Expected patchcode to be unchanged, got %s\n", patchcode);
9865 ok(!lstrcmpA(targetprod, "banana"),
9866 "Expected targetprod to be unchanged, got %s\n", targetprod);
9867 ok(context == 0xdeadbeef,
9868 "Expected context to be unchanged, got %d\n", context);
9869 ok(!lstrcmpA(targetsid, "kiwi"),
9870 "Expected targetsid to be unchanged, got %s\n", targetsid);
9871 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9872
9873 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9874 lstrcatA(keypath, expectedsid);
9875 lstrcatA(keypath, "\\Patches\\");
9876 lstrcatA(keypath, patch_squashed);
9877
9878 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9879 if (res == ERROR_ACCESS_DENIED)
9880 {
9881 skip("Not enough rights to perform tests\n");
9882 goto error;
9883 }
9884 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9885
9886 /* userdata patch key exists */
9887 lstrcpyA(patchcode, "apple");
9888 lstrcpyA(targetprod, "banana");
9889 context = 0xdeadbeef;
9890 lstrcpyA(targetsid, "kiwi");
9891 size = MAX_PATH;
9892 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9893 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9894 &context, targetsid, &size);
9895 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9896 ok(!lstrcmpA(patchcode, patch),
9897 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9898 ok(!lstrcmpA(targetprod, prodcode),
9899 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9900 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
9901 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
9902 ok(!lstrcmpA(targetsid, expectedsid),
9903 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
9904 ok(size == lstrlenA(expectedsid),
9905 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
9906
9907 /* MSIPATCHSTATE_SUPERSEDED */
9908
9909 lstrcpyA(patchcode, "apple");
9910 lstrcpyA(targetprod, "banana");
9911 context = 0xdeadbeef;
9912 lstrcpyA(targetsid, "kiwi");
9913 size = MAX_PATH;
9914 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9915 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9916 &context, targetsid, &size);
9917 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9918 ok(!lstrcmpA(patchcode, "apple"),
9919 "Expected patchcode to be unchanged, got %s\n", patchcode);
9920 ok(!lstrcmpA(targetprod, "banana"),
9921 "Expected targetprod to be unchanged, got %s\n", targetprod);
9922 ok(context == 0xdeadbeef,
9923 "Expected context to be unchanged, got %d\n", context);
9924 ok(!lstrcmpA(targetsid, "kiwi"),
9925 "Expected targetsid to be unchanged, got %s\n", targetsid);
9926 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9927
9928 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9929 lstrcatA(keypath, expectedsid);
9930 lstrcatA(keypath, "\\Products\\");
9931 lstrcatA(keypath, prod_squashed);
9932
9933 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9934 if (res == ERROR_ACCESS_DENIED)
9935 {
9936 skip("Not enough rights to perform tests\n");
9937 goto error;
9938 }
9939 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9940
9941 /* UserData product key exists */
9942 lstrcpyA(patchcode, "apple");
9943 lstrcpyA(targetprod, "banana");
9944 context = 0xdeadbeef;
9945 lstrcpyA(targetsid, "kiwi");
9946 size = MAX_PATH;
9947 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9948 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9949 &context, targetsid, &size);
9950 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9951 ok(!lstrcmpA(patchcode, "apple"),
9952 "Expected patchcode to be unchanged, got %s\n", patchcode);
9953 ok(!lstrcmpA(targetprod, "banana"),
9954 "Expected targetprod to be unchanged, got %s\n", targetprod);
9955 ok(context == 0xdeadbeef,
9956 "Expected context to be unchanged, got %d\n", context);
9957 ok(!lstrcmpA(targetsid, "kiwi"),
9958 "Expected targetsid to be unchanged, got %s\n", targetsid);
9959 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9960
9961 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9962 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9963
9964 /* UserData patches key exists */
9965 lstrcpyA(patchcode, "apple");
9966 lstrcpyA(targetprod, "banana");
9967 context = 0xdeadbeef;
9968 lstrcpyA(targetsid, "kiwi");
9969 size = MAX_PATH;
9970 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9971 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9972 &context, targetsid, &size);
9973 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9974 ok(!lstrcmpA(patchcode, "apple"),
9975 "Expected patchcode to be unchanged, got %s\n", patchcode);
9976 ok(!lstrcmpA(targetprod, "banana"),
9977 "Expected targetprod to be unchanged, got %s\n", targetprod);
9978 ok(context == 0xdeadbeef,
9979 "Expected context to be unchanged, got %d\n", context);
9980 ok(!lstrcmpA(targetsid, "kiwi"),
9981 "Expected targetsid to be unchanged, got %s\n", targetsid);
9982 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9983
9984 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9985 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9986
9987 /* specific UserData patch key exists */
9988 lstrcpyA(patchcode, "apple");
9989 lstrcpyA(targetprod, "banana");
9990 context = 0xdeadbeef;
9991 lstrcpyA(targetsid, "kiwi");
9992 size = MAX_PATH;
9993 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9994 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9995 &context, targetsid, &size);
9996 ok(r == ERROR_BAD_CONFIGURATION,
9997 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9998 ok(!lstrcmpA(patchcode, "apple"),
9999 "Expected patchcode to be unchanged, got %s\n", patchcode);
10000 ok(!lstrcmpA(targetprod, "banana"),
10001 "Expected targetprod to be unchanged, got %s\n", targetprod);
10002 ok(context == 0xdeadbeef,
10003 "Expected context to be unchanged, got %d\n", context);
10004 ok(!lstrcmpA(targetsid, "kiwi"),
10005 "Expected targetsid to be unchanged, got %s\n", targetsid);
10006 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10007
10008 data = MSIPATCHSTATE_SUPERSEDED;
10009 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10010 (const BYTE *)&data, sizeof(DWORD));
10011 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10012
10013 /* State value exists */
10014 lstrcpyA(patchcode, "apple");
10015 lstrcpyA(targetprod, "banana");
10016 context = 0xdeadbeef;
10017 lstrcpyA(targetsid, "kiwi");
10018 size = MAX_PATH;
10019 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10020 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10021 &context, targetsid, &size);
10022 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10023 ok(!lstrcmpA(patchcode, patch),
10024 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10025 ok(!lstrcmpA(targetprod, prodcode),
10026 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10027 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10028 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10029 ok(!lstrcmpA(targetsid, expectedsid),
10030 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10031 ok(size == lstrlenA(expectedsid),
10032 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10033
10034 /* MSIPATCHSTATE_OBSOLETED */
10035
10036 lstrcpyA(patchcode, "apple");
10037 lstrcpyA(targetprod, "banana");
10038 context = 0xdeadbeef;
10039 lstrcpyA(targetsid, "kiwi");
10040 size = MAX_PATH;
10041 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10042 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10043 &context, targetsid, &size);
10044 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10045 ok(!lstrcmpA(patchcode, "apple"),
10046 "Expected patchcode to be unchanged, got %s\n", patchcode);
10047 ok(!lstrcmpA(targetprod, "banana"),
10048 "Expected targetprod to be unchanged, got %s\n", targetprod);
10049 ok(context == 0xdeadbeef,
10050 "Expected context to be unchanged, got %d\n", context);
10051 ok(!lstrcmpA(targetsid, "kiwi"),
10052 "Expected targetsid to be unchanged, got %s\n", targetsid);
10053 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10054
10055 data = MSIPATCHSTATE_OBSOLETED;
10056 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10057 (const BYTE *)&data, sizeof(DWORD));
10058 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10059
10060 /* State value is obsoleted */
10061 lstrcpyA(patchcode, "apple");
10062 lstrcpyA(targetprod, "banana");
10063 context = 0xdeadbeef;
10064 lstrcpyA(targetsid, "kiwi");
10065 size = MAX_PATH;
10066 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10067 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10068 &context, targetsid, &size);
10069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10070 ok(!lstrcmpA(patchcode, patch),
10071 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10072 ok(!lstrcmpA(targetprod, prodcode),
10073 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10074 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10075 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10076 ok(!lstrcmpA(targetsid, expectedsid),
10077 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10078 ok(size == lstrlenA(expectedsid),
10079 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10080
10081 /* MSIPATCHSTATE_REGISTERED */
10082 /* FIXME */
10083
10084 /* MSIPATCHSTATE_ALL */
10085
10086 /* 1st */
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_USERUNMANAGED,
10093 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10094 &context, targetsid, &size);
10095 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10096 ok(!lstrcmpA(patchcode, patch),
10097 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10098 ok(!lstrcmpA(targetprod, prodcode),
10099 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10100 ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
10101 "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
10102 ok(!lstrcmpA(targetsid, expectedsid),
10103 "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
10104 ok(size == lstrlenA(expectedsid),
10105 "Expected %d, got %d\n", lstrlenA(expectedsid), size);
10106
10107 /* same patch in multiple places, only one is enumerated */
10108 lstrcpyA(patchcode, "apple");
10109 lstrcpyA(targetprod, "banana");
10110 context = 0xdeadbeef;
10111 lstrcpyA(targetsid, "kiwi");
10112 size = MAX_PATH;
10113 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10114 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10115 &context, targetsid, &size);
10116 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10117 ok(!lstrcmpA(patchcode, "apple"),
10118 "Expected patchcode to be unchanged, got %s\n", patchcode);
10119 ok(!lstrcmpA(targetprod, "banana"),
10120 "Expected targetprod to be unchanged, got %s\n", targetprod);
10121 ok(context == 0xdeadbeef,
10122 "Expected context to be unchanged, got %d\n", context);
10123 ok(!lstrcmpA(targetsid, "kiwi"),
10124 "Expected targetsid to be unchanged, got %s\n", targetsid);
10125 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10126
10127 RegDeleteValueA(hpatch, "State");
10128 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10129 RegCloseKey(hpatch);
10130 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10131 RegCloseKey(udpatch);
10132 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10133 RegCloseKey(udprod);
10134 delete_key(userkey, "", access & KEY_WOW64_64KEY);
10135 RegCloseKey(userkey);
10136 RegDeleteValueA(patches, patch_squashed);
10137 RegDeleteValueA(patches, "Patches");
10138
10139 error:
10140 RegDeleteKeyA(patches, "");
10141 RegCloseKey(patches);
10142 RegDeleteKeyA(prodkey, "");
10143 RegCloseKey(prodkey);
10144 }
10145
10146 static void test_MsiEnumPatchesEx_machine(void)
10147 {
10148 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10149 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
10150 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10151 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10152 HKEY prodkey, patches, udprod, udpatch;
10153 HKEY hpatch;
10154 MSIINSTALLCONTEXT context;
10155 DWORD size, data;
10156 LONG res;
10157 UINT r;
10158 REGSAM access = KEY_ALL_ACCESS;
10159
10160 create_test_guid(prodcode, prod_squashed);
10161 create_test_guid(patch, patch_squashed);
10162
10163 if (is_wow64)
10164 access |= KEY_WOW64_64KEY;
10165
10166 /* MSIPATCHSTATE_APPLIED */
10167
10168 lstrcpyA(patchcode, "apple");
10169 lstrcpyA(targetprod, "banana");
10170 context = 0xdeadbeef;
10171 lstrcpyA(targetsid, "kiwi");
10172 size = MAX_PATH;
10173 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10174 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10175 &context, targetsid, &size);
10176 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10177 ok(!lstrcmpA(patchcode, "apple"),
10178 "Expected patchcode to be unchanged, got %s\n", patchcode);
10179 ok(!lstrcmpA(targetprod, "banana"),
10180 "Expected targetprod to be unchanged, got %s\n", targetprod);
10181 ok(context == 0xdeadbeef,
10182 "Expected context to be unchanged, got %d\n", context);
10183 ok(!lstrcmpA(targetsid, "kiwi"),
10184 "Expected targetsid to be unchanged, got %s\n", targetsid);
10185 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10186
10187 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10188 lstrcatA(keypath, prod_squashed);
10189
10190 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10191 if (res == ERROR_ACCESS_DENIED)
10192 {
10193 skip("Not enough rights to perform tests\n");
10194 return;
10195 }
10196 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10197
10198 /* local product key exists */
10199 lstrcpyA(patchcode, "apple");
10200 lstrcpyA(targetprod, "banana");
10201 context = 0xdeadbeef;
10202 lstrcpyA(targetsid, "kiwi");
10203 size = MAX_PATH;
10204 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10205 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10206 &context, targetsid, &size);
10207 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10208 ok(!lstrcmpA(patchcode, "apple"),
10209 "Expected patchcode to be unchanged, got %s\n", patchcode);
10210 ok(!lstrcmpA(targetprod, "banana"),
10211 "Expected targetprod to be unchanged, got %s\n", targetprod);
10212 ok(context == 0xdeadbeef,
10213 "Expected context to be unchanged, got %d\n", context);
10214 ok(!lstrcmpA(targetsid, "kiwi"),
10215 "Expected targetsid to be unchanged, got %s\n", targetsid);
10216 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10217
10218 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10219 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10220
10221 /* Patches key exists */
10222 lstrcpyA(patchcode, "apple");
10223 lstrcpyA(targetprod, "banana");
10224 context = 0xdeadbeef;
10225 lstrcpyA(targetsid, "kiwi");
10226 size = MAX_PATH;
10227 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10228 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10229 &context, targetsid, &size);
10230 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10231 ok(!lstrcmpA(patchcode, "apple"),
10232 "Expected patchcode to be unchanged, got %s\n", patchcode);
10233 ok(!lstrcmpA(targetprod, "banana"),
10234 "Expected targetprod to be unchanged, got %s\n", targetprod);
10235 ok(context == 0xdeadbeef,
10236 "Expected context to be unchanged, got %d\n", context);
10237 ok(!lstrcmpA(targetsid, "kiwi"),
10238 "Expected targetsid to be unchanged, got %s\n", targetsid);
10239 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10240
10241 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10242 (const BYTE *)patch_squashed,
10243 lstrlenA(patch_squashed) + 1);
10244 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10245
10246 /* Patches value exists, is not REG_MULTI_SZ */
10247 lstrcpyA(patchcode, "apple");
10248 lstrcpyA(targetprod, "banana");
10249 context = 0xdeadbeef;
10250 lstrcpyA(targetsid, "kiwi");
10251 size = MAX_PATH;
10252 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10253 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10254 &context, targetsid, &size);
10255 ok(r == ERROR_BAD_CONFIGURATION,
10256 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10257 ok(!lstrcmpA(patchcode, "apple"),
10258 "Expected patchcode to be unchanged, got %s\n", patchcode);
10259 ok(!lstrcmpA(targetprod, "banana"),
10260 "Expected targetprod to be unchanged, got %s\n", targetprod);
10261 ok(context == 0xdeadbeef,
10262 "Expected context to be unchanged, got %d\n", context);
10263 ok(!lstrcmpA(targetsid, "kiwi"),
10264 "Expected targetsid to be unchanged, got %s\n", targetsid);
10265 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10266
10267 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10268 (const BYTE *)"a\0b\0c\0\0", 7);
10269 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10270
10271 /* Patches value exists, is not a squashed guid */
10272 lstrcpyA(patchcode, "apple");
10273 lstrcpyA(targetprod, "banana");
10274 context = 0xdeadbeef;
10275 lstrcpyA(targetsid, "kiwi");
10276 size = MAX_PATH;
10277 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10278 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10279 &context, targetsid, &size);
10280 ok(r == ERROR_BAD_CONFIGURATION,
10281 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10282 ok(!lstrcmpA(patchcode, "apple"),
10283 "Expected patchcode to be unchanged, got %s\n", patchcode);
10284 ok(!lstrcmpA(targetprod, "banana"),
10285 "Expected targetprod to be unchanged, got %s\n", targetprod);
10286 ok(context == 0xdeadbeef,
10287 "Expected context to be unchanged, got %d\n", context);
10288 ok(!lstrcmpA(targetsid, "kiwi"),
10289 "Expected targetsid to be unchanged, got %s\n", targetsid);
10290 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10291
10292 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10293 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10294 (const BYTE *)patch_squashed,
10295 lstrlenA(patch_squashed) + 2);
10296 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10297
10298 /* Patches value exists */
10299 lstrcpyA(patchcode, "apple");
10300 lstrcpyA(targetprod, "banana");
10301 context = 0xdeadbeef;
10302 lstrcpyA(targetsid, "kiwi");
10303 size = MAX_PATH;
10304 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10305 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10306 &context, targetsid, &size);
10307 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10308 ok(!lstrcmpA(patchcode, "apple"),
10309 "Expected patchcode to be unchanged, got %s\n", patchcode);
10310 ok(!lstrcmpA(targetprod, "banana"),
10311 "Expected targetprod to be unchanged, got %s\n", targetprod);
10312 ok(context == 0xdeadbeef,
10313 "Expected context to be unchanged, got %d\n", context);
10314 ok(!lstrcmpA(targetsid, "kiwi"),
10315 "Expected targetsid to be unchanged, got %s\n", targetsid);
10316 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10317
10318 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10319 (const BYTE *)"whatever", 9);
10320 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10321
10322 /* patch code value exists */
10323 lstrcpyA(patchcode, "apple");
10324 lstrcpyA(targetprod, "banana");
10325 context = 0xdeadbeef;
10326 lstrcpyA(targetsid, "kiwi");
10327 size = MAX_PATH;
10328 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10329 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10330 &context, targetsid, &size);
10331 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10332 ok(!lstrcmpA(patchcode, patch),
10333 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10334 ok(!lstrcmpA(targetprod, prodcode),
10335 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10336 ok(context == MSIINSTALLCONTEXT_MACHINE,
10337 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10338 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10339 ok(size == 0, "Expected 0, got %d\n", size);
10340
10341 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10342 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10343 lstrcatA(keypath, prod_squashed);
10344
10345 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10346 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10347
10348 /* local UserData product key exists */
10349 lstrcpyA(patchcode, "apple");
10350 lstrcpyA(targetprod, "banana");
10351 context = 0xdeadbeef;
10352 lstrcpyA(targetsid, "kiwi");
10353 size = MAX_PATH;
10354 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10355 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10356 &context, targetsid, &size);
10357 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10358 ok(!lstrcmpA(patchcode, patch),
10359 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10360 ok(!lstrcmpA(targetprod, prodcode),
10361 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10362 ok(context == MSIINSTALLCONTEXT_MACHINE,
10363 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10364 ok(!lstrcmpA(targetsid, ""),
10365 "Expected \"\", got \"%s\"\n", targetsid);
10366 ok(size == 0, "Expected 0, got %d\n", size);
10367
10368 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10369 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10370
10371 /* local UserData Patches key exists */
10372 lstrcpyA(patchcode, "apple");
10373 lstrcpyA(targetprod, "banana");
10374 context = 0xdeadbeef;
10375 lstrcpyA(targetsid, "kiwi");
10376 size = MAX_PATH;
10377 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10378 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10379 &context, targetsid, &size);
10380 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10381 ok(!lstrcmpA(patchcode, patch),
10382 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10383 ok(!lstrcmpA(targetprod, prodcode),
10384 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10385 ok(context == MSIINSTALLCONTEXT_MACHINE,
10386 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10387 ok(!lstrcmpA(targetsid, ""),
10388 "Expected \"\", got \"%s\"\n", targetsid);
10389 ok(size == 0, "Expected 0, got %d\n", size);
10390
10391 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10392 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10393
10394 /* local UserData Product patch key exists */
10395 lstrcpyA(patchcode, "apple");
10396 lstrcpyA(targetprod, "banana");
10397 context = 0xdeadbeef;
10398 lstrcpyA(targetsid, "kiwi");
10399 size = MAX_PATH;
10400 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10401 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10402 &context, targetsid, &size);
10403 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10404 ok(!lstrcmpA(patchcode, "apple"),
10405 "Expected patchcode to be unchanged, got %s\n", patchcode);
10406 ok(!lstrcmpA(targetprod, "banana"),
10407 "Expected targetprod to be unchanged, got %s\n", targetprod);
10408 ok(context == 0xdeadbeef,
10409 "Expected context to be unchanged, got %d\n", context);
10410 ok(!lstrcmpA(targetsid, "kiwi"),
10411 "Expected targetsid to be unchanged, got %s\n", targetsid);
10412 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10413
10414 data = MSIPATCHSTATE_APPLIED;
10415 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10416 (const BYTE *)&data, sizeof(DWORD));
10417 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10418
10419 /* State value exists */
10420 lstrcpyA(patchcode, "apple");
10421 lstrcpyA(targetprod, "banana");
10422 context = 0xdeadbeef;
10423 lstrcpyA(targetsid, "kiwi");
10424 size = MAX_PATH;
10425 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10426 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10427 &context, targetsid, &size);
10428 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10429 ok(!lstrcmpA(patchcode, patch),
10430 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10431 ok(!lstrcmpA(targetprod, prodcode),
10432 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10433 ok(context == MSIINSTALLCONTEXT_MACHINE,
10434 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10435 ok(!lstrcmpA(targetsid, ""),
10436 "Expected \"\", got \"%s\"\n", targetsid);
10437 ok(size == 0, "Expected 0, got %d\n", size);
10438
10439 /* MSIPATCHSTATE_SUPERSEDED */
10440
10441 lstrcpyA(patchcode, "apple");
10442 lstrcpyA(targetprod, "banana");
10443 context = 0xdeadbeef;
10444 lstrcpyA(targetsid, "kiwi");
10445 size = MAX_PATH;
10446 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10447 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10448 &context, targetsid, &size);
10449 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, 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 data = MSIPATCHSTATE_SUPERSEDED;
10461 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10462 (const BYTE *)&data, sizeof(DWORD));
10463 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10464
10465 /* State value is MSIPATCHSTATE_SUPERSEDED */
10466 lstrcpyA(patchcode, "apple");
10467 lstrcpyA(targetprod, "banana");
10468 context = 0xdeadbeef;
10469 lstrcpyA(targetsid, "kiwi");
10470 size = MAX_PATH;
10471 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10472 MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
10473 &context, targetsid, &size);
10474 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10475 ok(!lstrcmpA(patchcode, patch),
10476 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10477 ok(!lstrcmpA(targetprod, prodcode),
10478 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10479 ok(context == MSIINSTALLCONTEXT_MACHINE,
10480 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10481 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10482 ok(size == 0, "Expected 0, got %d\n", size);
10483
10484 /* MSIPATCHSTATE_OBSOLETED */
10485
10486 lstrcpyA(patchcode, "apple");
10487 lstrcpyA(targetprod, "banana");
10488 context = 0xdeadbeef;
10489 lstrcpyA(targetsid, "kiwi");
10490 size = MAX_PATH;
10491 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10492 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10493 &context, targetsid, &size);
10494 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10495 ok(!lstrcmpA(patchcode, "apple"),
10496 "Expected patchcode to be unchanged, got %s\n", patchcode);
10497 ok(!lstrcmpA(targetprod, "banana"),
10498 "Expected targetprod to be unchanged, got %s\n", targetprod);
10499 ok(context == 0xdeadbeef,
10500 "Expected context to be unchanged, got %d\n", context);
10501 ok(!lstrcmpA(targetsid, "kiwi"),
10502 "Expected targetsid to be unchanged, got %s\n", targetsid);
10503 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10504
10505 data = MSIPATCHSTATE_OBSOLETED;
10506 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10507 (const BYTE *)&data, sizeof(DWORD));
10508 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10509
10510 /* State value is obsoleted */
10511 lstrcpyA(patchcode, "apple");
10512 lstrcpyA(targetprod, "banana");
10513 context = 0xdeadbeef;
10514 lstrcpyA(targetsid, "kiwi");
10515 size = MAX_PATH;
10516 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10517 MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
10518 &context, targetsid, &size);
10519 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10520 ok(!lstrcmpA(patchcode, patch),
10521 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10522 ok(!lstrcmpA(targetprod, prodcode),
10523 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10524 ok(context == MSIINSTALLCONTEXT_MACHINE,
10525 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10526 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10527 ok(size == 0, "Expected 0, got %d\n", size);
10528
10529 /* MSIPATCHSTATE_REGISTERED */
10530 /* FIXME */
10531
10532 /* MSIPATCHSTATE_ALL */
10533
10534 /* 1st */
10535 lstrcpyA(patchcode, "apple");
10536 lstrcpyA(targetprod, "banana");
10537 context = 0xdeadbeef;
10538 lstrcpyA(targetsid, "kiwi");
10539 size = MAX_PATH;
10540 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10541 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10542 &context, targetsid, &size);
10543 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10544 ok(!lstrcmpA(patchcode, patch),
10545 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10546 ok(!lstrcmpA(targetprod, prodcode),
10547 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10548 ok(context == MSIINSTALLCONTEXT_MACHINE,
10549 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10550 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10551 ok(size == 0, "Expected 0, got %d\n", size);
10552
10553 /* same patch in multiple places, only one is enumerated */
10554 lstrcpyA(patchcode, "apple");
10555 lstrcpyA(targetprod, "banana");
10556 context = 0xdeadbeef;
10557 lstrcpyA(targetsid, "kiwi");
10558 size = MAX_PATH;
10559 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10560 MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
10561 &context, targetsid, &size);
10562 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10563 ok(!lstrcmpA(patchcode, "apple"),
10564 "Expected patchcode to be unchanged, got %s\n", patchcode);
10565 ok(!lstrcmpA(targetprod, "banana"),
10566 "Expected targetprod to be unchanged, got %s\n", targetprod);
10567 ok(context == 0xdeadbeef,
10568 "Expected context to be unchanged, got %d\n", context);
10569 ok(!lstrcmpA(targetsid, "kiwi"),
10570 "Expected targetsid to be unchanged, got %s\n", targetsid);
10571 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10572
10573 RegDeleteValueA(patches, patch_squashed);
10574 RegDeleteValueA(patches, "Patches");
10575 delete_key(patches, "", access & KEY_WOW64_64KEY);
10576 RegCloseKey(patches);
10577 RegDeleteValueA(hpatch, "State");
10578 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10579 RegCloseKey(hpatch);
10580 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10581 RegCloseKey(udpatch);
10582 delete_key(udprod, "", access & KEY_WOW64_64KEY);
10583 RegCloseKey(udprod);
10584 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10585 RegCloseKey(prodkey);
10586 }
10587
10588 static void test_MsiEnumPatchesEx(void)
10589 {
10590 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10591 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10592 CHAR patchcode[MAX_PATH];
10593 MSIINSTALLCONTEXT context;
10594 LPSTR usersid;
10595 DWORD size;
10596 UINT r;
10597
10598 if (!pMsiEnumPatchesExA)
10599 {
10600 win_skip("MsiEnumPatchesExA not implemented\n");
10601 return;
10602 }
10603
10604 create_test_guid(prodcode, prod_squashed);
10605 usersid = get_user_sid();
10606
10607 /* empty szProductCode */
10608 lstrcpyA(patchcode, "apple");
10609 lstrcpyA(targetprod, "banana");
10610 context = 0xdeadbeef;
10611 lstrcpyA(targetsid, "kiwi");
10612 size = MAX_PATH;
10613 r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10614 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10615 targetsid, &size);
10616 ok(r == ERROR_INVALID_PARAMETER,
10617 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10618 ok(!lstrcmpA(patchcode, "apple"),
10619 "Expected patchcode to be unchanged, got %s\n", patchcode);
10620 ok(!lstrcmpA(targetprod, "banana"),
10621 "Expected targetprod to be unchanged, got %s\n", targetprod);
10622 ok(context == 0xdeadbeef,
10623 "Expected context to be unchanged, got %d\n", context);
10624 ok(!lstrcmpA(targetsid, "kiwi"),
10625 "Expected targetsid to be unchanged, got %s\n", targetsid);
10626 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10627
10628 /* garbage szProductCode */
10629 lstrcpyA(patchcode, "apple");
10630 lstrcpyA(targetprod, "banana");
10631 context = 0xdeadbeef;
10632 lstrcpyA(targetsid, "kiwi");
10633 size = MAX_PATH;
10634 r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10635 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10636 targetsid, &size);
10637 ok(r == ERROR_INVALID_PARAMETER,
10638 "Expected ERROR_INVALID_PARAMETER, 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 /* guid without brackets */
10650 lstrcpyA(patchcode, "apple");
10651 lstrcpyA(targetprod, "banana");
10652 context = 0xdeadbeef;
10653 lstrcpyA(targetsid, "kiwi");
10654 size = MAX_PATH;
10655 r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
10656 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10657 0, patchcode, targetprod, &context,
10658 targetsid, &size);
10659 ok(r == ERROR_INVALID_PARAMETER,
10660 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10661 ok(!lstrcmpA(patchcode, "apple"),
10662 "Expected patchcode to be unchanged, got %s\n", patchcode);
10663 ok(!lstrcmpA(targetprod, "banana"),
10664 "Expected targetprod to be unchanged, got %s\n", targetprod);
10665 ok(context == 0xdeadbeef,
10666 "Expected context to be unchanged, got %d\n", context);
10667 ok(!lstrcmpA(targetsid, "kiwi"),
10668 "Expected targetsid to be unchanged, got %s\n", targetsid);
10669 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10670
10671 /* guid with brackets */
10672 lstrcpyA(patchcode, "apple");
10673 lstrcpyA(targetprod, "banana");
10674 context = 0xdeadbeef;
10675 lstrcpyA(targetsid, "kiwi");
10676 size = MAX_PATH;
10677 r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
10678 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10679 0, patchcode, targetprod, &context,
10680 targetsid, &size);
10681 ok(r == ERROR_NO_MORE_ITEMS,
10682 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10683 ok(!lstrcmpA(patchcode, "apple"),
10684 "Expected patchcode to be unchanged, got %s\n", patchcode);
10685 ok(!lstrcmpA(targetprod, "banana"),
10686 "Expected targetprod to be unchanged, got %s\n", targetprod);
10687 ok(context == 0xdeadbeef,
10688 "Expected context to be unchanged, got %d\n", context);
10689 ok(!lstrcmpA(targetsid, "kiwi"),
10690 "Expected targetsid to be unchanged, got %s\n", targetsid);
10691 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10692
10693 /* szUserSid is S-1-5-18 */
10694 lstrcpyA(patchcode, "apple");
10695 lstrcpyA(targetprod, "banana");
10696 context = 0xdeadbeef;
10697 lstrcpyA(targetsid, "kiwi");
10698 size = MAX_PATH;
10699 r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
10700 MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
10701 0, patchcode, targetprod, &context,
10702 targetsid, &size);
10703 ok(r == ERROR_INVALID_PARAMETER,
10704 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10705 ok(!lstrcmpA(patchcode, "apple"),
10706 "Expected patchcode to be unchanged, got %s\n", patchcode);
10707 ok(!lstrcmpA(targetprod, "banana"),
10708 "Expected targetprod to be unchanged, got %s\n", targetprod);
10709 ok(context == 0xdeadbeef,
10710 "Expected context to be unchanged, got %d\n", context);
10711 ok(!lstrcmpA(targetsid, "kiwi"),
10712 "Expected targetsid to be unchanged, got %s\n", targetsid);
10713 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10714
10715 /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
10716 lstrcpyA(patchcode, "apple");
10717 lstrcpyA(targetprod, "banana");
10718 context = 0xdeadbeef;
10719 lstrcpyA(targetsid, "kiwi");
10720 size = MAX_PATH;
10721 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
10722 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10723 &context, targetsid, &size);
10724 ok(r == ERROR_INVALID_PARAMETER,
10725 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10726 ok(!lstrcmpA(patchcode, "apple"),
10727 "Expected patchcode to be unchanged, got %s\n", patchcode);
10728 ok(!lstrcmpA(targetprod, "banana"),
10729 "Expected targetprod to be unchanged, got %s\n", targetprod);
10730 ok(context == 0xdeadbeef,
10731 "Expected context to be unchanged, got %d\n", context);
10732 ok(!lstrcmpA(targetsid, "kiwi"),
10733 "Expected targetsid to be unchanged, got %s\n", targetsid);
10734 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10735
10736 /* dwContext is out of bounds */
10737 lstrcpyA(patchcode, "apple");
10738 lstrcpyA(targetprod, "banana");
10739 context = 0xdeadbeef;
10740 lstrcpyA(targetsid, "kiwi");
10741 size = MAX_PATH;
10742 r = pMsiEnumPatchesExA(prodcode, usersid, 0,
10743 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10744 &context, targetsid, &size);
10745 ok(r == ERROR_INVALID_PARAMETER,
10746 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10747 ok(!lstrcmpA(patchcode, "apple"),
10748 "Expected patchcode to be unchanged, got %s\n", patchcode);
10749 ok(!lstrcmpA(targetprod, "banana"),
10750 "Expected targetprod to be unchanged, got %s\n", targetprod);
10751 ok(context == 0xdeadbeef,
10752 "Expected context to be unchanged, got %d\n", context);
10753 ok(!lstrcmpA(targetsid, "kiwi"),
10754 "Expected targetsid to be unchanged, got %s\n", targetsid);
10755 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10756
10757 /* dwContext is out of bounds */
10758 lstrcpyA(patchcode, "apple");
10759 lstrcpyA(targetprod, "banana");
10760 context = 0xdeadbeef;
10761 lstrcpyA(targetsid, "kiwi");
10762 size = MAX_PATH;
10763 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
10764 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10765 &context, targetsid, &size);
10766 ok(r == ERROR_INVALID_PARAMETER,
10767 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10768 ok(!lstrcmpA(patchcode, "apple"),
10769 "Expected patchcode to be unchanged, got %s\n", patchcode);
10770 ok(!lstrcmpA(targetprod, "banana"),
10771 "Expected targetprod to be unchanged, got %s\n", targetprod);
10772 ok(context == 0xdeadbeef,
10773 "Expected context to be unchanged, got %d\n", context);
10774 ok(!lstrcmpA(targetsid, "kiwi"),
10775 "Expected targetsid to be unchanged, got %s\n", targetsid);
10776 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10777
10778 /* dwFilter is out of bounds */
10779 lstrcpyA(patchcode, "apple");
10780 lstrcpyA(targetprod, "banana");
10781 context = 0xdeadbeef;
10782 lstrcpyA(targetsid, "kiwi");
10783 size = MAX_PATH;
10784 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10785 MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
10786 &context, targetsid, &size);
10787 ok(r == ERROR_INVALID_PARAMETER,
10788 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10789 ok(!lstrcmpA(patchcode, "apple"),
10790 "Expected patchcode to be unchanged, got %s\n", patchcode);
10791 ok(!lstrcmpA(targetprod, "banana"),
10792 "Expected targetprod to be unchanged, got %s\n", targetprod);
10793 ok(context == 0xdeadbeef,
10794 "Expected context to be unchanged, got %d\n", context);
10795 ok(!lstrcmpA(targetsid, "kiwi"),
10796 "Expected targetsid to be unchanged, got %s\n", targetsid);
10797 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10798
10799 /* dwFilter is out of bounds */
10800 lstrcpyA(patchcode, "apple");
10801 lstrcpyA(targetprod, "banana");
10802 context = 0xdeadbeef;
10803 lstrcpyA(targetsid, "kiwi");
10804 size = MAX_PATH;
10805 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10806 MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
10807 &context, targetsid, &size);
10808 ok(r == ERROR_INVALID_PARAMETER,
10809 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10810 ok(!lstrcmpA(patchcode, "apple"),
10811 "Expected patchcode to be unchanged, got %s\n", patchcode);
10812 ok(!lstrcmpA(targetprod, "banana"),
10813 "Expected targetprod to be unchanged, got %s\n", targetprod);
10814 ok(context == 0xdeadbeef,
10815 "Expected context to be unchanged, got %d\n", context);
10816 ok(!lstrcmpA(targetsid, "kiwi"),
10817 "Expected targetsid to be unchanged, got %s\n", targetsid);
10818 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10819
10820 /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
10821 lstrcpyA(patchcode, "apple");
10822 lstrcpyA(targetprod, "banana");
10823 context = 0xdeadbeef;
10824 lstrcpyA(targetsid, "kiwi");
10825 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10826 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
10827 &context, targetsid, NULL);
10828 ok(r == ERROR_INVALID_PARAMETER,
10829 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10830 ok(!lstrcmpA(patchcode, "apple"),
10831 "Expected patchcode to be unchanged, got %s\n", patchcode);
10832 ok(!lstrcmpA(targetprod, "banana"),
10833 "Expected targetprod to be unchanged, got %s\n", targetprod);
10834 ok(context == 0xdeadbeef,
10835 "Expected context to be unchanged, got %d\n", context);
10836 ok(!lstrcmpA(targetsid, "kiwi"),
10837 "Expected targetsid to be unchanged, got %s\n", targetsid);
10838
10839 test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
10840 test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
10841 test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
10842 test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
10843 test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
10844 /* FIXME: Successfully test userunmanaged with a different user */
10845 test_MsiEnumPatchesEx_machine();
10846 LocalFree(usersid);
10847 }
10848
10849 static void test_MsiEnumPatches(void)
10850 {
10851 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10852 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10853 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10854 CHAR transforms[MAX_PATH];
10855 WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
10856 HKEY prodkey, patches, udprod;
10857 HKEY userkey, hpatch, udpatch;
10858 DWORD size, data;
10859 LPSTR usersid;
10860 LONG res;
10861 UINT r;
10862 REGSAM access = KEY_ALL_ACCESS;
10863
10864 create_test_guid(prodcode, prod_squashed);
10865 create_test_guid(patchcode, patch_squashed);
10866 usersid = get_user_sid();
10867
10868 if (is_wow64)
10869 access |= KEY_WOW64_64KEY;
10870
10871 /* NULL szProduct */
10872 size = MAX_PATH;
10873 lstrcpyA(patch, "apple");
10874 lstrcpyA(transforms, "banana");
10875 r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
10876 ok(r == ERROR_INVALID_PARAMETER,
10877 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10878 ok(!lstrcmpA(patch, "apple"),
10879 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10880 ok(!lstrcmpA(transforms, "banana"),
10881 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10882 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10883
10884 /* empty szProduct */
10885 size = MAX_PATH;
10886 lstrcpyA(patch, "apple");
10887 lstrcpyA(transforms, "banana");
10888 r = MsiEnumPatchesA("", 0, patch, transforms, &size);
10889 ok(r == ERROR_INVALID_PARAMETER,
10890 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10891 ok(!lstrcmpA(patch, "apple"),
10892 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10893 ok(!lstrcmpA(transforms, "banana"),
10894 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10895 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10896
10897 /* garbage szProduct */
10898 size = MAX_PATH;
10899 lstrcpyA(patch, "apple");
10900 lstrcpyA(transforms, "banana");
10901 r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
10902 ok(r == ERROR_INVALID_PARAMETER,
10903 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10904 ok(!lstrcmpA(patch, "apple"),
10905 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10906 ok(!lstrcmpA(transforms, "banana"),
10907 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10908 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10909
10910 /* guid without brackets */
10911 size = MAX_PATH;
10912 lstrcpyA(patch, "apple");
10913 lstrcpyA(transforms, "banana");
10914 r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
10915 transforms, &size);
10916 ok(r == ERROR_INVALID_PARAMETER,
10917 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10918 ok(!lstrcmpA(patch, "apple"),
10919 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10920 ok(!lstrcmpA(transforms, "banana"),
10921 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10922 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10923
10924 /* guid with brackets */
10925 size = MAX_PATH;
10926 lstrcpyA(patch, "apple");
10927 lstrcpyA(transforms, "banana");
10928 r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
10929 transforms, &size);
10930 ok(r == ERROR_UNKNOWN_PRODUCT,
10931 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10932 ok(!lstrcmpA(patch, "apple"),
10933 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10934 ok(!lstrcmpA(transforms, "banana"),
10935 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10936 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10937
10938 /* same length as guid, but random */
10939 size = MAX_PATH;
10940 lstrcpyA(patch, "apple");
10941 lstrcpyA(transforms, "banana");
10942 r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
10943 transforms, &size);
10944 ok(r == ERROR_INVALID_PARAMETER,
10945 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10946 ok(!lstrcmpA(patch, "apple"),
10947 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10948 ok(!lstrcmpA(transforms, "banana"),
10949 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10950 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10951
10952 /* MSIINSTALLCONTEXT_USERMANAGED */
10953
10954 size = MAX_PATH;
10955 lstrcpyA(patch, "apple");
10956 lstrcpyA(transforms, "banana");
10957 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10958 ok(r == ERROR_UNKNOWN_PRODUCT,
10959 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10960 ok(!lstrcmpA(patch, "apple"),
10961 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10962 ok(!lstrcmpA(transforms, "banana"),
10963 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10964 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10965
10966 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10967 lstrcatA(keypath, usersid);
10968 lstrcatA(keypath, "\\Installer\\Products\\");
10969 lstrcatA(keypath, prod_squashed);
10970
10971 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10972 if (res == ERROR_ACCESS_DENIED)
10973 {
10974 skip("Not enough rights to perform tests\n");
10975 LocalFree(usersid);
10976 return;
10977 }
10978 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10979
10980 /* managed product key exists */
10981 size = MAX_PATH;
10982 lstrcpyA(patch, "apple");
10983 lstrcpyA(transforms, "banana");
10984 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10985 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10986 ok(!lstrcmpA(patch, "apple"),
10987 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10988 ok(!lstrcmpA(transforms, "banana"),
10989 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10990 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10991
10992 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10993 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10994
10995 /* patches key exists */
10996 size = MAX_PATH;
10997 lstrcpyA(patch, "apple");
10998 lstrcpyA(transforms, "banana");
10999 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11000 ok(r == ERROR_NO_MORE_ITEMS ||
11001 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11002 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11003 ok(!lstrcmpA(patch, "apple"),
11004 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11005 ok(!lstrcmpA(transforms, "banana"),
11006 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11007 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11008
11009 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11010 (const BYTE *)patch_squashed,
11011 lstrlenA(patch_squashed) + 1);
11012 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11013
11014 /* Patches value exists, is not REG_MULTI_SZ */
11015 size = MAX_PATH;
11016 lstrcpyA(patch, "apple");
11017 lstrcpyA(transforms, "banana");
11018 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11019 ok(r == ERROR_BAD_CONFIGURATION ||
11020 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11021 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11022 ok(!lstrcmpA(patch, "apple"),
11023 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11024 ok(!lstrcmpA(transforms, "banana"),
11025 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11026 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11027
11028 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11029 (const BYTE *)"a\0b\0c\0\0", 7);
11030 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11031
11032 /* Patches value exists, is not a squashed guid */
11033 size = MAX_PATH;
11034 lstrcpyA(patch, "apple");
11035 lstrcpyA(transforms, "banana");
11036 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11037 ok(r == ERROR_BAD_CONFIGURATION,
11038 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11039 ok(!lstrcmpA(patch, "apple"),
11040 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11041 ok(!lstrcmpA(transforms, "banana"),
11042 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11043 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11044
11045 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11046 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11047 (const BYTE *)patch_squashed,
11048 lstrlenA(patch_squashed) + 2);
11049 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11050
11051 /* Patches value exists */
11052 size = MAX_PATH;
11053 lstrcpyA(patch, "apple");
11054 lstrcpyA(transforms, "banana");
11055 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11056 ok(r == ERROR_NO_MORE_ITEMS ||
11057 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11058 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11059 ok(!lstrcmpA(patch, "apple") ||
11060 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11061 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11062 ok(!lstrcmpA(transforms, "banana"),
11063 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11064 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11065
11066 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11067 (const BYTE *)"whatever", 9);
11068 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11069
11070 /* patch squashed value exists */
11071 size = MAX_PATH;
11072 lstrcpyA(patch, "apple");
11073 lstrcpyA(transforms, "banana");
11074 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11075 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11076 ok(!lstrcmpA(patch, patchcode),
11077 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11078 ok(!lstrcmpA(transforms, "whatever"),
11079 "Expected \"whatever\", got \"%s\"\n", transforms);
11080 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11081
11082 /* lpPatchBuf is NULL */
11083 size = MAX_PATH;
11084 lstrcpyA(transforms, "banana");
11085 r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
11086 ok(r == ERROR_INVALID_PARAMETER,
11087 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11088 ok(!lstrcmpA(transforms, "banana"),
11089 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11090 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11091
11092 /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
11093 size = MAX_PATH;
11094 lstrcpyA(patch, "apple");
11095 r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
11096 ok(r == ERROR_INVALID_PARAMETER,
11097 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11098 ok(!lstrcmpA(patch, "apple"),
11099 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11100 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11101
11102 /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
11103 lstrcpyA(patch, "apple");
11104 lstrcpyA(transforms, "banana");
11105 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
11106 ok(r == ERROR_INVALID_PARAMETER,
11107 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11108 ok(!lstrcmpA(patch, "apple"),
11109 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11110 ok(!lstrcmpA(transforms, "banana"),
11111 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11112
11113 /* pcchTransformsBuf is too small */
11114 size = 6;
11115 lstrcpyA(patch, "apple");
11116 lstrcpyA(transforms, "banana");
11117 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11118 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11119 ok(!lstrcmpA(patch, patchcode),
11120 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11121 ok(!lstrcmpA(transforms, "whate") ||
11122 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11123 "Expected \"whate\", got \"%s\"\n", transforms);
11124 ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
11125
11126 /* increase the index */
11127 size = MAX_PATH;
11128 lstrcpyA(patch, "apple");
11129 lstrcpyA(transforms, "banana");
11130 r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
11131 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11132 ok(!lstrcmpA(patch, "apple"),
11133 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11134 ok(!lstrcmpA(transforms, "banana"),
11135 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11136 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11137
11138 /* increase again */
11139 size = MAX_PATH;
11140 lstrcpyA(patch, "apple");
11141 lstrcpyA(transforms, "banana");
11142 r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
11143 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11144 ok(!lstrcmpA(patch, "apple"),
11145 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11146 ok(!lstrcmpA(transforms, "banana"),
11147 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11148 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11149
11150 RegDeleteValueA(patches, "Patches");
11151 delete_key(patches, "", access & KEY_WOW64_64KEY);
11152 RegCloseKey(patches);
11153 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11154 RegCloseKey(prodkey);
11155
11156 /* MSIINSTALLCONTEXT_USERUNMANAGED */
11157
11158 size = MAX_PATH;
11159 lstrcpyA(patch, "apple");
11160 lstrcpyA(transforms, "banana");
11161 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11162 ok(r == ERROR_UNKNOWN_PRODUCT,
11163 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11164 ok(!lstrcmpA(patch, "apple"),
11165 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11166 ok(!lstrcmpA(transforms, "banana"),
11167 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11168 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11169
11170 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11171 lstrcatA(keypath, prod_squashed);
11172
11173 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11174 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11175
11176 /* current user product key exists */
11177 size = MAX_PATH;
11178 lstrcpyA(patch, "apple");
11179 lstrcpyA(transforms, "banana");
11180 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11181 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11182 ok(!lstrcmpA(patch, "apple"),
11183 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11184 ok(!lstrcmpA(transforms, "banana"),
11185 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11186 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11187
11188 res = RegCreateKeyA(prodkey, "Patches", &patches);
11189 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11190
11191 /* Patches key exists */
11192 size = MAX_PATH;
11193 lstrcpyA(patch, "apple");
11194 lstrcpyA(transforms, "banana");
11195 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11196 ok(r == ERROR_NO_MORE_ITEMS ||
11197 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11198 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11199 ok(!lstrcmpA(patch, "apple"),
11200 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11201 ok(!lstrcmpA(transforms, "banana"),
11202 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11203 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11204
11205 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11206 (const BYTE *)patch_squashed,
11207 lstrlenA(patch_squashed) + 1);
11208 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11209
11210 /* Patches value exists, is not REG_MULTI_SZ */
11211 size = MAX_PATH;
11212 lstrcpyA(patch, "apple");
11213 lstrcpyA(transforms, "banana");
11214 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11215 ok(r == ERROR_BAD_CONFIGURATION ||
11216 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11217 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11218 ok(!lstrcmpA(patch, "apple"),
11219 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11220 ok(!lstrcmpA(transforms, "banana"),
11221 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11222 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11223
11224 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11225 (const BYTE *)"a\0b\0c\0\0", 7);
11226 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11227
11228 /* Patches value exists, is not a squashed guid */
11229 size = MAX_PATH;
11230 lstrcpyA(patch, "apple");
11231 lstrcpyA(transforms, "banana");
11232 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11233 ok(r == ERROR_BAD_CONFIGURATION,
11234 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11235 ok(!lstrcmpA(patch, "apple"),
11236 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11237 ok(!lstrcmpA(transforms, "banana"),
11238 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11239 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11240
11241 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11242 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11243 (const BYTE *)patch_squashed,
11244 lstrlenA(patch_squashed) + 2);
11245 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11246
11247 /* Patches value exists */
11248 size = MAX_PATH;
11249 lstrcpyA(patch, "apple");
11250 lstrcpyA(transforms, "banana");
11251 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11252 ok(r == ERROR_NO_MORE_ITEMS ||
11253 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11254 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11255 ok(!lstrcmpA(patch, "apple") ||
11256 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11257 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11258 ok(!lstrcmpA(transforms, "banana"),
11259 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11260 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11261
11262 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11263 (const BYTE *)"whatever", 9);
11264 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11265
11266 /* patch code value exists */
11267 size = MAX_PATH;
11268 lstrcpyA(patch, "apple");
11269 lstrcpyA(transforms, "banana");
11270 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11271 ok(r == ERROR_NO_MORE_ITEMS ||
11272 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11273 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11274 ok(!lstrcmpA(patch, "apple") ||
11275 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11276 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11277 ok(!lstrcmpA(transforms, "banana") ||
11278 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11279 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11280 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11281
11282 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11283 lstrcatA(keypath, usersid);
11284 lstrcatA(keypath, "\\Patches\\");
11285 lstrcatA(keypath, patch_squashed);
11286
11287 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
11288 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11289
11290 /* userdata patch key exists */
11291 size = MAX_PATH;
11292 lstrcpyA(patch, "apple");
11293 lstrcpyA(transforms, "banana");
11294 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11295 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11296 ok(!lstrcmpA(patch, patchcode),
11297 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11298 ok(!lstrcmpA(transforms, "whatever"),
11299 "Expected \"whatever\", got \"%s\"\n", transforms);
11300 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11301
11302 delete_key(userkey, "", access & KEY_WOW64_64KEY);
11303 RegCloseKey(userkey);
11304 RegDeleteValueA(patches, patch_squashed);
11305 RegDeleteValueA(patches, "Patches");
11306 RegDeleteKeyA(patches, "");
11307 RegCloseKey(patches);
11308 RegDeleteKeyA(prodkey, "");
11309 RegCloseKey(prodkey);
11310
11311 /* MSIINSTALLCONTEXT_MACHINE */
11312
11313 size = MAX_PATH;
11314 lstrcpyA(patch, "apple");
11315 lstrcpyA(transforms, "banana");
11316 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11317 ok(r == ERROR_UNKNOWN_PRODUCT,
11318 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11319 ok(!lstrcmpA(patch, "apple"),
11320 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11321 ok(!lstrcmpA(transforms, "banana"),
11322 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11323 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11324
11325 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11326 lstrcatA(keypath, prod_squashed);
11327
11328 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11329 if (res == ERROR_ACCESS_DENIED)
11330 {
11331 skip("Not enough rights to perform tests\n");
11332 LocalFree(usersid);
11333 return;
11334 }
11335 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11336
11337 /* local product key exists */
11338 size = MAX_PATH;
11339 lstrcpyA(patch, "apple");
11340 lstrcpyA(transforms, "banana");
11341 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11342 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11343 ok(!lstrcmpA(patch, "apple"),
11344 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11345 ok(!lstrcmpA(transforms, "banana"),
11346 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11347 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11348
11349 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11350 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11351
11352 /* Patches key exists */
11353 size = MAX_PATH;
11354 lstrcpyA(patch, "apple");
11355 lstrcpyA(transforms, "banana");
11356 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11357 ok(r == ERROR_NO_MORE_ITEMS ||
11358 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11359 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11360 ok(!lstrcmpA(patch, "apple"),
11361 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11362 ok(!lstrcmpA(transforms, "banana"),
11363 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11364 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11365
11366 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11367 (const BYTE *)patch_squashed,
11368 lstrlenA(patch_squashed) + 1);
11369 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11370
11371 /* Patches value exists, is not REG_MULTI_SZ */
11372 size = MAX_PATH;
11373 lstrcpyA(patch, "apple");
11374 lstrcpyA(transforms, "banana");
11375 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11376 ok(r == ERROR_BAD_CONFIGURATION ||
11377 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11378 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11379 ok(!lstrcmpA(patch, "apple"),
11380 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11381 ok(!lstrcmpA(transforms, "banana"),
11382 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11383 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11384
11385 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11386 (const BYTE *)"a\0b\0c\0\0", 7);
11387 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11388
11389 /* Patches value exists, is not a squashed guid */
11390 size = MAX_PATH;
11391 lstrcpyA(patch, "apple");
11392 lstrcpyA(transforms, "banana");
11393 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11394 ok(r == ERROR_BAD_CONFIGURATION,
11395 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11396 ok(!lstrcmpA(patch, "apple"),
11397 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11398 ok(!lstrcmpA(transforms, "banana"),
11399 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11400 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11401
11402 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11403 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11404 (const BYTE *)patch_squashed,
11405 lstrlenA(patch_squashed) + 2);
11406 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11407
11408 /* Patches value exists */
11409 size = MAX_PATH;
11410 lstrcpyA(patch, "apple");
11411 lstrcpyA(transforms, "banana");
11412 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11413 ok(r == ERROR_NO_MORE_ITEMS ||
11414 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11415 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11416 ok(!lstrcmpA(patch, "apple") ||
11417 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11418 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11419 ok(!lstrcmpA(transforms, "banana"),
11420 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11421 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11422
11423 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11424 (const BYTE *)"whatever", 9);
11425 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11426
11427 /* patch code value exists */
11428 size = MAX_PATH;
11429 lstrcpyA(patch, "apple");
11430 lstrcpyA(transforms, "banana");
11431 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11432 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11433 ok(!lstrcmpA(patch, patchcode),
11434 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11435 ok(!lstrcmpA(transforms, "whatever"),
11436 "Expected \"whatever\", got \"%s\"\n", transforms);
11437 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11438
11439 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
11440 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
11441 lstrcatA(keypath, prod_squashed);
11442
11443 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11444 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11445
11446 /* local UserData product key exists */
11447 size = MAX_PATH;
11448 lstrcpyA(patch, "apple");
11449 lstrcpyA(transforms, "banana");
11450 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11451 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11452 ok(!lstrcmpA(patch, patchcode),
11453 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11454 ok(!lstrcmpA(transforms, "whatever"),
11455 "Expected \"whatever\", got \"%s\"\n", transforms);
11456 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11457
11458 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
11459 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11460
11461 /* local UserData Patches key exists */
11462 size = MAX_PATH;
11463 lstrcpyA(patch, "apple");
11464 lstrcpyA(transforms, "banana");
11465 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11466 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11467 ok(!lstrcmpA(patch, patchcode),
11468 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11469 ok(!lstrcmpA(transforms, "whatever"),
11470 "Expected \"whatever\", got \"%s\"\n", transforms);
11471 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11472
11473 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11474 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11475
11476 /* local UserData Product patch key exists */
11477 size = MAX_PATH;
11478 lstrcpyA(patch, "apple");
11479 lstrcpyA(transforms, "banana");
11480 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11481 ok(r == ERROR_NO_MORE_ITEMS ||
11482 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11483 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11484 ok(!lstrcmpA(patch, "apple") ||
11485 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11486 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11487 ok(!lstrcmpA(transforms, "banana") ||
11488 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11489 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11490 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11491
11492 data = MSIPATCHSTATE_APPLIED;
11493 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11494 (const BYTE *)&data, sizeof(DWORD));
11495 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11496
11497 /* State value exists */
11498 size = MAX_PATH;
11499 lstrcpyA(patch, "apple");
11500 lstrcpyA(transforms, "banana");
11501 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11502 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11503 ok(!lstrcmpA(patch, patchcode),
11504 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11505 ok(!lstrcmpA(transforms, "whatever"),
11506 "Expected \"whatever\", got \"%s\"\n", transforms);
11507 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11508
11509 /* now duplicate some of the tests for the W version */
11510
11511 /* pcchTransformsBuf is too small */
11512 size = 6;
11513 MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
11514 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11515 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11516 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11517 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11518 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11519 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11520 ok(!lstrcmpA(patch, patchcode),
11521 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11522 ok(!lstrcmpA(transforms, "whate") ||
11523 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11524 "Expected \"whate\", got \"%s\"\n", transforms);
11525 ok(size == 8, "Expected 8, got %d\n", size);
11526
11527 /* patch code value exists */
11528 size = MAX_PATH;
11529 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11530 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11531 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11533 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11534 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11535 ok(!lstrcmpA(patch, patchcode),
11536 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11537 ok(!lstrcmpA(transforms, "whatever"),
11538 "Expected \"whatever\", got \"%s\"\n", transforms);
11539 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
11540
11541 RegDeleteValueA(patches, patch_squashed);
11542 RegDeleteValueA(patches, "Patches");
11543 delete_key(patches, "", access & KEY_WOW64_64KEY);
11544 RegCloseKey(patches);
11545 RegDeleteValueA(hpatch, "State");
11546 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11547 RegCloseKey(hpatch);
11548 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11549 RegCloseKey(udpatch);
11550 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11551 RegCloseKey(udprod);
11552 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11553 RegCloseKey(prodkey);
11554 LocalFree(usersid);
11555 }
11556
11557 static void test_MsiGetPatchInfoEx(void)
11558 {
11559 CHAR keypath[MAX_PATH], val[MAX_PATH];
11560 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
11561 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11562 HKEY prodkey, patches, udprod, props;
11563 HKEY hpatch, udpatch, prodpatches;
11564 LPSTR usersid;
11565 DWORD size;
11566 LONG res;
11567 UINT r;
11568 REGSAM access = KEY_ALL_ACCESS;
11569
11570 if (!pMsiGetPatchInfoExA)
11571 {
11572 win_skip("MsiGetPatchInfoEx not implemented\n");
11573 return;
11574 }
11575
11576 create_test_guid(prodcode, prod_squashed);
11577 create_test_guid(patchcode, patch_squashed);
11578 usersid = get_user_sid();
11579
11580 if (is_wow64)
11581 access |= KEY_WOW64_64KEY;
11582
11583 /* NULL szPatchCode */
11584 lstrcpyA(val, "apple");
11585 size = MAX_PATH;
11586 r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11587 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11588 ok(r == ERROR_INVALID_PARAMETER,
11589 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11590 ok(!lstrcmpA(val, "apple"),
11591 "Expected val to be unchanged, got \"%s\"\n", val);
11592 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11593
11594 /* empty szPatchCode */
11595 size = MAX_PATH;
11596 lstrcpyA(val, "apple");
11597 r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11598 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11599 ok(r == ERROR_INVALID_PARAMETER,
11600 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11601 ok(!lstrcmpA(val, "apple"),
11602 "Expected val to be unchanged, got \"%s\"\n", val);
11603 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11604
11605 /* garbage szPatchCode */
11606 size = MAX_PATH;
11607 lstrcpyA(val, "apple");
11608 r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
11609 MSIINSTALLCONTEXT_USERMANAGED,
11610 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11611 ok(r == ERROR_INVALID_PARAMETER,
11612 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11613 ok(!lstrcmpA(val, "apple"),
11614 "Expected val to be unchanged, got \"%s\"\n", val);
11615 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11616
11617 /* guid without brackets */
11618 size = MAX_PATH;
11619 lstrcpyA(val, "apple");
11620 r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
11621 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11622 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11623 ok(r == ERROR_INVALID_PARAMETER,
11624 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11625 ok(!lstrcmpA(val, "apple"),
11626 "Expected val to be unchanged, got \"%s\"\n", val);
11627 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11628
11629 /* guid with brackets */
11630 size = MAX_PATH;
11631 lstrcpyA(val, "apple");
11632 r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
11633 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11634 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11635 ok(r == ERROR_UNKNOWN_PRODUCT,
11636 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11637 ok(!lstrcmpA(val, "apple"),
11638 "Expected val to be unchanged, got \"%s\"\n", val);
11639 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11640
11641 /* same length as guid, but random */
11642 size = MAX_PATH;
11643 lstrcpyA(val, "apple");
11644 r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
11645 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11646 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11647 ok(r == ERROR_INVALID_PARAMETER,
11648 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11649 ok(!lstrcmpA(val, "apple"),
11650 "Expected val to be unchanged, got \"%s\"\n", val);
11651 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11652
11653 /* NULL szProductCode */
11654 lstrcpyA(val, "apple");
11655 size = MAX_PATH;
11656 r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
11657 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11658 ok(r == ERROR_INVALID_PARAMETER,
11659 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11660 ok(!lstrcmpA(val, "apple"),
11661 "Expected val to be unchanged, got \"%s\"\n", val);
11662 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11663
11664 /* empty szProductCode */
11665 size = MAX_PATH;
11666 lstrcpyA(val, "apple");
11667 r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
11668 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11669 ok(r == ERROR_INVALID_PARAMETER,
11670 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11671 ok(!lstrcmpA(val, "apple"),
11672 "Expected val to be unchanged, got \"%s\"\n", val);
11673 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11674
11675 /* garbage szProductCode */
11676 size = MAX_PATH;
11677 lstrcpyA(val, "apple");
11678 r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
11679 MSIINSTALLCONTEXT_USERMANAGED,
11680 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11681 ok(r == ERROR_INVALID_PARAMETER,
11682 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11683 ok(!lstrcmpA(val, "apple"),
11684 "Expected val to be unchanged, got \"%s\"\n", val);
11685 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11686
11687 /* guid without brackets */
11688 size = MAX_PATH;
11689 lstrcpyA(val, "apple");
11690 r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
11691 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11692 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11693 ok(r == ERROR_INVALID_PARAMETER,
11694 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11695 ok(!lstrcmpA(val, "apple"),
11696 "Expected val to be unchanged, got \"%s\"\n", val);
11697 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11698
11699 /* guid with brackets */
11700 size = MAX_PATH;
11701 lstrcpyA(val, "apple");
11702 r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
11703 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11704 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11705 ok(r == ERROR_UNKNOWN_PRODUCT,
11706 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11707 ok(!lstrcmpA(val, "apple"),
11708 "Expected val to be unchanged, got \"%s\"\n", val);
11709 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11710
11711 /* same length as guid, but random */
11712 size = MAX_PATH;
11713 lstrcpyA(val, "apple");
11714 r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
11715 NULL, MSIINSTALLCONTEXT_USERMANAGED,
11716 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11717 ok(r == ERROR_INVALID_PARAMETER,
11718 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11719 ok(!lstrcmpA(val, "apple"),
11720 "Expected val to be unchanged, got \"%s\"\n", val);
11721 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11722
11723 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
11724 size = MAX_PATH;
11725 lstrcpyA(val, "apple");
11726 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11727 MSIINSTALLCONTEXT_USERMANAGED,
11728 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11729 ok(r == ERROR_INVALID_PARAMETER,
11730 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11731 ok(!lstrcmpA(val, "apple"),
11732 "Expected val to be unchanged, got \"%s\"\n", val);
11733 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11734
11735 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
11736 size = MAX_PATH;
11737 lstrcpyA(val, "apple");
11738 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11739 MSIINSTALLCONTEXT_USERUNMANAGED,
11740 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11741 ok(r == ERROR_INVALID_PARAMETER,
11742 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11743 ok(!lstrcmpA(val, "apple"),
11744 "Expected val to be unchanged, got \"%s\"\n", val);
11745 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11746
11747 /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
11748 size = MAX_PATH;
11749 lstrcpyA(val, "apple");
11750 r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
11751 MSIINSTALLCONTEXT_MACHINE,
11752 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11753 ok(r == ERROR_INVALID_PARAMETER,
11754 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11755 ok(!lstrcmpA(val, "apple"),
11756 "Expected val to be unchanged, got \"%s\"\n", val);
11757 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11758
11759 /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
11760 size = MAX_PATH;
11761 lstrcpyA(val, "apple");
11762 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11763 MSIINSTALLCONTEXT_MACHINE,
11764 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11765 ok(r == ERROR_INVALID_PARAMETER,
11766 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11767 ok(!lstrcmpA(val, "apple"),
11768 "Expected val to be unchanged, got \"%s\"\n", val);
11769 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11770
11771 /* dwContext is out of range */
11772 size = MAX_PATH;
11773 lstrcpyA(val, "apple");
11774 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11775 MSIINSTALLCONTEXT_NONE,
11776 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11777 ok(r == ERROR_INVALID_PARAMETER,
11778 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11779 ok(!lstrcmpA(val, "apple"),
11780 "Expected val to be unchanged, got \"%s\"\n", val);
11781 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11782
11783 /* dwContext is out of range */
11784 size = MAX_PATH;
11785 lstrcpyA(val, "apple");
11786 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11787 MSIINSTALLCONTEXT_ALL,
11788 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11789 ok(r == ERROR_INVALID_PARAMETER,
11790 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11791 ok(!lstrcmpA(val, "apple"),
11792 "Expected val to be unchanged, got \"%s\"\n", val);
11793 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11794
11795 /* dwContext is invalid */
11796 size = MAX_PATH;
11797 lstrcpyA(val, "apple");
11798 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
11799 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11800 ok(r == ERROR_INVALID_PARAMETER,
11801 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11802 ok(!lstrcmpA(val, "apple"),
11803 "Expected val to be unchanged, got \"%s\"\n", val);
11804 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11805
11806 /* MSIINSTALLCONTEXT_USERMANAGED */
11807
11808 size = MAX_PATH;
11809 lstrcpyA(val, "apple");
11810 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11811 MSIINSTALLCONTEXT_USERMANAGED,
11812 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11813 ok(r == ERROR_UNKNOWN_PRODUCT,
11814 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11815 ok(!lstrcmpA(val, "apple"),
11816 "Expected val to be unchanged, got \"%s\"\n", val);
11817 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11818
11819 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11820 lstrcatA(keypath, usersid);
11821 lstrcatA(keypath, "\\Products\\");
11822 lstrcatA(keypath, prod_squashed);
11823
11824 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11825 if (res == ERROR_ACCESS_DENIED)
11826 {
11827 skip("Not enough rights to perform tests\n");
11828 LocalFree(usersid);
11829 return;
11830 }
11831 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11832
11833 /* local UserData product key exists */
11834 size = MAX_PATH;
11835 lstrcpyA(val, "apple");
11836 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11837 MSIINSTALLCONTEXT_USERMANAGED,
11838 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11839 ok(r == ERROR_UNKNOWN_PRODUCT,
11840 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11841 ok(!lstrcmpA(val, "apple"),
11842 "Expected val to be unchanged, got \"%s\"\n", val);
11843 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11844
11845 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11846 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11847
11848 /* InstallProperties key exists */
11849 size = MAX_PATH;
11850 lstrcpyA(val, "apple");
11851 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11852 MSIINSTALLCONTEXT_USERMANAGED,
11853 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11854 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11855 ok(!lstrcmpA(val, "apple"),
11856 "Expected val to be unchanged, got \"%s\"\n", val);
11857 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11858
11859 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11860 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11861
11862 /* Patches key exists */
11863 size = MAX_PATH;
11864 lstrcpyA(val, "apple");
11865 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11866 MSIINSTALLCONTEXT_USERMANAGED,
11867 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11868 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11869 ok(!lstrcmpA(val, "apple"),
11870 "Expected val to be unchanged, got \"%s\"\n", val);
11871 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11872
11873 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11874 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11875
11876 /* Patches key exists */
11877 size = MAX_PATH;
11878 lstrcpyA(val, "apple");
11879 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11880 MSIINSTALLCONTEXT_USERMANAGED,
11881 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11882 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11883 ok(!lstrcmpA(val, "apple"),
11884 "Expected val to be unchanged, got \"%s\"\n", val);
11885 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11886
11887 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11888 lstrcatA(keypath, usersid);
11889 lstrcatA(keypath, "\\Installer\\Products\\");
11890 lstrcatA(keypath, prod_squashed);
11891
11892 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11893 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11894
11895 /* managed product key exists */
11896 size = MAX_PATH;
11897 lstrcpyA(val, "apple");
11898 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11899 MSIINSTALLCONTEXT_USERMANAGED,
11900 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11901 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11902 ok(!lstrcmpA(val, "apple"),
11903 "Expected val to be unchanged, got \"%s\"\n", val);
11904 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11905
11906 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11907 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11908
11909 /* Patches key exists */
11910 size = MAX_PATH;
11911 lstrcpyA(val, "apple");
11912 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11913 MSIINSTALLCONTEXT_USERMANAGED,
11914 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11915 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11916 ok(!lstrcmpA(val, "apple"),
11917 "Expected val to be unchanged, got \"%s\"\n", val);
11918 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11919
11920 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11921 (const BYTE *)"transforms", 11);
11922 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11923
11924 /* specific patch value exists */
11925 size = MAX_PATH;
11926 lstrcpyA(val, "apple");
11927 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11928 MSIINSTALLCONTEXT_USERMANAGED,
11929 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11930 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11931 ok(!lstrcmpA(val, "apple"),
11932 "Expected val to be unchanged, got \"%s\"\n", val);
11933 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11934
11935 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11936 lstrcatA(keypath, usersid);
11937 lstrcatA(keypath, "\\Patches\\");
11938 lstrcatA(keypath, patch_squashed);
11939
11940 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11941 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11942
11943 /* UserData Patches key exists */
11944 size = MAX_PATH;
11945 lstrcpyA(val, "apple");
11946 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11947 MSIINSTALLCONTEXT_USERMANAGED,
11948 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11949 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11950 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11951 ok(size == 0, "Expected 0, got %d\n", size);
11952
11953 res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
11954 (const BYTE *)"pack", 5);
11955 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11956
11957 /* ManagedLocalPatch value exists */
11958 size = MAX_PATH;
11959 lstrcpyA(val, "apple");
11960 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11961 MSIINSTALLCONTEXT_USERMANAGED,
11962 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11963 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11964 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11965 ok(size == 4, "Expected 4, got %d\n", size);
11966
11967 size = MAX_PATH;
11968 lstrcpyA(val, "apple");
11969 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11970 MSIINSTALLCONTEXT_USERMANAGED,
11971 INSTALLPROPERTY_TRANSFORMS, val, &size);
11972 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11973 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11974 ok(size == 10, "Expected 10, got %d\n", size);
11975
11976 res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
11977 (const BYTE *)"mydate", 7);
11978 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11979
11980 /* Installed value exists */
11981 size = MAX_PATH;
11982 lstrcpyA(val, "apple");
11983 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11984 MSIINSTALLCONTEXT_USERMANAGED,
11985 INSTALLPROPERTY_INSTALLDATE, val, &size);
11986 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11987 ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
11988 ok(size == 6, "Expected 6, got %d\n", size);
11989
11990 res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
11991 (const BYTE *)"yes", 4);
11992 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11993
11994 /* Uninstallable value exists */
11995 size = MAX_PATH;
11996 lstrcpyA(val, "apple");
11997 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11998 MSIINSTALLCONTEXT_USERMANAGED,
11999 INSTALLPROPERTY_UNINSTALLABLE, val, &size);
12000 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12001 ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
12002 ok(size == 3, "Expected 3, got %d\n", size);
12003
12004 res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
12005 (const BYTE *)"good", 5);
12006 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12007
12008 /* State value exists */
12009 size = MAX_PATH;
12010 lstrcpyA(val, "apple");
12011 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12012 MSIINSTALLCONTEXT_USERMANAGED,
12013 INSTALLPROPERTY_PATCHSTATE, val, &size);
12014 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12015 ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
12016 ok(size == 4, "Expected 4, got %d\n", size);
12017
12018 size = 1;
12019 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
12020 (const BYTE *)&size, sizeof(DWORD));
12021 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12022
12023 /* State value exists */
12024 size = MAX_PATH;
12025 lstrcpyA(val, "apple");
12026 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12027 MSIINSTALLCONTEXT_USERMANAGED,
12028 INSTALLPROPERTY_PATCHSTATE, val, &size);
12029 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12030 todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
12031 ok(size == 1, "Expected 1, got %d\n", size);
12032
12033 res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
12034 (const BYTE *)"display", 8);
12035 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12036
12037 /* DisplayName value exists */
12038 size = MAX_PATH;
12039 lstrcpyA(val, "apple");
12040 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12041 MSIINSTALLCONTEXT_USERMANAGED,
12042 INSTALLPROPERTY_DISPLAYNAME, val, &size);
12043 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12044 ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
12045 ok(size == 7, "Expected 7, got %d\n", size);
12046
12047 res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
12048 (const BYTE *)"moreinfo", 9);
12049 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12050
12051 /* MoreInfoURL value exists */
12052 size = MAX_PATH;
12053 lstrcpyA(val, "apple");
12054 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12055 MSIINSTALLCONTEXT_USERMANAGED,
12056 INSTALLPROPERTY_MOREINFOURL, val, &size);
12057 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12058 ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
12059 ok(size == 8, "Expected 8, got %d\n", size);
12060
12061 /* szProperty is invalid */
12062 size = MAX_PATH;
12063 lstrcpyA(val, "apple");
12064 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12065 MSIINSTALLCONTEXT_USERMANAGED,
12066 "IDontExist", val, &size);
12067 ok(r == ERROR_UNKNOWN_PROPERTY,
12068 "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
12069 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12070 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12071
12072 /* lpValue is NULL, while pcchValue is non-NULL */
12073 size = MAX_PATH;
12074 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12075 MSIINSTALLCONTEXT_USERMANAGED,
12076 INSTALLPROPERTY_MOREINFOURL, NULL, &size);
12077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12078 ok(size == 16, "Expected 16, got %d\n", size);
12079
12080 /* pcchValue is NULL, while lpValue is non-NULL */
12081 lstrcpyA(val, "apple");
12082 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12083 MSIINSTALLCONTEXT_USERMANAGED,
12084 INSTALLPROPERTY_MOREINFOURL, val, NULL);
12085 ok(r == ERROR_INVALID_PARAMETER,
12086 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
12087 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12088
12089 /* both lpValue and pcchValue are NULL */
12090 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12091 MSIINSTALLCONTEXT_USERMANAGED,
12092 INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
12093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12094
12095 /* pcchValue doesn't have enough room for NULL terminator */
12096 size = 8;
12097 lstrcpyA(val, "apple");
12098 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12099 MSIINSTALLCONTEXT_USERMANAGED,
12100 INSTALLPROPERTY_MOREINFOURL, val, &size);
12101 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
12102 ok(!lstrcmpA(val, "moreinf"),
12103 "Expected \"moreinf\", got \"%s\"\n", val);
12104 ok(size == 16, "Expected 16, got %d\n", size);
12105
12106 /* pcchValue has exactly enough room for NULL terminator */
12107 size = 9;
12108 lstrcpyA(val, "apple");
12109 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12110 MSIINSTALLCONTEXT_USERMANAGED,
12111 INSTALLPROPERTY_MOREINFOURL, val, &size);
12112 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12113 ok(!lstrcmpA(val, "moreinfo"),
12114 "Expected \"moreinfo\", got \"%s\"\n", val);
12115 ok(size == 8, "Expected 8, got %d\n", size);
12116
12117 /* pcchValue is too small, lpValue is NULL */
12118 size = 0;
12119 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12120 MSIINSTALLCONTEXT_USERMANAGED,
12121 INSTALLPROPERTY_MOREINFOURL, NULL, &size);
12122 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12123 ok(size == 16, "Expected 16, got %d\n", size);
12124
12125 RegDeleteValueA(prodpatches, patch_squashed);
12126 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12127 RegCloseKey(prodpatches);
12128 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12129 RegCloseKey(prodkey);
12130
12131 /* UserData is sufficient for all properties
12132 * except INSTALLPROPERTY_TRANSFORMS
12133 */
12134 size = MAX_PATH;
12135 lstrcpyA(val, "apple");
12136 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12137 MSIINSTALLCONTEXT_USERMANAGED,
12138 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12139 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12140 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12141 ok(size == 4, "Expected 4, got %d\n", size);
12142
12143 /* UserData is sufficient for all properties
12144 * except INSTALLPROPERTY_TRANSFORMS
12145 */
12146 size = MAX_PATH;
12147 lstrcpyA(val, "apple");
12148 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12149 MSIINSTALLCONTEXT_USERMANAGED,
12150 INSTALLPROPERTY_TRANSFORMS, val, &size);
12151 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12152 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12153 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12154
12155 RegDeleteValueA(hpatch, "MoreInfoURL");
12156 RegDeleteValueA(hpatch, "Display");
12157 RegDeleteValueA(hpatch, "State");
12158 RegDeleteValueA(hpatch, "Uninstallable");
12159 RegDeleteValueA(hpatch, "Installed");
12160 RegDeleteValueA(udpatch, "ManagedLocalPackage");
12161 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12162 RegCloseKey(udpatch);
12163 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12164 RegCloseKey(hpatch);
12165 delete_key(patches, "", access & KEY_WOW64_64KEY);
12166 RegCloseKey(patches);
12167 delete_key(props, "", access & KEY_WOW64_64KEY);
12168 RegCloseKey(props);
12169 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12170 RegCloseKey(udprod);
12171
12172 /* MSIINSTALLCONTEXT_USERUNMANAGED */
12173
12174 size = MAX_PATH;
12175 lstrcpyA(val, "apple");
12176 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12177 MSIINSTALLCONTEXT_USERUNMANAGED,
12178 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12179 ok(r == ERROR_UNKNOWN_PRODUCT,
12180 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12181 ok(!lstrcmpA(val, "apple"),
12182 "Expected val to be unchanged, got \"%s\"\n", val);
12183 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12184
12185 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12186 lstrcatA(keypath, usersid);
12187 lstrcatA(keypath, "\\Products\\");
12188 lstrcatA(keypath, prod_squashed);
12189
12190 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12191 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12192
12193 /* local UserData product key exists */
12194 size = MAX_PATH;
12195 lstrcpyA(val, "apple");
12196 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12197 MSIINSTALLCONTEXT_USERUNMANAGED,
12198 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12199 ok(r == ERROR_UNKNOWN_PRODUCT,
12200 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12201 ok(!lstrcmpA(val, "apple"),
12202 "Expected val to be unchanged, got \"%s\"\n", val);
12203 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12204
12205 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12206 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12207
12208 /* InstallProperties key exists */
12209 size = MAX_PATH;
12210 lstrcpyA(val, "apple");
12211 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12212 MSIINSTALLCONTEXT_USERUNMANAGED,
12213 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12214 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12215 ok(!lstrcmpA(val, "apple"),
12216 "Expected val to be unchanged, got \"%s\"\n", val);
12217 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12218
12219 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12220 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12221
12222 /* Patches key exists */
12223 size = MAX_PATH;
12224 lstrcpyA(val, "apple");
12225 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12226 MSIINSTALLCONTEXT_USERUNMANAGED,
12227 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12228 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12229 ok(!lstrcmpA(val, "apple"),
12230 "Expected val to be unchanged, got \"%s\"\n", val);
12231 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12232
12233 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12234 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12235
12236 /* Patches key exists */
12237 size = MAX_PATH;
12238 lstrcpyA(val, "apple");
12239 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12240 MSIINSTALLCONTEXT_USERUNMANAGED,
12241 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12242 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12243 ok(!lstrcmpA(val, "apple"),
12244 "Expected val to be unchanged, got \"%s\"\n", val);
12245 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12246
12247 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
12248 lstrcatA(keypath, prod_squashed);
12249
12250 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
12251 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12252
12253 /* current user product key exists */
12254 size = MAX_PATH;
12255 lstrcpyA(val, "apple");
12256 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12257 MSIINSTALLCONTEXT_USERUNMANAGED,
12258 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12259 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12260 ok(!lstrcmpA(val, "apple"),
12261 "Expected val to be unchanged, got \"%s\"\n", val);
12262 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12263
12264 res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
12265 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12266
12267 /* Patches key exists */
12268 size = MAX_PATH;
12269 lstrcpyA(val, "apple");
12270 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12271 MSIINSTALLCONTEXT_USERUNMANAGED,
12272 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12273 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12274 ok(!lstrcmpA(val, "apple"),
12275 "Expected val to be unchanged, got \"%s\"\n", val);
12276 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12277
12278 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12279 (const BYTE *)"transforms", 11);
12280 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12281
12282 /* specific patch value exists */
12283 size = MAX_PATH;
12284 lstrcpyA(val, "apple");
12285 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12286 MSIINSTALLCONTEXT_USERUNMANAGED,
12287 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12288 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12289 ok(!lstrcmpA(val, "apple"),
12290 "Expected val to be unchanged, got \"%s\"\n", val);
12291 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12292
12293 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
12294 lstrcatA(keypath, usersid);
12295 lstrcatA(keypath, "\\Patches\\");
12296 lstrcatA(keypath, patch_squashed);
12297
12298 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12299 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12300
12301 /* UserData Patches key exists */
12302 size = MAX_PATH;
12303 lstrcpyA(val, "apple");
12304 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12305 MSIINSTALLCONTEXT_USERUNMANAGED,
12306 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12307 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12308 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12309 ok(size == 0, "Expected 0, got %d\n", size);
12310
12311 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12312 (const BYTE *)"pack", 5);
12313 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12314
12315 /* LocalPatch value exists */
12316 size = MAX_PATH;
12317 lstrcpyA(val, "apple");
12318 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12319 MSIINSTALLCONTEXT_USERUNMANAGED,
12320 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12321 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12322 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12323 ok(size == 4, "Expected 4, got %d\n", size);
12324
12325 size = MAX_PATH;
12326 lstrcpyA(val, "apple");
12327 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12328 MSIINSTALLCONTEXT_USERUNMANAGED,
12329 INSTALLPROPERTY_TRANSFORMS, val, &size);
12330 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12331 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12332 ok(size == 10, "Expected 10, got %d\n", size);
12333
12334 RegDeleteValueA(prodpatches, patch_squashed);
12335 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12336 RegCloseKey(prodpatches);
12337 RegDeleteKeyA(prodkey, "");
12338 RegCloseKey(prodkey);
12339
12340 /* UserData is sufficient for all properties
12341 * except INSTALLPROPERTY_TRANSFORMS
12342 */
12343 size = MAX_PATH;
12344 lstrcpyA(val, "apple");
12345 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12346 MSIINSTALLCONTEXT_USERUNMANAGED,
12347 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12349 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12350 ok(size == 4, "Expected 4, got %d\n", size);
12351
12352 /* UserData is sufficient for all properties
12353 * except INSTALLPROPERTY_TRANSFORMS
12354 */
12355 size = MAX_PATH;
12356 lstrcpyA(val, "apple");
12357 r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
12358 MSIINSTALLCONTEXT_USERUNMANAGED,
12359 INSTALLPROPERTY_TRANSFORMS, val, &size);
12360 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12361 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12362 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12363
12364 RegDeleteValueA(udpatch, "LocalPackage");
12365 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12366 RegCloseKey(udpatch);
12367 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12368 RegCloseKey(hpatch);
12369 delete_key(patches, "", access & KEY_WOW64_64KEY);
12370 RegCloseKey(patches);
12371 delete_key(props, "", access & KEY_WOW64_64KEY);
12372 RegCloseKey(props);
12373 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12374 RegCloseKey(udprod);
12375
12376 /* MSIINSTALLCONTEXT_MACHINE */
12377
12378 size = MAX_PATH;
12379 lstrcpyA(val, "apple");
12380 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12381 MSIINSTALLCONTEXT_MACHINE,
12382 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12383 ok(r == ERROR_UNKNOWN_PRODUCT,
12384 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12385 ok(!lstrcmpA(val, "apple"),
12386 "Expected val to be unchanged, got \"%s\"\n", val);
12387 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12388
12389 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12390 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
12391 lstrcatA(keypath, prod_squashed);
12392
12393 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
12394 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12395
12396 /* local UserData product key exists */
12397 size = MAX_PATH;
12398 lstrcpyA(val, "apple");
12399 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12400 MSIINSTALLCONTEXT_MACHINE,
12401 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12402 ok(r == ERROR_UNKNOWN_PRODUCT,
12403 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
12404 ok(!lstrcmpA(val, "apple"),
12405 "Expected val to be unchanged, got \"%s\"\n", val);
12406 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12407
12408 res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
12409 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12410
12411 /* InstallProperties key exists */
12412 size = MAX_PATH;
12413 lstrcpyA(val, "apple");
12414 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12415 MSIINSTALLCONTEXT_MACHINE,
12416 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12417 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12418 ok(!lstrcmpA(val, "apple"),
12419 "Expected val to be unchanged, got \"%s\"\n", val);
12420 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12421
12422 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
12423 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12424
12425 /* Patches key exists */
12426 size = MAX_PATH;
12427 lstrcpyA(val, "apple");
12428 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12429 MSIINSTALLCONTEXT_MACHINE,
12430 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12431 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12432 ok(!lstrcmpA(val, "apple"),
12433 "Expected val to be unchanged, got \"%s\"\n", val);
12434 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12435
12436 res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
12437 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12438
12439 /* Patches key exists */
12440 size = MAX_PATH;
12441 lstrcpyA(val, "apple");
12442 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12443 MSIINSTALLCONTEXT_MACHINE,
12444 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12445 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12446 ok(!lstrcmpA(val, "apple"),
12447 "Expected val to be unchanged, got \"%s\"\n", val);
12448 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12449
12450 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
12451 lstrcatA(keypath, prod_squashed);
12452
12453 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
12454 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12455
12456 /* local product key exists */
12457 size = MAX_PATH;
12458 lstrcpyA(val, "apple");
12459 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12460 MSIINSTALLCONTEXT_MACHINE,
12461 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12462 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, 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 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
12468 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12469
12470 /* Patches key exists */
12471 size = MAX_PATH;
12472 lstrcpyA(val, "apple");
12473 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12474 MSIINSTALLCONTEXT_MACHINE,
12475 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12476 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12477 ok(!lstrcmpA(val, "apple"),
12478 "Expected val to be unchanged, got \"%s\"\n", val);
12479 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12480
12481 res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
12482 (const BYTE *)"transforms", 11);
12483 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12484
12485 /* specific patch value exists */
12486 size = MAX_PATH;
12487 lstrcpyA(val, "apple");
12488 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12489 MSIINSTALLCONTEXT_MACHINE,
12490 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12491 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12492 ok(!lstrcmpA(val, "apple"),
12493 "Expected val to be unchanged, got \"%s\"\n", val);
12494 ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
12495
12496 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12497 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
12498 lstrcatA(keypath, patch_squashed);
12499
12500 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
12501 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12502
12503 /* UserData Patches key exists */
12504 size = MAX_PATH;
12505 lstrcpyA(val, "apple");
12506 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12507 MSIINSTALLCONTEXT_MACHINE,
12508 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12509 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12510 ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
12511 ok(size == 0, "Expected 0, got %d\n", size);
12512
12513 res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
12514 (const BYTE *)"pack", 5);
12515 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12516
12517 /* LocalPatch value exists */
12518 size = MAX_PATH;
12519 lstrcpyA(val, "apple");
12520 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12521 MSIINSTALLCONTEXT_MACHINE,
12522 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12523 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12524 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12525 ok(size == 4, "Expected 4, got %d\n", size);
12526
12527 size = MAX_PATH;
12528 lstrcpyA(val, "apple");
12529 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12530 MSIINSTALLCONTEXT_MACHINE,
12531 INSTALLPROPERTY_TRANSFORMS, val, &size);
12532 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12533 ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
12534 ok(size == 10, "Expected 10, got %d\n", size);
12535
12536 RegDeleteValueA(prodpatches, patch_squashed);
12537 delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
12538 RegCloseKey(prodpatches);
12539 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
12540 RegCloseKey(prodkey);
12541
12542 /* UserData is sufficient for all properties
12543 * except INSTALLPROPERTY_TRANSFORMS
12544 */
12545 size = MAX_PATH;
12546 lstrcpyA(val, "apple");
12547 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12548 MSIINSTALLCONTEXT_MACHINE,
12549 INSTALLPROPERTY_LOCALPACKAGE, val, &size);
12550 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12551 ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
12552 ok(size == 4, "Expected 4, got %d\n", size);
12553
12554 /* UserData is sufficient for all properties
12555 * except INSTALLPROPERTY_TRANSFORMS
12556 */
12557 size = MAX_PATH;
12558 lstrcpyA(val, "apple");
12559 r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
12560 MSIINSTALLCONTEXT_MACHINE,
12561 INSTALLPROPERTY_TRANSFORMS, val, &size);
12562 ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
12563 ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
12564 ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
12565
12566 RegDeleteValueA(udpatch, "LocalPackage");
12567 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
12568 RegCloseKey(udpatch);
12569 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
12570 RegCloseKey(hpatch);
12571 delete_key(patches, "", access & KEY_WOW64_64KEY);
12572 RegCloseKey(patches);
12573 delete_key(props, "", access & KEY_WOW64_64KEY);
12574 RegCloseKey(props);
12575 delete_key(udprod, "", access & KEY_WOW64_64KEY);
12576 RegCloseKey(udprod);
12577 LocalFree(usersid);
12578 }
12579
12580 static void test_MsiGetPatchInfo(void)
12581 {
12582 UINT r;
12583 char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
12584 char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
12585 WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
12586 HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
12587 HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
12588 DWORD size;
12589 LONG res;
12590 REGSAM access = KEY_ALL_ACCESS;
12591
12592 create_test_guid(patch_code, patch_squashed);
12593 create_test_guid(prod_code, prod_squashed);
12594 MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
12595
12596 if (is_wow64)
12597 access |= KEY_WOW64_64KEY;
12598
12599 r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
12600 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12601
12602 r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
12603 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12604
12605 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
12606 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
12607
12608 size = 0;
12609 r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
12610 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
12611
12612 r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
12613 ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
12614
12615 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
12616 lstrcatA(keypath, prod_squashed);
12617
12618 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
12619 if (res == ERROR_ACCESS_DENIED)
12620 {
12621 skip("Not enough rights to perform tests\n");
12622 return;
12623 }
12624 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12625
12626 /* product key exists */
12627 size = MAX_PATH;
12628 lstrcpyA(val, "apple");
12629 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12630 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12631 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
12632 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12633
12634 res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
12635 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12636
12637 /* patches key exists */
12638 size = MAX_PATH;
12639 lstrcpyA(val, "apple");
12640 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12641 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12642 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12643 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12644
12645 res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
12646 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12647
12648 /* patch key exists */
12649 size = MAX_PATH;
12650 lstrcpyA(val, "apple");
12651 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12652 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12653 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12654 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12655
12656 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12657 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
12658 lstrcatA(keypath, prod_squashed);
12659
12660 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
12661 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
12662
12663 /* UserData product key exists */
12664 size = MAX_PATH;
12665 lstrcpyA(val, "apple");
12666 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12667 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12668 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12669 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12670
12671 res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
12672 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12673
12674 /* InstallProperties key exists */
12675 size = MAX_PATH;
12676 lstrcpyA(val, "apple");
12677 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12678 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12679 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
12680 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12681
12682 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
12683 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12684
12685 /* UserData Patches key exists */
12686 size = MAX_PATH;
12687 lstrcpyA(val, "apple");
12688 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12689 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12690 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12691 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12692
12693 res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
12694 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12695
12696 res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
12697 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
12698
12699 /* UserData product patch key exists */
12700 size = MAX_PATH;
12701 lstrcpyA(val, "apple");
12702 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12703 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
12704 ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
12705 ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
12706
12707 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
12708 lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
12709 lstrcatA(keypath, patch_squashed);
12710
12711 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
12712 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12713
12714 res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
12715 ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
12716
12717 /* UserData Patch key exists */
12718 size = 0;
12719 lstrcpyA(val, "apple");
12720 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12721 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
12722 ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
12723 ok(size == 11, "expected 11 got %u\n", size);
12724
12725 size = MAX_PATH;
12726 lstrcpyA(val, "apple");
12727 r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
12728 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
12729 ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
12730 ok(size == 11, "expected 11 got %u\n", size);
12731
12732 size = 0;
12733 valW[0] = 0;
12734 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
12735 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
12736 ok(!valW[0], "expected 0 got %u\n", valW[0]);
12737 ok(size == 11, "expected 11 got %u\n", size);
12738
12739 size = MAX_PATH;
12740 valW[0] = 0;
12741 r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
12742 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
12743 ok(valW[0], "expected > 0 got %u\n", valW[0]);
12744 ok(size == 11, "expected 11 got %u\n", size);
12745
12746 delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
12747 RegCloseKey(hkey_udproductpatch);
12748 delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
12749 RegCloseKey(hkey_udproductpatches);
12750 delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
12751 RegCloseKey(hkey_udpatch);
12752 delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
12753 RegCloseKey(hkey_patches);
12754 delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
12755 RegCloseKey(hkey_product);
12756 delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
12757 RegCloseKey(hkey_patch);
12758 delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
12759 RegCloseKey(hkey_udpatches);
12760 delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
12761 RegCloseKey(hkey_udprops);
12762 delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
12763 RegCloseKey(hkey_udproduct);
12764 }
12765
12766 static void test_MsiEnumProducts(void)
12767 {
12768 UINT r;
12769 int found1, found2, found3;
12770 DWORD index;
12771 char product1[39], product2[39], product3[39], guid[39];
12772 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
12773 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
12774 char *usersid;
12775 HKEY key1, key2, key3;
12776 REGSAM access = KEY_ALL_ACCESS;
12777
12778 create_test_guid(product1, product_squashed1);
12779 create_test_guid(product2, product_squashed2);
12780 create_test_guid(product3, product_squashed3);
12781 usersid = get_user_sid();
12782
12783 if (is_wow64)
12784 access |= KEY_WOW64_64KEY;
12785
12786 strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
12787 strcat(keypath1, product_squashed1);
12788
12789 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
12790 if (r == ERROR_ACCESS_DENIED)
12791 {
12792 skip("Not enough rights to perform tests\n");
12793 LocalFree(usersid);
12794 return;
12795 }
12796 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12797
12798 strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
12799 strcat(keypath2, usersid);
12800 strcat(keypath2, "\\Installer\\Products\\");
12801 strcat(keypath2, product_squashed2);
12802
12803 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
12804 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12805
12806 strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
12807 strcat(keypath3, product_squashed3);
12808
12809 r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
12810 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
12811
12812 index = 0;
12813 r = MsiEnumProductsA(index, guid);
12814 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12815
12816 r = MsiEnumProductsA(index, NULL);
12817 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12818
12819 index = 2;
12820 r = MsiEnumProductsA(index, guid);
12821 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
12822
12823 index = 0;
12824 r = MsiEnumProductsA(index, guid);
12825 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
12826
12827 found1 = found2 = found3 = 0;
12828 while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
12829 {
12830 if (!strcmp(product1, guid)) found1 = 1;
12831 if (!strcmp(product2, guid)) found2 = 1;
12832 if (!strcmp(product3, guid)) found3 = 1;
12833 index++;
12834 }
12835 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
12836 ok(found1, "product1 not found\n");
12837 ok(found2, "product2 not found\n");
12838 ok(found3, "product3 not found\n");
12839
12840 delete_key(key1, "", access & KEY_WOW64_64KEY);
12841 delete_key(key2, "", access & KEY_WOW64_64KEY);
12842 RegDeleteKeyA(key3, "");
12843 RegCloseKey(key1);
12844 RegCloseKey(key2);
12845 RegCloseKey(key3);
12846 LocalFree(usersid);
12847 }
12848
12849 static void test_MsiGetFileSignatureInformation(void)
12850 {
12851 HRESULT hr;
12852 const CERT_CONTEXT *cert;
12853 DWORD len;
12854
12855 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
12856 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12857
12858 hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
12859 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12860
12861 hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
12862 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12863
12864 hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
12865 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12866
12867 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
12868 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12869
12870 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
12871 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12872
12873 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
12874 todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
12875
12876 create_file( "signature.bin", "signature", sizeof("signature") );
12877
12878 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
12879 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12880
12881 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
12882 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
12883
12884 cert = (const CERT_CONTEXT *)0xdeadbeef;
12885 hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
12886 todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
12887 ok(cert == NULL, "got %p\n", cert);
12888
12889 DeleteFileA( "signature.bin" );
12890 }
12891
12892 static void test_MsiEnumProductsEx(void)
12893 {
12894 UINT r;
12895 DWORD len, index;
12896 MSIINSTALLCONTEXT context;
12897 char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
12898 char product_squashed1[33], product_squashed2[33], product_squashed3[33];
12899 char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
12900 HKEY key1 = NULL, key2 = NULL, key3 = NULL;
12901 REGSAM access = KEY_ALL_ACCESS;
12902 char *usersid = get_user_sid();
12903
12904 if (!pMsiEnumProductsExA)
12905 {
12906 win_skip("MsiEnumProductsExA not implemented\n");
12907 return;
12908 }
12909
12910 create_test_guid( product0, NULL );
12911 create_test_guid( product1, product_squashed1 );
12912 create_test_guid( product2, product_squashed2 );
12913 create_test_guid( product3, product_squashed3 );
12914
12915 if (is_wow64) access |= KEY_WOW64_64KEY;
12916
12917 strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
12918 strcat( keypath1, product_squashed1 );
12919
12920 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
12921 if (r == ERROR_ACCESS_DENIED)
12922 {
12923 skip( "insufficient rights\n" );
12924 goto done;
12925 }
12926 ok( r == ERROR_SUCCESS, "got %u\n", r );
12927
12928 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
12929 strcat( keypath2, usersid );
12930 strcat( keypath2, "\\Installer\\Products\\" );
12931 strcat( keypath2, product_squashed2 );
12932
12933 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
12934 ok( r == ERROR_SUCCESS, "got %u\n", r );
12935
12936 strcpy( keypath3, usersid );
12937 strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
12938 strcat( keypath3, product_squashed3 );
12939
12940 r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
12941 ok( r == ERROR_SUCCESS, "got %u\n", r );
12942
12943 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
12944 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12945
12946 len = sizeof(sid);
12947 r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
12948 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
12949 ok( len == sizeof(sid), "got %u\n", len );
12950
12951 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
12952 ok( r == ERROR_SUCCESS, "got %u\n", r );
12953
12954 sid[0] = 0;
12955 len = sizeof(sid);
12956 r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
12957 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
12958 ok( len == sizeof(sid), "got %u\n", len );
12959 ok( !sid[0], "got %s\n", sid );
12960
12961 sid[0] = 0;
12962 len = sizeof(sid);
12963 r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
12964 ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
12965 ok( len == sizeof(sid), "got %u\n", len );
12966 ok( !sid[0], "got %s\n", sid );
12967
12968 sid[0] = 0;
12969 len = 0;
12970 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
12971 ok( r == ERROR_MORE_DATA, "got %u\n", r );
12972 ok( len, "length unchanged\n" );
12973 ok( !sid[0], "got %s\n", sid );
12974
12975 guid[0] = 0;
12976 context = 0xdeadbeef;
12977 sid[0] = 0;
12978 len = sizeof(sid);
12979 r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
12980 ok( r == ERROR_SUCCESS, "got %u\n", r );
12981 ok( guid[0], "empty guid\n" );
12982 ok( context != 0xdeadbeef, "context unchanged\n" );
12983 ok( !len, "got %u\n", len );
12984 ok( !sid[0], "got %s\n", sid );
12985
12986 guid[0] = 0;
12987 context = 0xdeadbeef;
12988 sid[0] = 0;
12989 len = sizeof(sid);
12990 r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
12991 ok( r == ERROR_SUCCESS, "got %u\n", r );
12992 ok( guid[0], "empty guid\n" );
12993 ok( context != 0xdeadbeef, "context unchanged\n" );
12994 ok( !len, "got %u\n", len );
12995 ok( !sid[0], "got %s\n", sid );
12996
12997 guid[0] = 0;
12998 context = 0xdeadbeef;
12999 sid[0] = 0;
13000 len = sizeof(sid);
13001 r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
13002 if (r == ERROR_ACCESS_DENIED)
13003 {
13004 skip( "insufficient rights\n" );
13005 goto done;
13006 }
13007 ok( r == ERROR_SUCCESS, "got %u\n", r );
13008 ok( guid[0], "empty guid\n" );
13009 ok( context != 0xdeadbeef, "context unchanged\n" );
13010 ok( !len, "got %u\n", len );
13011 ok( !sid[0], "got %s\n", sid );
13012
13013 index = 0;
13014 guid[0] = 0;
13015 context = 0xdeadbeef;
13016 sid[0] = 0;
13017 len = sizeof(sid);
13018 while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13019 {
13020 if (!strcmp( product1, guid ))
13021 {
13022 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13023 ok( !sid[0], "got \"%s\"\n", sid );
13024 ok( !len, "unexpected length %u\n", len );
13025 }
13026 if (!strcmp( product2, guid ))
13027 {
13028 ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
13029 ok( sid[0], "empty sid\n" );
13030 ok( len == strlen(sid), "unexpected length %u\n", len );
13031 }
13032 if (!strcmp( product3, guid ))
13033 {
13034 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13035 ok( sid[0], "empty sid\n" );
13036 ok( len == strlen(sid), "unexpected length %u\n", len );
13037 }
13038 index++;
13039 guid[0] = 0;
13040 context = 0xdeadbeef;
13041 sid[0] = 0;
13042 len = sizeof(sid);
13043 }
13044
13045 done:
13046 delete_key( key1, "", access );
13047 delete_key( key2, "", access );
13048 delete_key( key3, "", access );
13049 RegCloseKey( key1 );
13050 RegCloseKey( key2 );
13051 RegCloseKey( key3 );
13052 LocalFree( usersid );
13053 }
13054
13055 static void test_MsiEnumComponents(void)
13056 {
13057 UINT r;
13058 int found1, found2;
13059 DWORD index;
13060 char comp1[39], comp2[39], guid[39];
13061 char comp_squashed1[33], comp_squashed2[33];
13062 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13063 REGSAM access = KEY_ALL_ACCESS;
13064 char *usersid = get_user_sid();
13065 HKEY key1 = NULL, key2 = NULL;
13066
13067 create_test_guid( comp1, comp_squashed1 );
13068 create_test_guid( comp2, comp_squashed2 );
13069
13070 if (is_wow64) access |= KEY_WOW64_64KEY;
13071
13072 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13073 strcat( keypath1, "S-1-5-18\\Components\\" );
13074 strcat( keypath1, comp_squashed1 );
13075
13076 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13077 if (r == ERROR_ACCESS_DENIED)
13078 {
13079 skip( "insufficient rights\n" );
13080 goto done;
13081 }
13082 ok( r == ERROR_SUCCESS, "got %u\n", r );
13083
13084 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13085 strcat( keypath2, usersid );
13086 strcat( keypath2, "\\Components\\" );
13087 strcat( keypath2, comp_squashed2 );
13088
13089 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13090 if (r == ERROR_ACCESS_DENIED)
13091 {
13092 skip( "insufficient rights\n" );
13093 goto done;
13094 }
13095
13096 r = MsiEnumComponentsA( 0, NULL );
13097 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13098
13099 index = 0;
13100 guid[0] = 0;
13101 found1 = found2 = 0;
13102 while (!MsiEnumComponentsA( index, guid ))
13103 {
13104 if (!strcmp( guid, comp1 )) found1 = 1;
13105 if (!strcmp( guid, comp2 )) found2 = 1;
13106 ok( guid[0], "empty guid\n" );
13107 guid[0] = 0;
13108 index++;
13109 }
13110 ok( found1, "comp1 not found\n" );
13111 ok( found2, "comp2 not found\n" );
13112
13113 done:
13114 delete_key( key1, "", access );
13115 delete_key( key2, "", access );
13116 RegCloseKey( key1 );
13117 RegCloseKey( key2 );
13118 LocalFree( usersid );
13119 }
13120
13121 static void test_MsiEnumComponentsEx(void)
13122 {
13123 UINT r;
13124 int found1, found2;
13125 DWORD len, index;
13126 MSIINSTALLCONTEXT context;
13127 char comp1[39], comp2[39], guid[39], sid[128];
13128 char comp_squashed1[33], comp_squashed2[33];
13129 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13130 HKEY key1 = NULL, key2 = NULL;
13131 REGSAM access = KEY_ALL_ACCESS;
13132 char *usersid = get_user_sid();
13133
13134 if (!pMsiEnumComponentsExA)
13135 {
13136 win_skip( "MsiEnumComponentsExA not implemented\n" );
13137 return;
13138 }
13139 create_test_guid( comp1, comp_squashed1 );
13140 create_test_guid( comp2, comp_squashed2 );
13141
13142 if (is_wow64) access |= KEY_WOW64_64KEY;
13143
13144 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13145 strcat( keypath1, "S-1-5-18\\Components\\" );
13146 strcat( keypath1, comp_squashed1 );
13147
13148 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13149 if (r == ERROR_ACCESS_DENIED)
13150 {
13151 skip( "insufficient rights\n" );
13152 goto done;
13153 }
13154 ok( r == ERROR_SUCCESS, "got %u\n", r );
13155
13156 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13157 strcat( keypath2, usersid );
13158 strcat( keypath2, "\\Components\\" );
13159 strcat( keypath2, comp_squashed2 );
13160
13161 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13162 if (r == ERROR_ACCESS_DENIED)
13163 {
13164 skip( "insufficient rights\n" );
13165 goto done;
13166 }
13167 ok( r == ERROR_SUCCESS, "got %u\n", r );
13168 r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
13169 sizeof("c:\\doesnotexist"));
13170 ok( r == ERROR_SUCCESS, "got %u\n", r );
13171
13172 index = 0;
13173 guid[0] = 0;
13174 context = 0xdeadbeef;
13175 sid[0] = 0;
13176 len = sizeof(sid);
13177 found1 = found2 = 0;
13178 while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13179 {
13180 if (!strcmp( comp1, guid ))
13181 {
13182 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13183 ok( !sid[0], "got \"%s\"\n", sid );
13184 ok( !len, "unexpected length %u\n", len );
13185 found1 = 1;
13186 }
13187 if (!strcmp( comp2, guid ))
13188 {
13189 ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
13190 ok( sid[0], "empty sid\n" );
13191 ok( len == strlen(sid), "unexpected length %u\n", len );
13192 found2 = 1;
13193 }
13194 index++;
13195 guid[0] = 0;
13196 context = 0xdeadbeef;
13197 sid[0] = 0;
13198 len = sizeof(sid);
13199 }
13200 ok( found1, "comp1 not found\n" );
13201 ok( found2, "comp2 not found\n" );
13202
13203 r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
13204 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13205
13206 r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
13207 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13208
13209 done:
13210 RegDeleteValueA( key2, comp_squashed2 );
13211 delete_key( key1, "", access );
13212 delete_key( key2, "", access );
13213 RegCloseKey( key1 );
13214 RegCloseKey( key2 );
13215 LocalFree( usersid );
13216 }
13217
13218 static void test_MsiConfigureProductEx(void)
13219 {
13220 UINT r;
13221 LONG res;
13222 DWORD type, size;
13223 HKEY props, source;
13224 CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
13225 REGSAM access = KEY_ALL_ACCESS;
13226
13227 if (is_process_limited())
13228 {
13229 skip("process is limited\n");
13230 return;
13231 }
13232
13233 CreateDirectoryA("msitest", NULL);
13234 create_file("msitest\\hydrogen", "hydrogen", 500);
13235 create_file("msitest\\helium", "helium", 500);
13236 create_file("msitest\\lithium", "lithium", 500);
13237
13238 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13239
13240 if (is_wow64)
13241 access |= KEY_WOW64_64KEY;
13242
13243 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13244
13245 /* NULL szProduct */
13246 r = MsiConfigureProductExA(NULL, INSTALLLEVEL_DEFAULT,
13247 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13248 ok(r == ERROR_INVALID_PARAMETER,
13249 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13250
13251 /* empty szProduct */
13252 r = MsiConfigureProductExA("", INSTALLLEVEL_DEFAULT,
13253 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13254 ok(r == ERROR_INVALID_PARAMETER,
13255 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13256
13257 /* garbage szProduct */
13258 r = MsiConfigureProductExA("garbage", INSTALLLEVEL_DEFAULT,
13259 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13260 ok(r == ERROR_INVALID_PARAMETER,
13261 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13262
13263 /* guid without brackets */
13264 r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
13265 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13266 "PROPVAR=42");
13267 ok(r == ERROR_INVALID_PARAMETER,
13268 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13269
13270 /* guid with brackets */
13271 r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
13272 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13273 "PROPVAR=42");
13274 ok(r == ERROR_UNKNOWN_PRODUCT,
13275 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13276
13277 /* same length as guid, but random */
13278 r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
13279 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13280 "PROPVAR=42");
13281 ok(r == ERROR_UNKNOWN_PRODUCT,
13282 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13283
13284 /* product not installed yet */
13285 r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
13286 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13287 "PROPVAR=42");
13288 ok(r == ERROR_UNKNOWN_PRODUCT,
13289 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13290
13291 /* install the product, per-user unmanaged */
13292 r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
13293 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13294 {
13295 skip("Not enough rights to perform tests\n");
13296 goto error;
13297 }
13298 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13299 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13300 ok(pf_exists("msitest\\helium"), "File not installed\n");
13301 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13302 ok(pf_exists("msitest"), "File not installed\n");
13303
13304 /* product is installed per-user managed, remove it */
13305 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13306 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13307 "PROPVAR=42");
13308 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13309 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13310 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13311 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13312 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13313
13314 /* product has been removed */
13315 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13316 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13317 "PROPVAR=42");
13318 ok(r == ERROR_UNKNOWN_PRODUCT,
13319 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13320
13321 /* install the product, machine */
13322 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13323 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13324 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13325 ok(pf_exists("msitest\\helium"), "File not installed\n");
13326 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13327 ok(pf_exists("msitest"), "File not installed\n");
13328
13329 /* product is installed machine, remove it */
13330 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13331 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13332 "PROPVAR=42");
13333 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13334 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13335 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13336 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13337 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13338
13339 /* product has been removed */
13340 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13341 INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT,
13342 "PROPVAR=42");
13343 ok(r == ERROR_UNKNOWN_PRODUCT,
13344 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13345
13346 /* install the product, machine */
13347 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13348 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13349 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13350 ok(pf_exists("msitest\\helium"), "File not installed\n");
13351 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13352 ok(pf_exists("msitest"), "File not installed\n");
13353
13354 DeleteFileA(msifile);
13355
13356 /* msifile is removed */
13357 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13358 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13359 "PROPVAR=42");
13360 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13361 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13362 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13363 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13364 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13365
13366 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13367
13368 /* install the product, machine */
13369 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13370 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13371 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13372 ok(pf_exists("msitest\\helium"), "File not installed\n");
13373 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13374 ok(pf_exists("msitest"), "File not installed\n");
13375
13376 DeleteFileA(msifile);
13377
13378 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13379 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13380 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13381
13382 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
13383 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13384
13385 type = REG_SZ;
13386 size = MAX_PATH;
13387 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13388 (LPBYTE)localpackage, &size);
13389 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13390
13391 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13392 (const BYTE *)"C:\\idontexist.msi", 18);
13393 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13394
13395 /* LocalPackage is used to find the cached msi package */
13396 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13397 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13398 "PROPVAR=42");
13399 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
13400 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13401 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13402 ok(pf_exists("msitest\\helium"), "File not installed\n");
13403 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13404 ok(pf_exists("msitest"), "File not installed\n");
13405
13406 RegCloseKey(props);
13407 create_database(msifile, mcp_tables, sizeof(mcp_tables) / sizeof(msi_table));
13408
13409 /* LastUsedSource can be used as a last resort */
13410 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13411 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13412 "PROPVAR=42");
13413 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13414 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13415 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13416 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13417 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13418 DeleteFileA( localpackage );
13419
13420 /* install the product, machine */
13421 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13422 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13423 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13424 ok(pf_exists("msitest\\helium"), "File not installed\n");
13425 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13426 ok(pf_exists("msitest"), "File not installed\n");
13427
13428 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13429 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13430 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13431
13432 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
13433 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13434
13435 type = REG_SZ;
13436 size = MAX_PATH;
13437 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13438 (LPBYTE)localpackage, &size);
13439 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13440
13441 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13442 (const BYTE *)"C:\\idontexist.msi", 18);
13443 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13444
13445 lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
13446 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\SourceList");
13447
13448 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source);
13449 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13450
13451 type = REG_SZ;
13452 size = MAX_PATH;
13453 res = RegQueryValueExA(source, "PackageName", NULL, &type,
13454 (LPBYTE)packagename, &size);
13455 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13456
13457 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13458 (const BYTE *)"idontexist.msi", 15);
13459 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13460
13461 /* SourceList is altered */
13462 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13463 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13464 "PROPVAR=42");
13465 ok(r == ERROR_INSTALL_SOURCE_ABSENT,
13466 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13467 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13468 ok(pf_exists("msitest\\helium"), "File not installed\n");
13469 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13470 ok(pf_exists("msitest"), "File not installed\n");
13471
13472 /* restore PackageName */
13473 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13474 (const BYTE *)packagename, lstrlenA(packagename) + 1);
13475 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13476
13477 /* restore LocalPackage */
13478 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13479 (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
13480 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
13481
13482 /* finally remove the product */
13483 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13484 INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT,
13485 "PROPVAR=42");
13486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13487 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13488 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13489 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13490 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13491
13492 RegCloseKey(source);
13493 RegCloseKey(props);
13494
13495 error:
13496 DeleteFileA("msitest\\hydrogen");
13497 DeleteFileA("msitest\\helium");
13498 DeleteFileA("msitest\\lithium");
13499 RemoveDirectoryA("msitest");
13500 DeleteFileA(msifile);
13501 }
13502
13503 static void test_MsiSetFeatureAttributes(void)
13504 {
13505 UINT r;
13506 DWORD attrs;
13507 char path[MAX_PATH];
13508 MSIHANDLE package;
13509
13510 if (is_process_limited())
13511 {
13512 skip("process is limited\n");
13513 return;
13514 }
13515 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
13516
13517 strcpy( path, CURR_DIR );
13518 strcat( path, "\\" );
13519 strcat( path, msifile );
13520
13521 r = MsiOpenPackage( path, &package );
13522 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13523 {
13524 skip("Not enough rights to perform tests\n");
13525 DeleteFileA( msifile );
13526 return;
13527 }
13528 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13529
13530 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13531 ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_FUNCTION_FAILED, got %u\n", r);
13532
13533 r = MsiDoAction( package, "CostInitialize" );
13534 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13535
13536 r = MsiSetFeatureAttributesA( 0, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13537 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
13538
13539 r = MsiSetFeatureAttributesA( package, "", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13540 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13541
13542 r = MsiSetFeatureAttributesA( package, NULL, INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13543 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13544
13545 r = MsiSetFeatureAttributesA( package, "One", 0 );
13546 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13547
13548 attrs = 0xdeadbeef;
13549 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13550 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13551 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
13552 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
13553
13554 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13555 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13556
13557 attrs = 0;
13558 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13559 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13560 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL,
13561 "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got 0x%08x\n", attrs);
13562
13563 r = MsiDoAction( package, "FileCost" );
13564 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13565
13566 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORSOURCE );
13567 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13568
13569 attrs = 0;
13570 r = MsiGetFeatureInfoA( package, "One", &attrs, NULL, NULL, NULL, NULL );
13571 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13572 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORSOURCE,
13573 "expected INSTALLFEATUREATTRIBUTE_FAVORSOURCE, got 0x%08x\n", attrs);
13574
13575 r = MsiDoAction( package, "CostFinalize" );
13576 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13577
13578 r = MsiSetFeatureAttributesA( package, "One", INSTALLFEATUREATTRIBUTE_FAVORLOCAL );
13579 ok(r == ERROR_FUNCTION_FAILED, "expected ERROR_FUNCTION_FAILED, got %u\n", r);
13580
13581 MsiCloseHandle( package );
13582 DeleteFileA( msifile );
13583 }
13584
13585 static void test_MsiGetFeatureInfo(void)
13586 {
13587 UINT r;
13588 MSIHANDLE package;
13589 char title[32], help[32], path[MAX_PATH];
13590 DWORD attrs, title_len, help_len;
13591
13592 if (is_process_limited())
13593 {
13594 skip("process is limited\n");
13595 return;
13596 }
13597 create_database( msifile, tables, sizeof(tables) / sizeof(tables[0]) );
13598
13599 strcpy( path, CURR_DIR );
13600 strcat( path, "\\" );
13601 strcat( path, msifile );
13602
13603 r = MsiOpenPackage( path, &package );
13604 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13605 {
13606 skip("Not enough rights to perform tests\n");
13607 DeleteFileA( msifile );
13608 return;
13609 }
13610 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13611
13612 r = MsiGetFeatureInfoA( 0, NULL, NULL, NULL, NULL, NULL, NULL );
13613 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13614
13615 r = MsiGetFeatureInfoA( package, NULL, NULL, NULL, NULL, NULL, NULL );
13616 ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
13617
13618 r = MsiGetFeatureInfoA( package, "", NULL, NULL, NULL, NULL, NULL );
13619 ok(r == ERROR_UNKNOWN_FEATURE, "expected ERROR_UNKNOWN_FEATURE, got %u\n", r);
13620
13621 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, NULL, NULL, NULL );
13622 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13623
13624 r = MsiGetFeatureInfoA( 0, "One", NULL, NULL, NULL, NULL, NULL );
13625 ok(r == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", r);
13626
13627 title_len = help_len = 0;
13628 r = MsiGetFeatureInfoA( package, "One", NULL, NULL, &title_len, NULL, &help_len );
13629 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13630 ok(title_len == 3, "expected 3, got %u\n", title_len);
13631 ok(help_len == 3, "expected 3, got %u\n", help_len);
13632
13633 title[0] = help[0] = 0;
13634 title_len = help_len = 0;
13635 r = MsiGetFeatureInfoA( package, "One", NULL, title, &title_len, help, &help_len );
13636 ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %u\n", r);
13637 ok(title_len == 3, "expected 3, got %u\n", title_len);
13638 ok(help_len == 3, "expected 3, got %u\n", help_len);
13639
13640 attrs = 0;
13641 title[0] = help[0] = 0;
13642 title_len = sizeof(title);
13643 help_len = sizeof(help);
13644 r = MsiGetFeatureInfoA( package, "One", &attrs, title, &title_len, help, &help_len );
13645 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13646 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
13647 ok(title_len == 3, "expected 3, got %u\n", title_len);
13648 ok(help_len == 3, "expected 3, got %u\n", help_len);
13649 ok(!strcmp(title, "One"), "expected \"One\", got \"%s\"\n", title);
13650 ok(!strcmp(help, "One"), "expected \"One\", got \"%s\"\n", help);
13651
13652 attrs = 0;
13653 title[0] = help[0] = 0;
13654 title_len = sizeof(title);
13655 help_len = sizeof(help);
13656 r = MsiGetFeatureInfoA( package, "Two", &attrs, title, &title_len, help, &help_len );
13657 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13658 ok(attrs == INSTALLFEATUREATTRIBUTE_FAVORLOCAL, "expected INSTALLFEATUREATTRIBUTE_FAVORLOCAL, got %u\n", attrs);
13659 ok(!title_len, "expected 0, got %u\n", title_len);
13660 ok(!help_len, "expected 0, got %u\n", help_len);
13661 ok(!title[0], "expected \"\", got \"%s\"\n", title);
13662 ok(!help[0], "expected \"\", got \"%s\"\n", help);
13663
13664 MsiCloseHandle( package );
13665 DeleteFileA( msifile );
13666 }
13667
13668 static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg)
13669 {
13670 return IDOK;
13671 }
13672
13673 static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg)
13674 {
13675 return IDOK;
13676 }
13677
13678 static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
13679 {
13680 return IDOK;
13681 }
13682
13683 static void test_MsiSetExternalUI(void)
13684 {
13685 INSTALLUI_HANDLERA ret_a;
13686 INSTALLUI_HANDLERW ret_w;
13687 INSTALLUI_HANDLER_RECORD prev;
13688 UINT error;
13689
13690 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
13691 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13692
13693 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
13694 ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a);
13695
13696 /* Not present before Installer 3.1 */
13697 if (!pMsiSetExternalUIRecord) {
13698 win_skip("MsiSetExternalUIRecord is not available\n");
13699 return;
13700 }
13701
13702 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
13703 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13704 ok(prev == NULL, "expected NULL, got %p\n", prev);
13705
13706 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13707 error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev);
13708 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13709 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
13710
13711 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
13712 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13713
13714 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
13715 ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w);
13716
13717 ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL);
13718 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13719
13720 ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL);
13721 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13722
13723 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13724 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev);
13725 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13726 ok(prev == NULL, "expected NULL, got %p\n", prev);
13727
13728 ret_a = MsiSetExternalUIA(NULL, 0, NULL);
13729 ok(ret_a == NULL, "expected NULL, got %p\n", ret_a);
13730
13731 ret_w = MsiSetExternalUIW(NULL, 0, NULL);
13732 ok(ret_w == NULL, "expected NULL, got %p\n", ret_w);
13733
13734 prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef;
13735 error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev);
13736 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13737 ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev);
13738
13739 error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL);
13740 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13741
13742 error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL);
13743 ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
13744 }
13745
13746 static void test_lastusedsource(void)
13747 {
13748 static char prodcode[] = "{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}";
13749 char value[MAX_PATH], path[MAX_PATH];
13750 DWORD size;
13751 UINT r;
13752
13753 if (!pMsiSourceListGetInfoA)
13754 {
13755 win_skip("MsiSourceListGetInfoA is not available\n");
13756 return;
13757 }
13758
13759 CreateDirectoryA("msitest", NULL);
13760 create_file("maximus", "maximus", 500);
13761 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
13762 DeleteFile("maximus");
13763
13764 create_database("msifile0.msi", lus0_tables, sizeof(lus0_tables) / sizeof(msi_table));
13765 create_database("msifile1.msi", lus1_tables, sizeof(lus1_tables) / sizeof(msi_table));
13766 create_database("msifile2.msi", lus2_tables, sizeof(lus2_tables) / sizeof(msi_table));
13767
13768 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13769
13770 /* no cabinet file */
13771
13772 size = MAX_PATH;
13773 lstrcpyA(value, "aaa");
13774 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13775 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
13776 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13777 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13778
13779 r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
13780 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13781 {
13782 skip("Not enough rights to perform tests\n");
13783 goto error;
13784 }
13785 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13786
13787 lstrcpyA(path, CURR_DIR);
13788 lstrcatA(path, "\\");
13789
13790 size = MAX_PATH;
13791 lstrcpyA(value, "aaa");
13792 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13793 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
13794 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13795 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13796 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
13797
13798 r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL");
13799 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13800
13801 /* separate cabinet file */
13802
13803 size = MAX_PATH;
13804 lstrcpyA(value, "aaa");
13805 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13806 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
13807 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13808 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13809
13810 r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
13811 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13812
13813 lstrcpyA(path, CURR_DIR);
13814 lstrcatA(path, "\\");
13815
13816 size = MAX_PATH;
13817 lstrcpyA(value, "aaa");
13818 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13819 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
13820 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13821 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13822 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
13823
13824 r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL");
13825 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13826
13827 size = MAX_PATH;
13828 lstrcpyA(value, "aaa");
13829 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13830 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
13831 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13832 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13833
13834 /* embedded cabinet stream */
13835
13836 add_cabinet_storage("msifile2.msi", "test1.cab");
13837
13838 r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
13839 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13840
13841 size = MAX_PATH;
13842 lstrcpyA(value, "aaa");
13843 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13844 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
13845 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13846 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
13847 ok(size == lstrlenA(path), "expected %d, got %d\n", lstrlenA(path), size);
13848
13849 r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL");
13850 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
13851
13852 size = MAX_PATH;
13853 lstrcpyA(value, "aaa");
13854 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
13855 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCE, value, &size);
13856 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13857 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
13858
13859 error:
13860 delete_cab_files();
13861 DeleteFile("msitest\\maximus");
13862 RemoveDirectory("msitest");
13863 DeleteFile("msifile0.msi");
13864 DeleteFile("msifile1.msi");
13865 DeleteFile("msifile2.msi");
13866 }
13867
13868 static void test_setpropertyfolder(void)
13869 {
13870 UINT r;
13871 CHAR path[MAX_PATH];
13872 DWORD attr;
13873
13874 if (is_process_limited())
13875 {
13876 skip("process is limited\n");
13877 return;
13878 }
13879
13880 lstrcpyA(path, PROG_FILES_DIR);
13881 lstrcatA(path, "\\msitest\\added");
13882
13883 CreateDirectoryA("msitest", NULL);
13884 create_file("msitest\\maximus", "msitest\\maximus", 500);
13885
13886 create_database(msifile, spf_tables, sizeof(spf_tables) / sizeof(msi_table));
13887
13888 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
13889
13890 r = MsiInstallProductA(msifile, NULL);
13891 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
13892 {
13893 skip("Not enough rights to perform tests\n");
13894 goto error;
13895 }
13896 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13897 attr = GetFileAttributesA(path);
13898 if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
13899 {
13900 ok(delete_pf("msitest\\added\\maximus", TRUE), "File not installed\n");
13901 ok(delete_pf("msitest\\added", FALSE), "Directory not created\n");
13902 ok(delete_pf("msitest", FALSE), "Directory not created\n");
13903 }
13904 else
13905 {
13906 trace("changing folder property not supported\n");
13907 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
13908 ok(delete_pf("msitest", FALSE), "Directory not created\n");
13909 }
13910
13911 error:
13912 DeleteFile(msifile);
13913 DeleteFile("msitest\\maximus");
13914 RemoveDirectory("msitest");
13915 }
13916
13917 static void test_sourcedir_props(void)
13918 {
13919 UINT r;
13920
13921 if (is_process_limited())
13922 {
13923 skip("process is limited\n");
13924 return;
13925 }
13926
13927 create_test_files();
13928 create_file("msitest\\sourcedir.txt", "msitest\\sourcedir.txt", 1000);
13929 create_database(msifile, sd_tables, sizeof(sd_tables) / sizeof(msi_table));
13930
13931 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
13932
13933 /* full UI, no ResolveSource action */
13934 r = MsiInstallProductA(msifile, NULL);
13935 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13936
13937 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13938 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13939
13940 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13941 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
13942
13943 /* full UI, ResolveSource action */
13944 r = MsiInstallProductA(msifile, "ResolveSource=1");
13945 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13946
13947 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13948 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13949
13950 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13951 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
13952
13953 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
13954
13955 /* no UI, no ResolveSource action */
13956 r = MsiInstallProductA(msifile, NULL);
13957 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13958
13959 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13960 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13961
13962 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13963 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
13964
13965 /* no UI, ResolveSource action */
13966 r = MsiInstallProductA(msifile, "ResolveSource=1");
13967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13968
13969 r = MsiInstallProductA(msifile, "REMOVE=ALL");
13970 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13971
13972 ok(!delete_pf("msitest\\sourcedir.txt", TRUE), "file not removed\n");
13973 ok(!delete_pf("msitest", FALSE), "directory not removed\n");
13974
13975 DeleteFileA("msitest\\sourcedir.txt");
13976 delete_test_files();
13977 DeleteFile(msifile);
13978 }
13979
13980 static void test_concurrentinstall(void)
13981 {
13982 UINT r;
13983 CHAR path[MAX_PATH];
13984
13985 if (is_process_limited())
13986 {
13987 skip("process is limited\n");
13988 return;
13989 }
13990
13991 CreateDirectoryA("msitest", NULL);
13992 CreateDirectoryA("msitest\\msitest", NULL);
13993 create_file("msitest\\maximus", "msitest\\maximus", 500);
13994 create_file("msitest\\msitest\\augustus", "msitest\\msitest\\augustus", 500);
13995
13996 create_database(msifile, ci_tables, sizeof(ci_tables) / sizeof(msi_table));
13997
13998 lstrcpyA(path, CURR_DIR);
13999 lstrcatA(path, "\\msitest\\concurrent.msi");
14000 create_database(path, ci2_tables, sizeof(ci2_tables) / sizeof(msi_table));
14001
14002 MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
14003
14004 r = MsiInstallProductA(msifile, NULL);
14005 if (r == ERROR_INSTALL_PACKAGE_REJECTED)
14006 {
14007 skip("Not enough rights to perform tests\n");
14008 DeleteFile(path);
14009 goto error;
14010 }
14011 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14012 if (!delete_pf("msitest\\augustus", TRUE))
14013 trace("concurrent installs not supported\n");
14014 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14015 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14016
14017 r = MsiConfigureProductA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", INSTALLLEVEL_DEFAULT,
14018 INSTALLSTATE_ABSENT);
14019 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14020
14021 DeleteFile(path);
14022
14023 error:
14024 DeleteFile(msifile);
14025 DeleteFile("msitest\\msitest\\augustus");
14026 DeleteFile("msitest\\maximus");
14027 RemoveDirectory("msitest\\msitest");
14028 RemoveDirectory("msitest");
14029 }
14030
14031 static void test_command_line_parsing(void)
14032 {
14033 UINT r;
14034 const char *cmd;
14035
14036 if (is_process_limited())
14037 {
14038 skip("process is limited\n");
14039 return;
14040 }
14041
14042 create_test_files();
14043 create_database(msifile, cl_tables, sizeof(cl_tables)/sizeof(msi_table));
14044
14045 MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
14046
14047 cmd = " ";
14048 r = MsiInstallProductA(msifile, cmd);
14049 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14050
14051 cmd = "=";
14052 r = MsiInstallProductA(msifile, cmd);
14053 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14054
14055 cmd = "==";
14056 r = MsiInstallProductA(msifile, cmd);
14057 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14058
14059 cmd = "one";
14060 r = MsiInstallProductA(msifile, cmd);
14061 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14062
14063 cmd = "=one";
14064 r = MsiInstallProductA(msifile, cmd);
14065 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14066
14067 cmd = "P=";
14068 r = MsiInstallProductA(msifile, cmd);
14069 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14070
14071 cmd = " P=";
14072 r = MsiInstallProductA(msifile, cmd);
14073 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14074
14075 cmd = "P= ";
14076 r = MsiInstallProductA(msifile, cmd);
14077 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14078
14079 cmd = "P=\"";
14080 r = MsiInstallProductA(msifile, cmd);
14081 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14082
14083 cmd = "P=\"\"";
14084 r = MsiInstallProductA(msifile, cmd);
14085 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14086
14087 cmd = "P=\"\"\"";
14088 r = MsiInstallProductA(msifile, cmd);
14089 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14090
14091 cmd = "P=\"\"\"\"";
14092 r = MsiInstallProductA(msifile, cmd);
14093 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14094
14095 cmd = "P=\" ";
14096 r = MsiInstallProductA(msifile, cmd);
14097 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14098
14099 cmd = "P= \"";
14100 r = MsiInstallProductA(msifile, cmd);
14101 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14102
14103 cmd = "P= \"\" ";
14104 r = MsiInstallProductA(msifile, cmd);
14105 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14106
14107 cmd = "P=\" \"";
14108 r = MsiInstallProductA(msifile, cmd);
14109 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14110
14111 cmd = "P=one";
14112 r = MsiInstallProductA(msifile, cmd);
14113 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14114
14115 cmd = "P= one";
14116 r = MsiInstallProductA(msifile, cmd);
14117 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14118
14119 cmd = "P=\"one";
14120 r = MsiInstallProductA(msifile, cmd);
14121 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14122
14123 cmd = "P=one\"";
14124 r = MsiInstallProductA(msifile, cmd);
14125 todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14126
14127 cmd = "P=\"one\"";
14128 r = MsiInstallProductA(msifile, cmd);
14129 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14130
14131 cmd = "P= \"one\" ";
14132 r = MsiInstallProductA(msifile, cmd);
14133 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14134
14135 cmd = "P=\"one\"\"";
14136 r = MsiInstallProductA(msifile, cmd);
14137 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14138
14139 cmd = "P=\"\"one\"";
14140 r = MsiInstallProductA(msifile, cmd);
14141 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14142
14143 cmd = "P=\"\"one\"\"";
14144 r = MsiInstallProductA(msifile, cmd);
14145 todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14146
14147 cmd = "P=\"one two\"";
14148 r = MsiInstallProductA(msifile, cmd);
14149 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14150
14151 cmd = "P=\"\"\"one\"\" two\"";
14152 r = MsiInstallProductA(msifile, cmd);
14153 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14154
14155 cmd = "P=\"\"\"one\"\" two\" Q=three";
14156 r = MsiInstallProductA(msifile, cmd);
14157 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14158
14159 cmd = "P=\"\" Q=\"two\"";
14160 r = MsiInstallProductA(msifile, cmd);
14161 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14162
14163 cmd = "P=\"one\" Q=\"two\"";
14164 r = MsiInstallProductA(msifile, cmd);
14165 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14166
14167 cmd = "P=\"one=two\"";
14168 r = MsiInstallProductA(msifile, cmd);
14169 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14170
14171 cmd = "Q=\"\" P=\"one\"";
14172 r = MsiInstallProductA(msifile, cmd);
14173 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14174
14175 cmd = "P=\"\"\"one\"\"\" Q=\"two\"";
14176 r = MsiInstallProductA(msifile, cmd);
14177 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14178
14179 cmd = "P=\"one \"\"two\"\"\" Q=\"three\"";
14180 r = MsiInstallProductA(msifile, cmd);
14181 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14182
14183 cmd = "P=\"\"\"one\"\" two\" Q=\"three\"";
14184 r = MsiInstallProductA(msifile, cmd);
14185 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14186
14187 DeleteFile(msifile);
14188 delete_test_files();
14189 }
14190
14191 START_TEST(msi)
14192 {
14193 DWORD len;
14194 char temp_path[MAX_PATH], prev_path[MAX_PATH];
14195
14196 init_functionpointers();
14197
14198 if (pIsWow64Process)
14199 pIsWow64Process(GetCurrentProcess(), &is_wow64);
14200
14201 GetCurrentDirectoryA(MAX_PATH, prev_path);
14202 GetTempPath(MAX_PATH, temp_path);
14203 SetCurrentDirectoryA(temp_path);
14204
14205 lstrcpyA(CURR_DIR, temp_path);
14206 len = lstrlenA(CURR_DIR);
14207
14208 if(len && (CURR_DIR[len - 1] == '\\'))
14209 CURR_DIR[len - 1] = 0;
14210
14211 ok(get_system_dirs(), "failed to retrieve system dirs\n");
14212
14213 test_usefeature();
14214 test_null();
14215 test_getcomponentpath();
14216 test_MsiGetFileHash();
14217
14218 if (!pConvertSidToStringSidA)
14219 win_skip("ConvertSidToStringSidA not implemented\n");
14220 else
14221 {
14222 /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
14223 test_MsiQueryProductState();
14224 test_MsiQueryFeatureState();
14225 test_MsiQueryComponentState();
14226 test_MsiGetComponentPath();
14227 test_MsiGetProductCode();
14228 test_MsiEnumClients();
14229 test_MsiGetProductInfo();
14230 test_MsiGetProductInfoEx();
14231 test_MsiGetUserInfo();
14232 test_MsiOpenProduct();
14233 test_MsiEnumPatchesEx();
14234 test_MsiEnumPatches();
14235 test_MsiGetPatchInfoEx();
14236 test_MsiGetPatchInfo();
14237 test_MsiEnumProducts();
14238 test_MsiEnumProductsEx();
14239 test_MsiEnumComponents();
14240 test_MsiEnumComponentsEx();
14241 }
14242 test_MsiGetFileVersion();
14243 test_MsiGetFileSignatureInformation();
14244 test_MsiConfigureProductEx();
14245 test_MsiSetFeatureAttributes();
14246 test_MsiGetFeatureInfo();
14247 test_MsiSetExternalUI();
14248 test_lastusedsource();
14249 test_setpropertyfolder();
14250 test_sourcedir_props();
14251 test_concurrentinstall();
14252 test_command_line_parsing();
14253
14254 SetCurrentDirectoryA(prev_path);
14255 }