ReactOS  0.4.13-dev-39-g8b6696f
msi.c
Go to the documentation of this file.
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #define _WIN32_MSI 300
22 #define COBJMACROS
23 
24 #include <stdio.h>
25 #include <windows.h>
26 #include <msi.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <sddl.h>
30 #include <fci.h>
31 #include <shellapi.h>
32 #include <objidl.h>
33 
34 #include "wine/test.h"
35 
36 static BOOL is_wow64;
37 static const char msifile[] = "winetest.msi";
38 static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','.','m','s','i',0};
39 static char CURR_DIR[MAX_PATH];
40 static char PROG_FILES_DIR[MAX_PATH];
43 static char WINDOWS_DIR[MAX_PATH];
44 
45 static BOOL (WINAPI *pCheckTokenMembership)(HANDLE,PSID,PBOOL);
46 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
47 static BOOL (WINAPI *pOpenProcessToken)( HANDLE, DWORD, PHANDLE );
48 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
49 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
50 
51 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
53 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
55 static INSTALLSTATE (WINAPI *pMsiProvideComponentA)
57 static INSTALLSTATE (WINAPI *pMsiProvideComponentW)
59 static UINT (WINAPI *pMsiGetFileHashA)
61 static UINT (WINAPI *pMsiGetProductInfoExA)
63 static UINT (WINAPI *pMsiOpenPackageExA)
64  (LPCSTR, DWORD, MSIHANDLE*);
65 static UINT (WINAPI *pMsiOpenPackageExW)
66  (LPCWSTR, DWORD, MSIHANDLE*);
67 static UINT (WINAPI *pMsiEnumPatchesExA)
70 static UINT (WINAPI *pMsiQueryComponentStateA)
72 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
73  (LPCSTR, LPCSTR ,DWORD, DWORD);
74 static UINT (WINAPI *pMsiGetPatchInfoExA)
76 static UINT (WINAPI *pMsiEnumProductsExA)
78 static UINT (WINAPI *pMsiEnumComponentsExA)
80 static UINT (WINAPI *pMsiSetExternalUIRecord)
82 static UINT (WINAPI *pMsiSourceListGetInfoA)
84 
85 static void init_functionpointers(void)
86 {
87  HMODULE hmsi = GetModuleHandleA("msi.dll");
88  HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
89  HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
90 
91 #define GET_PROC(dll, func) \
92  p ## func = (void *)GetProcAddress(dll, #func); \
93  if(!p ## func) \
94  trace("GetProcAddress(%s) failed\n", #func);
95 
112 
113  GET_PROC(hadvapi32, CheckTokenMembership);
114  GET_PROC(hadvapi32, ConvertSidToStringSidA)
115  GET_PROC(hadvapi32, OpenProcessToken);
116  GET_PROC(hadvapi32, RegDeleteKeyExA)
118 
119 #undef GET_PROC
120 }
121 
122 static BOOL get_system_dirs(void)
123 {
124  HKEY hkey;
125  DWORD type, size;
126 
127  if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
128  return FALSE;
129 
130  size = MAX_PATH;
131  if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
132  RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
133  {
134  RegCloseKey(hkey);
135  return FALSE;
136  }
137  size = MAX_PATH;
138  if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
139  RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
140  {
141  RegCloseKey(hkey);
142  return FALSE;
143  }
144  size = MAX_PATH;
145  if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR_NATIVE, &size))
146  {
147  RegCloseKey(hkey);
148  return FALSE;
149  }
150  RegCloseKey(hkey);
152  return TRUE;
153 }
154 
155 static BOOL file_exists(const char *file)
156 {
158 }
159 
160 static BOOL pf_exists(const char *file)
161 {
162  char path[MAX_PATH];
163 
165  lstrcatA(path, "\\");
166  lstrcatA(path, file);
167  return file_exists(path);
168 }
169 
170 static BOOL delete_pf(const char *rel_path, BOOL is_file)
171 {
172  char path[MAX_PATH];
173 
175  lstrcatA(path, "\\");
176  lstrcatA(path, rel_path);
177 
178  if (is_file)
179  return DeleteFileA(path);
180  else
181  return RemoveDirectoryA(path);
182 }
183 
185 {
187  PSID Group = NULL;
188  BOOL IsInGroup;
189  HANDLE token;
190 
191  if (!pCheckTokenMembership || !pOpenProcessToken) return FALSE;
192 
194  DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
195  !pCheckTokenMembership(NULL, Group, &IsInGroup))
196  {
197  trace("Could not check if the current user is an administrator\n");
198  FreeSid(Group);
199  return FALSE;
200  }
201  FreeSid(Group);
202 
203  if (!IsInGroup)
204  {
205  /* Only administrators have enough privileges for these tests */
206  return TRUE;
207  }
208 
209  if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
210  {
211  BOOL ret;
213  DWORD size;
214 
217  return (ret && type == TokenElevationTypeLimited);
218  }
219  return FALSE;
220 }
221 
222 /* cabinet definitions */
223 
224 /* make the max size large so there is only one cab file */
225 #define MEDIA_SIZE 0x7FFFFFFF
226 #define FOLDER_THRESHOLD 900000
227 
228 /* the FCI callbacks */
229 
230 static void * CDECL mem_alloc(ULONG cb)
231 {
232  return HeapAlloc(GetProcessHeap(), 0, cb);
233 }
234 
235 static void CDECL mem_free(void *memory)
236 {
238 }
239 
240 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG cbPrevCab, void *pv)
241 {
242  sprintf(pccab->szCab, pv, pccab->iCab);
243  return TRUE;
244 }
245 
246 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
247 {
248  return 0;
249 }
250 
251 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
252  BOOL fContinuation, void *pv)
253 {
254  return 0;
255 }
256 
257 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
258 {
259  HANDLE handle;
260  DWORD dwAccess = 0;
261  DWORD dwShareMode = 0;
262  DWORD dwCreateDisposition = OPEN_EXISTING;
263 
264  dwAccess = GENERIC_READ | GENERIC_WRITE;
265  /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
266  dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
267 
269  dwCreateDisposition = OPEN_EXISTING;
270  else
271  dwCreateDisposition = CREATE_NEW;
272 
273  handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
274  dwCreateDisposition, 0, NULL);
275 
276  ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
277 
278  return (INT_PTR)handle;
279 }
280 
281 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
282 {
283  HANDLE handle = (HANDLE)hf;
284  DWORD dwRead;
285  BOOL res;
286 
287  res = ReadFile(handle, memory, cb, &dwRead, NULL);
288  ok(res, "Failed to ReadFile\n");
289 
290  return dwRead;
291 }
292 
293 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
294 {
295  HANDLE handle = (HANDLE)hf;
296  DWORD dwWritten;
297  BOOL res;
298 
299  res = WriteFile(handle, memory, cb, &dwWritten, NULL);
300  ok(res, "Failed to WriteFile\n");
301 
302  return dwWritten;
303 }
304 
305 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
306 {
307  HANDLE handle = (HANDLE)hf;
308  ok(CloseHandle(handle), "Failed to CloseHandle\n");
309 
310  return 0;
311 }
312 
313 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
314 {
315  HANDLE handle = (HANDLE)hf;
316  DWORD ret;
317 
318  ret = SetFilePointer(handle, dist, NULL, seektype);
319  ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
320 
321  return ret;
322 }
323 
324 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
325 {
326  BOOL ret = DeleteFileA(pszFile);
327  ok(ret, "Failed to DeleteFile %s\n", pszFile);
328 
329  return 0;
330 }
331 
332 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
333 {
334  LPSTR tempname;
335 
336  tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
337  GetTempFileNameA(".", "xx", 0, tempname);
338 
339  if (tempname && (strlen(tempname) < (unsigned)cbTempName))
340  {
341  lstrcpyA(pszTempName, tempname);
342  HeapFree(GetProcessHeap(), 0, tempname);
343  return TRUE;
344  }
345 
346  HeapFree(GetProcessHeap(), 0, tempname);
347 
348  return FALSE;
349 }
350 
351 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
352  USHORT *pattribs, int *err, void *pv)
353 {
356  HANDLE handle;
357  DWORD attrs;
358  BOOL res;
359 
362  ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
363 
365  ok(res, "Expected GetFileInformationByHandle to succeed\n");
366 
368  FileTimeToDosDateTime(&filetime, pdate, ptime);
369 
370  attrs = GetFileAttributesA(pszName);
371  ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
372 
373  return (INT_PTR)handle;
374 }
375 
376 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
377 {
378  char path[MAX_PATH];
379  char filename[MAX_PATH];
380 
382  lstrcatA(path, "\\");
383  lstrcatA(path, file);
384 
386 
389 }
390 
391 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
392 {
393  ZeroMemory(pCabParams, sizeof(CCAB));
394 
395  pCabParams->cb = max_size;
396  pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
397  pCabParams->setID = 0xbeef;
398  pCabParams->iCab = 1;
399  lstrcpyA(pCabParams->szCabPath, CURR_DIR);
400  lstrcatA(pCabParams->szCabPath, "\\");
401  lstrcpyA(pCabParams->szCab, name);
402 }
403 
404 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
405 {
406  CCAB cabParams;
407  LPCSTR ptr;
408  HFCI hfci;
409  ERF erf;
410  BOOL res;
411 
412  set_cab_parameters(&cabParams, name, max_size);
413 
416  get_temp_file, &cabParams, NULL);
417 
418  ok(hfci != NULL, "Failed to create an FCI context\n");
419 
420  ptr = files;
421  while (*ptr)
422  {
423  res = add_file(hfci, ptr, tcompTYPE_MSZIP);
424  ok(res, "Failed to add file: %s\n", ptr);
425  ptr += lstrlenA(ptr) + 1;
426  }
427 
429  ok(res, "Failed to flush the cabinet\n");
430 
431  res = FCIDestroy(hfci);
432  ok(res, "Failed to destroy the cabinet\n");
433 }
434 
436 {
437  WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
438  IStorage *stg;
439  IStream *stm;
440  HRESULT hr;
441  HANDLE handle;
442 
443  MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
445  if (FAILED(hr))
446  return FALSE;
447 
448  MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
449  hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
450  if (FAILED(hr))
451  {
452  IStorage_Release(stg);
453  return FALSE;
454  }
455 
456  handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
458  {
459  DWORD count;
460  char buffer[1024];
461  if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
462  IStream_Write(stm, buffer, count, &count);
464  }
465 
466  IStream_Release(stm);
467  IStorage_Release(stg);
468 
469  return TRUE;
470 }
471 
472 static void delete_cab_files(void)
473 {
474  SHFILEOPSTRUCTA shfl;
475  CHAR path[MAX_PATH+10];
476 
478  lstrcatA(path, "\\*.cab");
479  path[strlen(path) + 1] = '\0';
480 
481  shfl.hwnd = NULL;
482  shfl.wFunc = FO_DELETE;
483  shfl.pFrom = path;
484  shfl.pTo = NULL;
486 
487  SHFileOperationA(&shfl);
488 }
489 
490 /* msi database data */
491 
492 static const char directory_dat[] =
493  "Directory\tDirectory_Parent\tDefaultDir\n"
494  "s72\tS72\tl255\n"
495  "Directory\tDirectory\n"
496  "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
497  "ProgramFilesFolder\tTARGETDIR\t.\n"
498  "TARGETDIR\t\tSourceDir";
499 
500 static const char component_dat[] =
501  "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
502  "s72\tS38\ts72\ti2\tS255\tS72\n"
503  "Component\tComponent\n"
504  "One\t{8F5BAEEF-DD92-40AC-9397-BE3CF9F97C81}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n";
505 
506 static const char feature_dat[] =
507  "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
508  "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
509  "Feature\tFeature\n"
510  "One\t\tOne\tOne\t1\t3\tMSITESTDIR\t0\n"
511  "Two\t\t\t\t2\t1\tTARGETDIR\t0\n";
512 
513 static const char feature_comp_dat[] =
514  "Feature_\tComponent_\n"
515  "s38\ts72\n"
516  "FeatureComponents\tFeature_\tComponent_\n"
517  "One\tOne\n";
518 
519 static const char file_dat[] =
520  "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
521  "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
522  "File\tFile\n"
523  "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n";
524 
525 static const char install_exec_seq_dat[] =
526  "Action\tCondition\tSequence\n"
527  "s72\tS255\tI2\n"
528  "InstallExecuteSequence\tAction\n"
529  "ValidateProductID\t\t700\n"
530  "CostInitialize\t\t800\n"
531  "FileCost\t\t900\n"
532  "CostFinalize\t\t1000\n"
533  "InstallValidate\t\t1400\n"
534  "InstallInitialize\t\t1500\n"
535  "ProcessComponents\t\t1600\n"
536  "UnpublishFeatures\t\t1800\n"
537  "RemoveFiles\t\t3500\n"
538  "InstallFiles\t\t4000\n"
539  "RegisterProduct\t\t6100\n"
540  "PublishFeatures\t\t6300\n"
541  "PublishProduct\t\t6400\n"
542  "InstallFinalize\t\t6600";
543 
544 static const char media_dat[] =
545  "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
546  "i2\ti4\tL64\tS255\tS32\tS72\n"
547  "Media\tDiskId\n"
548  "1\t1\t\t\tDISK1\t\n";
549 
550 static const char property_dat[] =
551  "Property\tValue\n"
552  "s72\tl0\n"
553  "Property\tProperty\n"
554  "INSTALLLEVEL\t3\n"
555  "Manufacturer\tWine\n"
556  "ProductCode\t{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}\n"
557  "ProductName\tMSITEST\n"
558  "ProductVersion\t1.1.1\n"
559  "UpgradeCode\t{9574448F-9B86-4E07-B6F6-8D199DA12127}\n"
560  "MSIFASTINSTALL\t1\n";
561 
562 static const char ci2_property_dat[] =
563  "Property\tValue\n"
564  "s72\tl0\n"
565  "Property\tProperty\n"
566  "INSTALLLEVEL\t3\n"
567  "Manufacturer\tWine\n"
568  "ProductCode\t{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}\n"
569  "ProductName\tMSITEST2\n"
570  "ProductVersion\t1.1.1\n"
571  "UpgradeCode\t{6B60C3CA-B8CA-4FB7-A395-092D98FF5D2A}\n"
572  "MSIFASTINSTALL\t1\n";
573 
574 static const char mcp_component_dat[] =
575  "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
576  "s72\tS38\ts72\ti2\tS255\tS72\n"
577  "Component\tComponent\n"
578  "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t2\t\thydrogen\n"
579  "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t2\t\thelium\n"
580  "lithium\t{4AF28FFC-71C7-4307-BDE4-B77C5338F56F}\tMSITESTDIR\t2\tPROPVAR=42\tlithium\n";
581 
582 static const char mcp_feature_dat[] =
583  "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
584  "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
585  "Feature\tFeature\n"
586  "hydroxyl\t\thydroxyl\thydroxyl\t2\t1\tTARGETDIR\t0\n"
587  "heliox\t\theliox\theliox\t2\t5\tTARGETDIR\t0\n"
588  "lithia\t\tlithia\tlithia\t2\t10\tTARGETDIR\t0";
589 
590 static const char mcp_feature_comp_dat[] =
591  "Feature_\tComponent_\n"
592  "s38\ts72\n"
593  "FeatureComponents\tFeature_\tComponent_\n"
594  "hydroxyl\thydrogen\n"
595  "heliox\thelium\n"
596  "lithia\tlithium";
597 
598 static const char mcp_file_dat[] =
599  "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
600  "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
601  "File\tFile\n"
602  "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
603  "helium\thelium\thelium\t0\t\t\t8192\t1\n"
604  "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
605 
606 static const char lus_component_dat[] =
607  "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
608  "s72\tS38\ts72\ti2\tS255\tS72\n"
609  "Component\tComponent\n"
610  "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
611 
612 static const char lus_feature_dat[] =
613  "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
614  "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
615  "Feature\tFeature\n"
616  "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
617  "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
618 
619 static const char lus_file_dat[] =
620  "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
621  "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
622  "File\tFile\n"
623  "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
624 
625 static const char lus_feature_comp_dat[] =
626  "Feature_\tComponent_\n"
627  "s38\ts72\n"
628  "FeatureComponents\tFeature_\tComponent_\n"
629  "feature\tmaximus\n"
630  "montecristo\tmaximus";
631 
632 static const char lus_install_exec_seq_dat[] =
633  "Action\tCondition\tSequence\n"
634  "s72\tS255\tI2\n"
635  "InstallExecuteSequence\tAction\n"
636  "ValidateProductID\t\t700\n"
637  "CostInitialize\t\t800\n"
638  "FileCost\t\t900\n"
639  "CostFinalize\t\t1000\n"
640  "InstallValidate\t\t1400\n"
641  "InstallInitialize\t\t1500\n"
642  "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
643  "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
644  "RemoveFiles\t\t3500\n"
645  "InstallFiles\t\t4000\n"
646  "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
647  "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
648  "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
649  "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
650  "InstallFinalize\t\t6600";
651 
652 static const char lus0_media_dat[] =
653  "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
654  "i2\ti4\tL64\tS255\tS32\tS72\n"
655  "Media\tDiskId\n"
656  "1\t1\t\t\tDISK1\t\n";
657 
658 static const char lus1_media_dat[] =
659  "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
660  "i2\ti4\tL64\tS255\tS32\tS72\n"
661  "Media\tDiskId\n"
662  "1\t1\t\ttest1.cab\tDISK1\t\n";
663 
664 static const char lus2_media_dat[] =
665  "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
666  "i2\ti4\tL64\tS255\tS32\tS72\n"
667  "Media\tDiskId\n"
668  "1\t1\t\t#test1.cab\tDISK1\t\n";
669 
670 static const char spf_custom_action_dat[] =
671  "Action\tType\tSource\tTarget\tISComments\n"
672  "s72\ti2\tS64\tS0\tS255\n"
673  "CustomAction\tAction\n"
674  "SetFolderProp\t51\tMSITESTDIR\t[ProgramFilesFolder]\\msitest\\added\t\n";
675 
676 static const char spf_install_exec_seq_dat[] =
677  "Action\tCondition\tSequence\n"
678  "s72\tS255\tI2\n"
679  "InstallExecuteSequence\tAction\n"
680  "CostFinalize\t\t1000\n"
681  "CostInitialize\t\t800\n"
682  "FileCost\t\t900\n"
683  "SetFolderProp\t\t950\n"
684  "InstallFiles\t\t4000\n"
685  "InstallServices\t\t5000\n"
686  "InstallFinalize\t\t6600\n"
687  "InstallInitialize\t\t1500\n"
688  "InstallValidate\t\t1400\n"
689  "LaunchConditions\t\t100";
690 
691 static const char spf_install_ui_seq_dat[] =
692  "Action\tCondition\tSequence\n"
693  "s72\tS255\tI2\n"
694  "InstallUISequence\tAction\n"
695  "CostInitialize\t\t800\n"
696  "FileCost\t\t900\n"
697  "CostFinalize\t\t1000\n"
698  "ExecuteAction\t\t1100\n";
699 
700 static const char sd_file_dat[] =
701  "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
702  "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
703  "File\tFile\n"
704  "sourcedir.txt\tsourcedir\tsourcedir.txt\t1000\t\t\t8192\t1\n";
705 
706 static const char sd_feature_dat[] =
707  "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
708  "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
709  "Feature\tFeature\n"
710  "sourcedir\t\t\tsourcedir feature\t1\t2\tMSITESTDIR\t0\n";
711 
712 static const char sd_feature_comp_dat[] =
713  "Feature_\tComponent_\n"
714  "s38\ts72\n"
715  "FeatureComponents\tFeature_\tComponent_\n"
716  "sourcedir\tsourcedir\n";
717 
718 static const char sd_component_dat[] =
719  "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
720  "s72\tS38\ts72\ti2\tS255\tS72\n"
721  "Component\tComponent\n"
722  "sourcedir\t{DD422F92-3ED8-49B5-A0B7-F266F98357DF}\tMSITESTDIR\t0\t\tsourcedir.txt\n";
723 
724 static const char sd_install_ui_seq_dat[] =
725  "Action\tCondition\tSequence\n"
726  "s72\tS255\tI2\n"
727  "InstallUISequence\tAction\n"
728  "TestSourceDirProp1\tnot SourceDir and not SOURCEDIR and not Installed\t99\n"
729  "AppSearch\t\t100\n"
730  "TestSourceDirProp2\tnot SourceDir and not SOURCEDIR and not Installed\t101\n"
731  "LaunchConditions\tnot Installed \t110\n"
732  "TestSourceDirProp3\tnot SourceDir and not SOURCEDIR and not Installed\t111\n"
733  "FindRelatedProducts\t\t120\n"
734  "TestSourceDirProp4\tnot SourceDir and not SOURCEDIR and not Installed\t121\n"
735  "CCPSearch\t\t130\n"
736  "TestSourceDirProp5\tnot SourceDir and not SOURCEDIR and not Installed\t131\n"
737  "RMCCPSearch\t\t140\n"
738  "TestSourceDirProp6\tnot SourceDir and not SOURCEDIR and not Installed\t141\n"
739  "ValidateProductID\t\t150\n"
740  "TestSourceDirProp7\tnot SourceDir and not SOURCEDIR and not Installed\t151\n"
741  "CostInitialize\t\t800\n"
742  "TestSourceDirProp8\tnot SourceDir and not SOURCEDIR and not Installed\t801\n"
743  "FileCost\t\t900\n"
744  "TestSourceDirProp9\tnot SourceDir and not SOURCEDIR and not Installed\t901\n"
745  "IsolateComponents\t\t1000\n"
746  "TestSourceDirProp10\tnot SourceDir and not SOURCEDIR and not Installed\t1001\n"
747  "CostFinalize\t\t1100\n"
748  "TestSourceDirProp11\tnot SourceDir and not SOURCEDIR and not Installed\t1101\n"
749  "MigrateFeatureStates\t\t1200\n"
750  "TestSourceDirProp12\tnot SourceDir and not SOURCEDIR and not Installed\t1201\n"
751  "ExecuteAction\t\t1300\n"
752  "TestSourceDirProp13\tnot SourceDir and not SOURCEDIR and not Installed\t1301\n";
753 
754 static const char sd_install_exec_seq_dat[] =
755  "Action\tCondition\tSequence\n"
756  "s72\tS255\tI2\n"
757  "InstallExecuteSequence\tAction\n"
758  "TestSourceDirProp14\tSourceDir and SOURCEDIR and not Installed\t99\n"
759  "LaunchConditions\t\t100\n"
760  "TestSourceDirProp15\tSourceDir and SOURCEDIR and not Installed\t101\n"
761  "ValidateProductID\t\t700\n"
762  "TestSourceDirProp16\tSourceDir and SOURCEDIR and not Installed\t701\n"
763  "CostInitialize\t\t800\n"
764  "TestSourceDirProp17\tSourceDir and SOURCEDIR and not Installed\t801\n"
765  "ResolveSource\tResolveSource and not Installed\t850\n"
766  "TestSourceDirProp18\tResolveSource and not SourceDir and not SOURCEDIR and not Installed\t851\n"
767  "TestSourceDirProp19\tnot ResolveSource and SourceDir and SOURCEDIR and not Installed\t852\n"
768  "FileCost\t\t900\n"
769  "TestSourceDirProp20\tSourceDir and SOURCEDIR and not Installed\t901\n"
770  "IsolateComponents\t\t1000\n"
771  "TestSourceDirProp21\tSourceDir and SOURCEDIR and not Installed\t1001\n"
772  "CostFinalize\t\t1100\n"
773  "TestSourceDirProp22\tSourceDir and SOURCEDIR and not Installed\t1101\n"
774  "MigrateFeatureStates\t\t1200\n"
775  "TestSourceDirProp23\tSourceDir and SOURCEDIR and not Installed\t1201\n"
776  "InstallValidate\t\t1400\n"
777  "TestSourceDirProp24\tSourceDir and SOURCEDIR and not Installed\t1401\n"
778  "InstallInitialize\t\t1500\n"
779  "TestSourceDirProp25\tSourceDir and SOURCEDIR and not Installed\t1501\n"
780  "ProcessComponents\t\t1600\n"
781  "TestSourceDirProp26\tnot SourceDir and not SOURCEDIR and not Installed\t1601\n"
782  "UnpublishFeatures\t\t1800\n"
783  "TestSourceDirProp27\tnot SourceDir and not SOURCEDIR and not Installed\t1801\n"
784  "RemoveFiles\t\t3500\n"
785  "TestSourceDirProp28\tnot SourceDir and not SOURCEDIR and not Installed\t3501\n"
786  "InstallFiles\t\t4000\n"
787  "TestSourceDirProp29\tnot SourceDir and not SOURCEDIR and not Installed\t4001\n"
788  "RegisterUser\t\t6000\n"
789  "TestSourceDirProp30\tnot SourceDir and not SOURCEDIR and not Installed\t6001\n"
790  "RegisterProduct\t\t6100\n"
791  "TestSourceDirProp31\tnot SourceDir and not SOURCEDIR and not Installed\t6101\n"
792  "PublishFeatures\t\t6300\n"
793  "TestSourceDirProp32\tnot SourceDir and not SOURCEDIR and not Installed\t6301\n"
794  "PublishProduct\t\t6400\n"
795  "TestSourceDirProp33\tnot SourceDir and not SOURCEDIR and not Installed\t6401\n"
796  "InstallExecute\t\t6500\n"
797  "TestSourceDirProp34\tnot SourceDir and not SOURCEDIR and not Installed\t6501\n"
798  "InstallFinalize\t\t6600\n"
799  "TestSourceDirProp35\tnot SourceDir and not SOURCEDIR and not Installed\t6601\n";
800 
801 static const char sd_custom_action_dat[] =
802  "Action\tType\tSource\tTarget\tISComments\n"
803  "s72\ti2\tS64\tS0\tS255\n"
804  "CustomAction\tAction\n"
805  "TestSourceDirProp1\t19\t\tTest 1 failed\t\n"
806  "TestSourceDirProp2\t19\t\tTest 2 failed\t\n"
807  "TestSourceDirProp3\t19\t\tTest 3 failed\t\n"
808  "TestSourceDirProp4\t19\t\tTest 4 failed\t\n"
809  "TestSourceDirProp5\t19\t\tTest 5 failed\t\n"
810  "TestSourceDirProp6\t19\t\tTest 6 failed\t\n"
811  "TestSourceDirProp7\t19\t\tTest 7 failed\t\n"
812  "TestSourceDirProp8\t19\t\tTest 8 failed\t\n"
813  "TestSourceDirProp9\t19\t\tTest 9 failed\t\n"
814  "TestSourceDirProp10\t19\t\tTest 10 failed\t\n"
815  "TestSourceDirProp11\t19\t\tTest 11 failed\t\n"
816  "TestSourceDirProp12\t19\t\tTest 12 failed\t\n"
817  "TestSourceDirProp13\t19\t\tTest 13 failed\t\n"
818  "TestSourceDirProp14\t19\t\tTest 14 failed\t\n"
819  "TestSourceDirProp15\t19\t\tTest 15 failed\t\n"
820  "TestSourceDirProp16\t19\t\tTest 16 failed\t\n"
821  "TestSourceDirProp17\t19\t\tTest 17 failed\t\n"
822  "TestSourceDirProp18\t19\t\tTest 18 failed\t\n"
823  "TestSourceDirProp19\t19\t\tTest 19 failed\t\n"
824  "TestSourceDirProp20\t19\t\tTest 20 failed\t\n"
825  "TestSourceDirProp21\t19\t\tTest 21 failed\t\n"
826  "TestSourceDirProp22\t19\t\tTest 22 failed\t\n"
827  "TestSourceDirProp23\t19\t\tTest 23 failed\t\n"
828  "TestSourceDirProp24\t19\t\tTest 24 failed\t\n"
829  "TestSourceDirProp25\t19\t\tTest 25 failed\t\n"
830  "TestSourceDirProp26\t19\t\tTest 26 failed\t\n"
831  "TestSourceDirProp27\t19\t\tTest 27 failed\t\n"
832  "TestSourceDirProp28\t19\t\tTest 28 failed\t\n"
833  "TestSourceDirProp29\t19\t\tTest 29 failed\t\n"
834  "TestSourceDirProp30\t19\t\tTest 30 failed\t\n"
835  "TestSourceDirProp31\t19\t\tTest 31 failed\t\n"
836  "TestSourceDirProp32\t19\t\tTest 32 failed\t\n"
837  "TestSourceDirProp33\t19\t\tTest 33 failed\t\n"
838  "TestSourceDirProp34\t19\t\tTest 34 failed\t\n"
839  "TestSourceDirProp35\t19\t\tTest 35 failed\t\n";
840 
841 static const char ci_install_exec_seq_dat[] =
842  "Action\tCondition\tSequence\n"
843  "s72\tS255\tI2\n"
844  "InstallExecuteSequence\tAction\n"
845  "CostInitialize\t\t800\n"
846  "FileCost\t\t900\n"
847  "CostFinalize\t\t1000\n"
848  "InstallValidate\t\t1400\n"
849  "InstallInitialize\t\t1500\n"
850  "RunInstall\tnot Installed\t1550\n"
851  "ProcessComponents\t\t1600\n"
852  "UnpublishFeatures\t\t1800\n"
853  "RemoveFiles\t\t3500\n"
854  "InstallFiles\t\t4000\n"
855  "RegisterProduct\t\t6100\n"
856  "PublishFeatures\t\t6300\n"
857  "PublishProduct\t\t6400\n"
858  "InstallFinalize\t\t6600\n";
859 
860 static const char ci_custom_action_dat[] =
861  "Action\tType\tSource\tTarget\tISComments\n"
862  "s72\ti2\tS64\tS0\tS255\n"
863  "CustomAction\tAction\n"
864  "RunInstall\t23\tmsitest\\concurrent.msi\tMYPROP=[UILevel]\t\n";
865 
866 static const char ci_component_dat[] =
867  "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
868  "s72\tS38\ts72\ti2\tS255\tS72\n"
869  "Component\tComponent\n"
870  "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n";
871 
872 static const char ci2_component_dat[] =
873  "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
874  "s72\tS38\ts72\ti2\tS255\tS72\n"
875  "Component\tComponent\n"
876  "augustus\t\tMSITESTDIR\t0\tUILevel=3 AND MYPROP=5\taugustus\n";
877 
878 static const char ci2_feature_comp_dat[] =
879  "Feature_\tComponent_\n"
880  "s38\ts72\n"
881  "FeatureComponents\tFeature_\tComponent_\n"
882  "feature\taugustus";
883 
884 static const char ci2_file_dat[] =
885  "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
886  "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
887  "File\tFile\n"
888  "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
889 
890 static const char cl_custom_action_dat[] =
891  "Action\tType\tSource\tTarget\tISComments\n"
892  "s72\ti2\tS64\tS0\tS255\n"
893  "CustomAction\tAction\n"
894  "TestCommandlineProp\t19\t\tTest1\t\n";
895 
896 static const char cl_install_exec_seq_dat[] =
897  "Action\tCondition\tSequence\n"
898  "s72\tS255\tI2\n"
899  "InstallExecuteSequence\tAction\n"
900  "LaunchConditions\t\t100\n"
901  "ValidateProductID\t\t700\n"
902  "CostInitialize\t\t800\n"
903  "FileCost\t\t900\n"
904  "CostFinalize\t\t1000\n"
905  "TestCommandlineProp\tP=\"one\"\t1100\n"
906  "InstallInitialize\t\t1500\n"
907  "ProcessComponents\t\t1600\n"
908  "InstallValidate\t\t1400\n"
909  "InstallFinalize\t\t5000\n";
910 
911 typedef struct _msi_table
912 {
913  const CHAR *filename;
914  const CHAR *data;
915  int size;
916 } msi_table;
917 
918 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
919 
920 static const msi_table tables[] =
921 {
923  ADD_TABLE(component),
925  ADD_TABLE(feature_comp),
926  ADD_TABLE(file),
927  ADD_TABLE(install_exec_seq),
928  ADD_TABLE(media),
930 };
931 
932 static const msi_table mcp_tables[] =
933 {
935  ADD_TABLE(mcp_component),
936  ADD_TABLE(mcp_feature),
937  ADD_TABLE(mcp_feature_comp),
938  ADD_TABLE(mcp_file),
939  ADD_TABLE(install_exec_seq),
940  ADD_TABLE(media),
942 };
943 
944 static const msi_table lus0_tables[] =
945 {
946  ADD_TABLE(lus_component),
948  ADD_TABLE(lus_feature),
949  ADD_TABLE(lus_feature_comp),
950  ADD_TABLE(lus_file),
951  ADD_TABLE(lus_install_exec_seq),
952  ADD_TABLE(lus0_media),
954 };
955 
956 static const msi_table lus1_tables[] =
957 {
958  ADD_TABLE(lus_component),
960  ADD_TABLE(lus_feature),
961  ADD_TABLE(lus_feature_comp),
962  ADD_TABLE(lus_file),
963  ADD_TABLE(lus_install_exec_seq),
964  ADD_TABLE(lus1_media),
966 };
967 
968 static const msi_table lus2_tables[] =
969 {
970  ADD_TABLE(lus_component),
972  ADD_TABLE(lus_feature),
973  ADD_TABLE(lus_feature_comp),
974  ADD_TABLE(lus_file),
975  ADD_TABLE(lus_install_exec_seq),
976  ADD_TABLE(lus2_media),
978 };
979 
980 static const msi_table spf_tables[] =
981 {
982  ADD_TABLE(lus_component),
984  ADD_TABLE(lus_feature),
985  ADD_TABLE(lus_feature_comp),
986  ADD_TABLE(lus_file),
987  ADD_TABLE(lus0_media),
989  ADD_TABLE(spf_custom_action),
990  ADD_TABLE(spf_install_exec_seq),
991  ADD_TABLE(spf_install_ui_seq)
992 };
993 
994 static const msi_table sd_tables[] =
995 {
997  ADD_TABLE(sd_component),
998  ADD_TABLE(sd_feature),
999  ADD_TABLE(sd_feature_comp),
1000  ADD_TABLE(sd_file),
1001  ADD_TABLE(sd_install_exec_seq),
1002  ADD_TABLE(sd_install_ui_seq),
1003  ADD_TABLE(sd_custom_action),
1004  ADD_TABLE(media),
1006 };
1007 
1008 static const msi_table ci_tables[] =
1009 {
1010  ADD_TABLE(ci_component),
1012  ADD_TABLE(lus_feature),
1013  ADD_TABLE(lus_feature_comp),
1014  ADD_TABLE(lus_file),
1015  ADD_TABLE(ci_install_exec_seq),
1016  ADD_TABLE(lus0_media),
1018  ADD_TABLE(ci_custom_action),
1019 };
1020 
1021 static const msi_table ci2_tables[] =
1022 {
1023  ADD_TABLE(ci2_component),
1025  ADD_TABLE(lus_feature),
1026  ADD_TABLE(ci2_feature_comp),
1027  ADD_TABLE(ci2_file),
1028  ADD_TABLE(install_exec_seq),
1029  ADD_TABLE(lus0_media),
1030  ADD_TABLE(ci2_property),
1031 };
1032 
1033 static const msi_table cl_tables[] =
1034 {
1035  ADD_TABLE(component),
1037  ADD_TABLE(feature),
1038  ADD_TABLE(feature_comp),
1039  ADD_TABLE(file),
1040  ADD_TABLE(cl_custom_action),
1041  ADD_TABLE(cl_install_exec_seq),
1042  ADD_TABLE(media),
1044 };
1045 
1046 static void write_file(const CHAR *filename, const char *data, int data_size)
1047 {
1048  DWORD size;
1049 
1052  WriteFile(hf, data, data_size, &size, NULL);
1053  CloseHandle(hf);
1054 }
1055 
1056 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
1057 {
1058  MSIHANDLE summary;
1059  UINT r;
1060 
1061  r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
1062  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1063 
1064  r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
1065  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1066 
1068  "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
1069  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1070 
1072  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1073 
1074  r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
1075  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1076 
1077  r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
1078  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1079 
1080  /* write the summary changes back to the stream */
1081  r = MsiSummaryInfoPersist(summary);
1082  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1083 
1084  MsiCloseHandle(summary);
1085 }
1086 
1087 #define create_database(name, tables, num_tables) \
1088  create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
1089 
1090 #define create_database_template(name, tables, num_tables, version, template) \
1091  create_database_wordcount(name, tables, num_tables, version, 0, template);
1092 
1094  int num_tables, INT version, INT wordcount,
1095  const char *template)
1096 {
1097  MSIHANDLE db;
1098  UINT r;
1099  WCHAR *nameW;
1100  int j, len;
1101 
1102  len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
1103  if (!(nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return;
1104  MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
1105 
1107  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1108 
1109  /* import the tables into the database */
1110  for (j = 0; j < num_tables; j++)
1111  {
1112  const msi_table *table = &tables[j];
1113 
1114  write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
1115 
1116  r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
1117  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1118 
1119  DeleteFileA(table->filename);
1120  }
1121 
1122  write_msi_summary_info(db, version, wordcount, template);
1123 
1124  r = MsiDatabaseCommit(db);
1125  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
1126 
1127  MsiCloseHandle(db);
1128  HeapFree( GetProcessHeap(), 0, nameW );
1129 }
1130 
1131 static UINT run_query(MSIHANDLE hdb, const char *query)
1132 {
1133  MSIHANDLE hview = 0;
1134  UINT r;
1135 
1136  r = MsiDatabaseOpenViewA(hdb, query, &hview);
1137  if (r != ERROR_SUCCESS)
1138  return r;
1139 
1140  r = MsiViewExecute(hview, 0);
1141  if (r == ERROR_SUCCESS)
1142  r = MsiViewClose(hview);
1143  MsiCloseHandle(hview);
1144  return r;
1145 }
1146 
1147 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
1148 {
1149  UINT res;
1151 
1152  /* build summary info */
1154  ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
1155 
1157  "Installation Database");
1158  ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1159 
1161  "Installation Database");
1162  ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1163 
1165  "Wine Hackers");
1166  ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1167 
1169  ";1033");
1170  ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1171 
1173  "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
1174  ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1175 
1177  ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1178 
1180  ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
1181 
1183  ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
1184 
1186  ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
1187 
1188  return res;
1189 }
1190 
1192 {
1193  MSIHANDLE hdb = 0;
1194  CHAR query[MAX_PATH];
1195  UINT res;
1196 
1198 
1199  /* create an empty database */
1201  ok( res == ERROR_SUCCESS , "Failed to create database\n" );
1202  if (res != ERROR_SUCCESS)
1203  return hdb;
1204 
1205  res = MsiDatabaseCommit(hdb);
1206  ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1207 
1208  set_summary_info(hdb, prodcode);
1209 
1210  res = run_query(hdb,
1211  "CREATE TABLE `Directory` ( "
1212  "`Directory` CHAR(255) NOT NULL, "
1213  "`Directory_Parent` CHAR(255), "
1214  "`DefaultDir` CHAR(255) NOT NULL "
1215  "PRIMARY KEY `Directory`)");
1216  ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1217 
1218  res = run_query(hdb,
1219  "CREATE TABLE `Property` ( "
1220  "`Property` CHAR(72) NOT NULL, "
1221  "`Value` CHAR(255) "
1222  "PRIMARY KEY `Property`)");
1223  ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
1224 
1225  sprintf(query, "INSERT INTO `Property` "
1226  "(`Property`, `Value`) "
1227  "VALUES( 'ProductCode', '%s' )", prodcode);
1228  res = run_query(hdb, query);
1229  ok(res == ERROR_SUCCESS , "Failed\n");
1230 
1231  res = MsiDatabaseCommit(hdb);
1232  ok(res == ERROR_SUCCESS, "Failed to commit database\n");
1233 
1234  return hdb;
1235 }
1236 
1237 static void test_usefeature(void)
1238 {
1239  INSTALLSTATE r;
1240 
1241  if (!pMsiUseFeatureExA)
1242  {
1243  win_skip("MsiUseFeatureExA not implemented\n");
1244  return;
1245  }
1246 
1248  ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1249 
1250  r = MsiQueryFeatureStateA("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
1251  ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1252 
1253  r = pMsiUseFeatureExA(NULL,NULL,0,0);
1254  ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1255 
1256  r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
1257  ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1258 
1259  r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1260  NULL, -2, 0 );
1261  ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1262 
1263  r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}",
1264  "WORDVIEWFiles", -2, 0 );
1265  ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1266 
1267  r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}",
1268  "WORDVIEWFiles", -2, 0 );
1269  ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1270 
1271  r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}",
1272  "WORDVIEWFiles", -2, 1 );
1273  ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
1274 }
1275 
1277 {
1278  if (pRegDeleteKeyExA)
1279  return pRegDeleteKeyExA( key, subkey, access, 0 );
1280  return RegDeleteKeyA( key, subkey );
1281 }
1282 
1283 static void test_null(void)
1284 {
1285  MSIHANDLE hpkg;
1286  UINT r;
1287  HKEY hkey;
1288  DWORD dwType, cbData;
1289  LPBYTE lpData = NULL;
1292 
1293  if (is_wow64)
1295 
1296  r = pMsiOpenPackageExW(NULL, 0, &hpkg);
1297  ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1298 
1300  ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
1301 
1303  ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
1304 
1306  ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1307 
1308  r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
1309  ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
1310 
1311  r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
1312  ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1313 
1314  r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
1315  ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
1316 
1317  /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
1318  * necessary registry values */
1319 
1320  /* empty product string */
1321  r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
1322  if (r == ERROR_ACCESS_DENIED)
1323  {
1324  skip("Not enough rights to perform tests\n");
1325  return;
1326  }
1327  ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1328 
1329  r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1330  ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
1331  if ( r == ERROR_SUCCESS )
1332  {
1333  lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
1334  if (!lpData)
1335  skip("Out of memory\n");
1336  else
1337  {
1338  r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
1339  ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1340  }
1341  }
1342 
1343  r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1344  if (r == ERROR_ACCESS_DENIED)
1345  {
1346  skip("Not enough rights to perform tests\n");
1347  HeapFree(GetProcessHeap(), 0, lpData);
1348  RegCloseKey(hkey);
1349  return;
1350  }
1351  ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1352 
1353  r = MsiGetProductInfoA("", "", NULL, NULL);
1354  ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
1355 
1356  if (lpData)
1357  {
1358  r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
1359  ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1360 
1361  HeapFree(GetProcessHeap(), 0, lpData);
1362  }
1363  else
1364  {
1365  r = RegDeleteValueA(hkey, NULL);
1366  ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
1367  }
1368 
1369  r = RegCloseKey(hkey);
1370  ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1371 
1372  /* empty attribute */
1373  r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1374  0, NULL, 0, access, NULL, &hkey, NULL);
1375  ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1376 
1377  r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
1378  ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1379 
1380  r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
1381  ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
1382 
1383  r = RegCloseKey(hkey);
1384  ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1385 
1386  r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
1388  ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
1389 }
1390 
1391 static void test_getcomponentpath(void)
1392 {
1393  INSTALLSTATE r;
1394  char buffer[0x100];
1395  DWORD sz;
1396 
1397  if(!pMsiGetComponentPathA)
1398  return;
1399 
1400  r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
1401  ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1402 
1403  r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
1404  ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1405 
1406  r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
1407  ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1408 
1409  sz = sizeof buffer;
1410  buffer[0]=0;
1411  r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
1412  ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1413 
1414  r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
1415  "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
1416  ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1417 
1418  r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1419  "{00000000-0000-0000-0000-00000000}", buffer, &sz );
1420  ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1421 
1422  r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1423  "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
1424  ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1425 
1426  r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
1427  "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
1428  ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1429 }
1430 
1432 {
1433  HANDLE file;
1434  DWORD written;
1435 
1437  ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
1438  WriteFile(file, data, strlen(data), &written, NULL);
1439 
1440  if (size)
1441  {
1443  SetEndOfFile(file);
1444  }
1445 
1446  CloseHandle(file);
1447 }
1448 
1449 static void create_test_files(void)
1450 {
1451  CreateDirectoryA("msitest", NULL);
1452  create_file("msitest\\one.txt", "msitest\\one.txt", 100);
1453  CreateDirectoryA("msitest\\first", NULL);
1454  create_file("msitest\\first\\two.txt", "msitest\\first\\two.txt", 100);
1455  CreateDirectoryA("msitest\\second", NULL);
1456  create_file("msitest\\second\\three.txt", "msitest\\second\\three.txt", 100);
1457 
1458  create_file("four.txt", "four.txt", 100);
1459  create_file("five.txt", "five.txt", 100);
1460  create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1461 
1462  create_file("msitest\\filename", "msitest\\filename", 100);
1463  create_file("msitest\\service.exe", "msitest\\service.exe", 100);
1464 
1465  DeleteFileA("four.txt");
1466  DeleteFileA("five.txt");
1467 }
1468 
1469 static void delete_test_files(void)
1470 {
1471  DeleteFileA("msitest.msi");
1472  DeleteFileA("msitest.cab");
1473  DeleteFileA("msitest\\second\\three.txt");
1474  DeleteFileA("msitest\\first\\two.txt");
1475  DeleteFileA("msitest\\one.txt");
1476  DeleteFileA("msitest\\service.exe");
1477  DeleteFileA("msitest\\filename");
1478  RemoveDirectoryA("msitest\\second");
1479  RemoveDirectoryA("msitest\\first");
1480  RemoveDirectoryA("msitest");
1481 }
1482 
1483 #define HASHSIZE sizeof(MSIFILEHASHINFO)
1484 
1485 static const struct
1486 {
1490 } hash_data[] =
1491 {
1492  { "", 0,
1493  { HASHSIZE,
1494  { 0, 0, 0, 0 },
1495  },
1496  },
1497 
1498  { "abc", 0,
1499  { HASHSIZE,
1500  { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
1501  },
1502  },
1503 
1504  { "C:\\Program Files\\msitest\\caesar\n", 0,
1505  { HASHSIZE,
1506  { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
1507  },
1508  },
1509 
1510  { "C:\\Program Files\\msitest\\caesar\n", 500,
1511  { HASHSIZE,
1512  { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
1513  },
1514  },
1515 };
1516 
1517 static void test_MsiGetFileHash(void)
1518 {
1519  const char name[] = "msitest.bin";
1520  UINT r;
1522  DWORD i;
1523 
1524  if (!pMsiGetFileHashA)
1525  {
1526  win_skip("MsiGetFileHash not implemented\n");
1527  return;
1528  }
1529 
1530  hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1531 
1532  /* szFilePath is NULL */
1533  r = pMsiGetFileHashA(NULL, 0, &hash);
1534  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1535 
1536  /* szFilePath is empty */
1537  r = pMsiGetFileHashA("", 0, &hash);
1539  "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
1540 
1541  /* szFilePath is nonexistent */
1542  r = pMsiGetFileHashA(name, 0, &hash);
1543  ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
1544 
1545  /* dwOptions is non-zero */
1546  r = pMsiGetFileHashA(name, 1, &hash);
1547  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1548 
1549  /* pHash.dwFileHashInfoSize is not correct */
1550  hash.dwFileHashInfoSize = 0;
1551  r = pMsiGetFileHashA(name, 0, &hash);
1552  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1553 
1554  /* pHash is NULL */
1555  r = pMsiGetFileHashA(name, 0, NULL);
1556  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1557 
1558  for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
1559  {
1560  int ret;
1561 
1563 
1564  memset(&hash, 0, sizeof(MSIFILEHASHINFO));
1565  hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1566 
1567  r = pMsiGetFileHashA(name, 0, &hash);
1568  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1569 
1571  ok(!ret, "Hash incorrect\n");
1572 
1573  DeleteFileA(name);
1574  }
1575 }
1576 
1577 /* copied from dlls/msi/registry.c */
1579 {
1580  DWORD i,n=1;
1581  GUID guid;
1582 
1583  if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
1584  return FALSE;
1585 
1586  for(i=0; i<8; i++)
1587  out[7-i] = in[n++];
1588  n++;
1589  for(i=0; i<4; i++)
1590  out[11-i] = in[n++];
1591  n++;
1592  for(i=0; i<4; i++)
1593  out[15-i] = in[n++];
1594  n++;
1595  for(i=0; i<2; i++)
1596  {
1597  out[17+i*2] = in[n++];
1598  out[16+i*2] = in[n++];
1599  }
1600  n++;
1601  for( ; i<8; i++)
1602  {
1603  out[17+i*2] = in[n++];
1604  out[16+i*2] = in[n++];
1605  }
1606  out[32]=0;
1607  return TRUE;
1608 }
1609 
1610 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
1611 {
1612  WCHAR guidW[MAX_PATH];
1613  WCHAR squashedW[MAX_PATH];
1614  GUID guid;
1615  HRESULT hr;
1616  int size;
1617 
1618  hr = CoCreateGuid(&guid);
1619  ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1620 
1621  size = StringFromGUID2(&guid, guidW, MAX_PATH);
1622  ok(size == 39, "Expected 39, got %d\n", hr);
1623 
1624  WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
1625  if (squashed)
1626  {
1627  squash_guid(guidW, squashedW);
1628  WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1629  }
1630 }
1631 
1632 static char *get_user_sid(void)
1633 {
1634  HANDLE token;
1635  DWORD size = 0;
1636  TOKEN_USER *user;
1637  char *usersid = NULL;
1638 
1641 
1642  user = HeapAlloc(GetProcessHeap(), 0, size);
1644  pConvertSidToStringSidA(user->User.Sid, &usersid);
1645  HeapFree(GetProcessHeap(), 0, user);
1646 
1647  CloseHandle(token);
1648  return usersid;
1649 }
1650 
1651 static void test_MsiQueryProductState(void)
1652 {
1653  CHAR prodcode[MAX_PATH];
1654  CHAR prod_squashed[MAX_PATH];
1655  CHAR keypath[MAX_PATH*2];
1656  LPSTR usersid;
1658  LONG res;
1659  HKEY userkey, localkey, props;
1660  HKEY prodkey;
1661  DWORD data, error;
1663 
1664  create_test_guid(prodcode, prod_squashed);
1665  usersid = get_user_sid();
1666 
1667  if (is_wow64)
1669 
1670  /* NULL prodcode */
1671  SetLastError(0xdeadbeef);
1673  error = GetLastError();
1674  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1675  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1676 
1677  /* empty prodcode */
1678  SetLastError(0xdeadbeef);
1680  error = GetLastError();
1681  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1682  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1683 
1684  /* garbage prodcode */
1685  SetLastError(0xdeadbeef);
1686  state = MsiQueryProductStateA("garbage");
1687  error = GetLastError();
1688  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1689  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1690 
1691  /* guid without brackets */
1692  SetLastError(0xdeadbeef);
1693  state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
1694  error = GetLastError();
1695  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1696  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1697 
1698  /* guid with brackets */
1699  SetLastError(0xdeadbeef);
1700  state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
1701  error = GetLastError();
1702  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1703  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1704  "expected ERROR_SUCCESS, got %u\n", error);
1705 
1706  /* same length as guid, but random */
1707  SetLastError(0xdeadbeef);
1708  state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
1709  error = GetLastError();
1710  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1711  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
1712 
1713  /* MSIINSTALLCONTEXT_USERUNMANAGED */
1714 
1715  SetLastError(0xdeadbeef);
1716  state = MsiQueryProductStateA(prodcode);
1717  error = GetLastError();
1718  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1719  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1720  "expected ERROR_SUCCESS, got %u\n", error);
1721 
1722  lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1723  lstrcatA(keypath, prod_squashed);
1724 
1725  res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
1726  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1727 
1728  /* user product key exists */
1729  SetLastError(0xdeadbeef);
1730  state = MsiQueryProductStateA(prodcode);
1731  error = GetLastError();
1732  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1733  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1734  "expected ERROR_SUCCESS, got %u\n", error);
1735 
1736  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
1737  lstrcatA(keypath, prodcode);
1738 
1739  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1740  if (res == ERROR_ACCESS_DENIED)
1741  {
1742  skip("Not enough rights to perform tests\n");
1743  RegDeleteKeyA(userkey, "");
1744  RegCloseKey(userkey);
1745  LocalFree(usersid);
1746  return;
1747  }
1748  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1749 
1750  /* local uninstall key exists */
1751  SetLastError(0xdeadbeef);
1752  state = MsiQueryProductStateA(prodcode);
1753  error = GetLastError();
1754  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1755  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1756  "expected ERROR_SUCCESS, got %u\n", error);
1757 
1758  data = 1;
1759  res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1760  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1761 
1762  /* WindowsInstaller value exists */
1763  SetLastError(0xdeadbeef);
1764  state = MsiQueryProductStateA(prodcode);
1765  error = GetLastError();
1766  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1767  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1768  "expected ERROR_SUCCESS, got %u\n", error);
1769 
1770  RegDeleteValueA(localkey, "WindowsInstaller");
1771  delete_key(localkey, "", access & KEY_WOW64_64KEY);
1772 
1773  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1774  lstrcatA(keypath, usersid);
1775  lstrcatA(keypath, "\\Products\\");
1776  lstrcatA(keypath, prod_squashed);
1777 
1778  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1779  if (res == ERROR_ACCESS_DENIED)
1780  {
1781  skip("Not enough rights to perform tests\n");
1782  RegDeleteKeyA(userkey, "");
1783  RegCloseKey(userkey);
1784  LocalFree(usersid);
1785  return;
1786  }
1787  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1788 
1789  /* local product key exists */
1790  SetLastError(0xdeadbeef);
1791  state = MsiQueryProductStateA(prodcode);
1792  error = GetLastError();
1793  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1794  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1795  "expected ERROR_SUCCESS, got %u\n", error);
1796 
1797  res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1798  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1799 
1800  /* install properties key exists */
1801  SetLastError(0xdeadbeef);
1802  state = MsiQueryProductStateA(prodcode);
1803  error = GetLastError();
1804  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1805  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1806  "expected ERROR_SUCCESS, got %u\n", error);
1807 
1808  data = 1;
1809  res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1810  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1811 
1812  /* WindowsInstaller value exists */
1813  SetLastError(0xdeadbeef);
1814  state = MsiQueryProductStateA(prodcode);
1815  error = GetLastError();
1816  ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1817  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1818  "expected ERROR_SUCCESS, got %u\n", error);
1819 
1820  data = 2;
1821  res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1822  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1823 
1824  /* WindowsInstaller value is not 1 */
1825  SetLastError(0xdeadbeef);
1826  state = MsiQueryProductStateA(prodcode);
1827  error = GetLastError();
1828  ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1829  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1830  "expected ERROR_SUCCESS, got %u\n", error);
1831 
1832  RegDeleteKeyA(userkey, "");
1833 
1834  /* user product key does not exist */
1835  SetLastError(0xdeadbeef);
1836  state = MsiQueryProductStateA(prodcode);
1837  error = GetLastError();
1838  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1839  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
1840  "expected ERROR_SUCCESS, got %u\n", error);
1841 
1842  RegDeleteValueA(props, "WindowsInstaller");
1844  RegCloseKey(props);
1845  delete_key(localkey, "", access & KEY_WOW64_64KEY);
1846  RegCloseKey(localkey);
1847  RegDeleteKeyA(userkey, "");
1848  RegCloseKey(userkey);
1849 
1850  /* MSIINSTALLCONTEXT_USERMANAGED */
1851 
1852  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1853  lstrcatA(keypath, usersid);
1854  lstrcatA(keypath, "\\Installer\\Products\\");
1855  lstrcatA(keypath, prod_squashed);
1856 
1857  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1858  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1859 
1860  state = MsiQueryProductStateA(prodcode);
1862  "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1863 
1864  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1865  lstrcatA(keypath, usersid);
1866  lstrcatA(keypath, "\\Products\\");
1867  lstrcatA(keypath, prod_squashed);
1868 
1869  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1870  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1871 
1872  state = MsiQueryProductStateA(prodcode);
1874  "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1875 
1876  res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1877  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1878 
1879  state = MsiQueryProductStateA(prodcode);
1881  "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1882 
1883  data = 1;
1884  res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1885  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1886 
1887  /* WindowsInstaller value exists */
1888  state = MsiQueryProductStateA(prodcode);
1889  ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1890 
1891  RegDeleteValueA(props, "WindowsInstaller");
1893  RegCloseKey(props);
1894  delete_key(localkey, "", access & KEY_WOW64_64KEY);
1895  RegCloseKey(localkey);
1896  delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1897  RegCloseKey(prodkey);
1898 
1899  /* MSIINSTALLCONTEXT_MACHINE */
1900 
1901  lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1902  lstrcatA(keypath, prod_squashed);
1903 
1904  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1905  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1906 
1907  state = MsiQueryProductStateA(prodcode);
1908  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1909 
1910  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1911  lstrcatA(keypath, "S-1-5-18\\Products\\");
1912  lstrcatA(keypath, prod_squashed);
1913 
1914  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1915  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1916 
1917  state = MsiQueryProductStateA(prodcode);
1919  "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1920 
1921  res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
1922  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1923 
1924  state = MsiQueryProductStateA(prodcode);
1926  "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1927 
1928  data = 1;
1929  res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
1930  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1931 
1932  /* WindowsInstaller value exists */
1933  state = MsiQueryProductStateA(prodcode);
1934  ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
1935 
1936  RegDeleteValueA(props, "WindowsInstaller");
1938  RegCloseKey(props);
1939  delete_key(localkey, "", access & KEY_WOW64_64KEY);
1940  RegCloseKey(localkey);
1941  delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1942  RegCloseKey(prodkey);
1943 
1944  LocalFree(usersid);
1945 }
1946 
1947 static const char table_enc85[] =
1948 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
1949 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
1950 "yz{}~";
1951 
1952 /*
1953  * Encodes a base85 guid given a GUID pointer
1954  * Caller should provide a 21 character buffer for the encoded string.
1955  */
1957 {
1958  unsigned int x, *p, i;
1959 
1960  p = (unsigned int*) guid;
1961  for( i=0; i<4; i++ )
1962  {
1963  x = p[i];
1964  *str++ = table_enc85[x%85];
1965  x = x/85;
1966  *str++ = table_enc85[x%85];
1967  x = x/85;
1968  *str++ = table_enc85[x%85];
1969  x = x/85;
1970  *str++ = table_enc85[x%85];
1971  x = x/85;
1972  *str++ = table_enc85[x%85];
1973  }
1974  *str = 0;
1975 }
1976 
1977 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
1978 {
1979  WCHAR guidW[MAX_PATH];
1980  WCHAR base85W[MAX_PATH];
1981  WCHAR squashedW[MAX_PATH];
1982  GUID guid;
1983  HRESULT hr;
1984  int size;
1985 
1986  hr = CoCreateGuid(&guid);
1987  ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
1988 
1989  size = StringFromGUID2(&guid, guidW, MAX_PATH);
1990  ok(size == 39, "Expected 39, got %d\n", hr);
1991 
1992  WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1993  encode_base85_guid(&guid, base85W);
1994  WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1995  squash_guid(guidW, squashedW);
1996  WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1997 }
1998 
1999 static void test_MsiQueryFeatureState(void)
2000 {
2001  HKEY userkey, localkey, compkey, compkey2;
2002  CHAR prodcode[MAX_PATH];
2003  CHAR prod_squashed[MAX_PATH];
2004  CHAR component[MAX_PATH];
2005  CHAR comp_base85[MAX_PATH];
2006  CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
2007  CHAR keypath[MAX_PATH*2];
2009  LPSTR usersid;
2010  LONG res;
2012  DWORD error;
2013 
2014  create_test_guid(prodcode, prod_squashed);
2015  compose_base85_guid(component, comp_base85, comp_squashed);
2016  compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
2017  usersid = get_user_sid();
2018 
2019  if (is_wow64)
2021 
2022  /* NULL prodcode */
2023  SetLastError(0xdeadbeef);
2024  state = MsiQueryFeatureStateA(NULL, "feature");
2025  error = GetLastError();
2026  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2027  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2028 
2029  /* empty prodcode */
2030  SetLastError(0xdeadbeef);
2031  state = MsiQueryFeatureStateA("", "feature");
2032  error = GetLastError();
2033  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2034  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2035 
2036  /* garbage prodcode */
2037  SetLastError(0xdeadbeef);
2038  state = MsiQueryFeatureStateA("garbage", "feature");
2039  error = GetLastError();
2040  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2041  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2042 
2043  /* guid without brackets */
2044  SetLastError(0xdeadbeef);
2045  state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
2046  error = GetLastError();
2047  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2048  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2049 
2050  /* guid with brackets */
2051  SetLastError(0xdeadbeef);
2052  state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
2053  error = GetLastError();
2054  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2055  ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
2056  "expected ERROR_SUCCESS, got %u\n", error);
2057 
2058  /* same length as guid, but random */
2059  SetLastError(0xdeadbeef);
2060  state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
2061  error = GetLastError();
2062  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2063  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2064 
2065  /* NULL szFeature */
2066  SetLastError(0xdeadbeef);
2067  state = MsiQueryFeatureStateA(prodcode, NULL);
2068  error = GetLastError();
2069  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2070  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2071 
2072  /* empty szFeature */
2073  SetLastError(0xdeadbeef);
2074  state = MsiQueryFeatureStateA(prodcode, "");
2075  error = GetLastError();
2076  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2077  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2078  "expected ERROR_SUCCESS, got %u\n", error);
2079 
2080  /* feature key does not exist yet */
2081  SetLastError(0xdeadbeef);
2082  state = MsiQueryFeatureStateA(prodcode, "feature");
2083  error = GetLastError();
2084  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2085  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2086  "expected ERROR_SUCCESS, got %u\n", error);
2087 
2088  /* MSIINSTALLCONTEXT_USERUNMANAGED */
2089 
2090  lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
2091  lstrcatA(keypath, prod_squashed);
2092 
2093  res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
2094  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2095 
2096  /* feature key exists */
2097  SetLastError(0xdeadbeef);
2098  state = MsiQueryFeatureStateA(prodcode, "feature");
2099  error = GetLastError();
2100  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2101  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2102  "expected ERROR_SUCCESS, got %u\n", error);
2103 
2104  res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
2105  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2106 
2107  /* feature value exists */
2108  SetLastError(0xdeadbeef);
2109  state = MsiQueryFeatureStateA(prodcode, "feature");
2110  error = GetLastError();
2111  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2112  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2113  "expected ERROR_SUCCESS, got %u\n", error);
2114 
2115  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2116  lstrcatA(keypath, usersid);
2117  lstrcatA(keypath, "\\Products\\");
2118  lstrcatA(keypath, prod_squashed);
2119  lstrcatA(keypath, "\\Features");
2120 
2121  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2122  if (res == ERROR_ACCESS_DENIED)
2123  {
2124  skip("Not enough rights to perform tests\n");
2125  RegDeleteKeyA(userkey, "");
2126  RegCloseKey(userkey);
2127  LocalFree(usersid);
2128  return;
2129  }
2130  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2131 
2132  /* userdata features key exists */
2133  SetLastError(0xdeadbeef);
2134  state = MsiQueryFeatureStateA(prodcode, "feature");
2135  error = GetLastError();
2136  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2137  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2138  "expected ERROR_SUCCESS, got %u\n", error);
2139 
2140  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2141  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2142 
2143  SetLastError(0xdeadbeef);
2144  state = MsiQueryFeatureStateA(prodcode, "feature");
2145  error = GetLastError();
2146  ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2147  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2148  "expected ERROR_SUCCESS, got %u\n", error);
2149 
2150  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2151  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2152 
2153  SetLastError(0xdeadbeef);
2154  state = MsiQueryFeatureStateA(prodcode, "feature");
2155  error = GetLastError();
2156  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2157  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2158  "expected ERROR_SUCCESS, got %u\n", error);
2159 
2160  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2161  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2162 
2163  SetLastError(0xdeadbeef);
2164  state = MsiQueryFeatureStateA(prodcode, "feature");
2165  error = GetLastError();
2166  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2167  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2168  "expected ERROR_SUCCESS, got %u\n", error);
2169 
2170  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2171  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2172 
2173  SetLastError(0xdeadbeef);
2174  state = MsiQueryFeatureStateA(prodcode, "feature");
2175  error = GetLastError();
2176  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2177  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2178  "expected ERROR_SUCCESS, got %u\n", error);
2179 
2180  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2181  lstrcatA(keypath, usersid);
2182  lstrcatA(keypath, "\\Components\\");
2183  lstrcatA(keypath, comp_squashed);
2184 
2185  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2186  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2187 
2188  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2189  lstrcatA(keypath, usersid);
2190  lstrcatA(keypath, "\\Components\\");
2191  lstrcatA(keypath, comp_squashed2);
2192 
2193  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2194  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2195 
2196  SetLastError(0xdeadbeef);
2197  state = MsiQueryFeatureStateA(prodcode, "feature");
2198  error = GetLastError();
2199  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2200  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2201  "expected ERROR_SUCCESS, got %u\n", error);
2202 
2203  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2204  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2205 
2206  SetLastError(0xdeadbeef);
2207  state = MsiQueryFeatureStateA(prodcode, "feature");
2208  error = GetLastError();
2209  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2210  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2211  "expected ERROR_SUCCESS, got %u\n", error);
2212 
2213  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2214  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2215 
2216  SetLastError(0xdeadbeef);
2217  state = MsiQueryFeatureStateA(prodcode, "feature");
2218  error = GetLastError();
2219  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2220  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2221  "expected ERROR_SUCCESS, got %u\n", error);
2222 
2223  res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2224  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2225 
2226  /* INSTALLSTATE_LOCAL */
2227  SetLastError(0xdeadbeef);
2228  state = MsiQueryFeatureStateA(prodcode, "feature");
2229  error = GetLastError();
2230  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2231  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2232  "expected ERROR_SUCCESS, got %u\n", error);
2233 
2234  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2235  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2236 
2237  /* INSTALLSTATE_SOURCE */
2238  SetLastError(0xdeadbeef);
2239  state = MsiQueryFeatureStateA(prodcode, "feature");
2240  error = GetLastError();
2241  ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2242  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2243  "expected ERROR_SUCCESS, got %u\n", error);
2244 
2245  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2246  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2247 
2248  /* bad INSTALLSTATE_SOURCE */
2249  SetLastError(0xdeadbeef);
2250  state = MsiQueryFeatureStateA(prodcode, "feature");
2251  error = GetLastError();
2252  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2253  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2254  "expected ERROR_SUCCESS, got %u\n", error);
2255 
2256  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2257  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2258 
2259  /* INSTALLSTATE_SOURCE */
2260  SetLastError(0xdeadbeef);
2261  state = MsiQueryFeatureStateA(prodcode, "feature");
2262  error = GetLastError();
2263  ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2264  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2265  "expected ERROR_SUCCESS, got %u\n", error);
2266 
2267  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2268  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2269 
2270  /* bad INSTALLSTATE_SOURCE */
2271  SetLastError(0xdeadbeef);
2272  state = MsiQueryFeatureStateA(prodcode, "feature");
2273  error = GetLastError();
2274  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2275  ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
2276  "expected ERROR_SUCCESS, got %u\n", error);
2277 
2278  RegDeleteValueA(compkey, prod_squashed);
2279  RegDeleteValueA(compkey2, prod_squashed);
2280  delete_key(compkey, "", access & KEY_WOW64_64KEY);
2281  delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2282  RegDeleteValueA(localkey, "feature");
2283  RegDeleteValueA(userkey, "feature");
2284  RegDeleteKeyA(userkey, "");
2285  RegCloseKey(compkey);
2286  RegCloseKey(compkey2);
2287  RegCloseKey(localkey);
2288  RegCloseKey(userkey);
2289 
2290  /* MSIINSTALLCONTEXT_USERMANAGED */
2291 
2292  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2293  lstrcatA(keypath, usersid);
2294  lstrcatA(keypath, "\\Installer\\Features\\");
2295  lstrcatA(keypath, prod_squashed);
2296 
2297  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2298  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2299 
2300  /* feature key exists */
2301  state = MsiQueryFeatureStateA(prodcode, "feature");
2302  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2303 
2304  res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2305  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2306 
2307  /* feature value exists */
2308  state = MsiQueryFeatureStateA(prodcode, "feature");
2309  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2310 
2311  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2312  lstrcatA(keypath, usersid);
2313  lstrcatA(keypath, "\\Products\\");
2314  lstrcatA(keypath, prod_squashed);
2315  lstrcatA(keypath, "\\Features");
2316 
2317  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2318  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2319 
2320  /* userdata features key exists */
2321  state = MsiQueryFeatureStateA(prodcode, "feature");
2322  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2323 
2324  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2325  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2326 
2327  state = MsiQueryFeatureStateA(prodcode, "feature");
2328  ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2329 
2330  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2331  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2332 
2333  state = MsiQueryFeatureStateA(prodcode, "feature");
2334  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2335 
2336  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2337  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2338 
2339  state = MsiQueryFeatureStateA(prodcode, "feature");
2340  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2341 
2342  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2343  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2344 
2345  state = MsiQueryFeatureStateA(prodcode, "feature");
2346  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2347 
2348  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2349  lstrcatA(keypath, usersid);
2350  lstrcatA(keypath, "\\Components\\");
2351  lstrcatA(keypath, comp_squashed);
2352 
2353  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2354  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2355 
2356  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2357  lstrcatA(keypath, usersid);
2358  lstrcatA(keypath, "\\Components\\");
2359  lstrcatA(keypath, comp_squashed2);
2360 
2361  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2362  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2363 
2364  state = MsiQueryFeatureStateA(prodcode, "feature");
2365  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2366 
2367  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2368  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2369 
2370  state = MsiQueryFeatureStateA(prodcode, "feature");
2371  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2372 
2373  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2374  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2375 
2376  state = MsiQueryFeatureStateA(prodcode, "feature");
2377  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2378 
2379  res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2380  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2381 
2382  state = MsiQueryFeatureStateA(prodcode, "feature");
2383  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2384 
2385  RegDeleteValueA(compkey, prod_squashed);
2386  RegDeleteValueA(compkey2, prod_squashed);
2387  delete_key(compkey, "", access & KEY_WOW64_64KEY);
2388  delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2389  RegDeleteValueA(localkey, "feature");
2390  RegDeleteValueA(userkey, "feature");
2391  delete_key(userkey, "", access & KEY_WOW64_64KEY);
2392  RegCloseKey(compkey);
2393  RegCloseKey(compkey2);
2394  RegCloseKey(localkey);
2395  RegCloseKey(userkey);
2396 
2397  /* MSIINSTALLCONTEXT_MACHINE */
2398 
2399  lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
2400  lstrcatA(keypath, prod_squashed);
2401 
2402  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
2403  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2404 
2405  /* feature key exists */
2406  state = MsiQueryFeatureStateA(prodcode, "feature");
2407  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2408 
2409  res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
2410  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2411 
2412  /* feature value exists */
2413  state = MsiQueryFeatureStateA(prodcode, "feature");
2414  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2415 
2416  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2417  lstrcatA(keypath, "S-1-5-18\\Products\\");
2418  lstrcatA(keypath, prod_squashed);
2419  lstrcatA(keypath, "\\Features");
2420 
2421  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2422  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2423 
2424  /* userdata features key exists */
2425  state = MsiQueryFeatureStateA(prodcode, "feature");
2426  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2427 
2428  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
2429  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2430 
2431  state = MsiQueryFeatureStateA(prodcode, "feature");
2432  ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
2433 
2434  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
2435  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2436 
2437  state = MsiQueryFeatureStateA(prodcode, "feature");
2438  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2439 
2440  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
2441  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2442 
2443  state = MsiQueryFeatureStateA(prodcode, "feature");
2444  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2445 
2446  res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
2447  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2448 
2449  state = MsiQueryFeatureStateA(prodcode, "feature");
2450  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2451 
2452  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2453  lstrcatA(keypath, "S-1-5-18\\Components\\");
2454  lstrcatA(keypath, comp_squashed);
2455 
2456  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2457  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2458 
2459  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2460  lstrcatA(keypath, "S-1-5-18\\Components\\");
2461  lstrcatA(keypath, comp_squashed2);
2462 
2463  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
2464  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2465 
2466  state = MsiQueryFeatureStateA(prodcode, "feature");
2467  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2468 
2469  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
2470  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2471 
2472  state = MsiQueryFeatureStateA(prodcode, "feature");
2473  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2474 
2475  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
2476  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2477 
2478  state = MsiQueryFeatureStateA(prodcode, "feature");
2479  ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
2480 
2481  res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
2482  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2483 
2484  state = MsiQueryFeatureStateA(prodcode, "feature");
2485  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2486 
2487  RegDeleteValueA(compkey, prod_squashed);
2488  RegDeleteValueA(compkey2, prod_squashed);
2489  delete_key(compkey, "", access & KEY_WOW64_64KEY);
2490  delete_key(compkey2, "", access & KEY_WOW64_64KEY);
2491  RegDeleteValueA(localkey, "feature");
2492  RegDeleteValueA(userkey, "feature");
2493  delete_key(userkey, "", access & KEY_WOW64_64KEY);
2494  RegCloseKey(compkey);
2495  RegCloseKey(compkey2);
2496  RegCloseKey(localkey);
2497  RegCloseKey(userkey);
2498  LocalFree(usersid);
2499 }
2500 
2502 {
2503  HKEY compkey, prodkey;
2504  CHAR prodcode[MAX_PATH];
2505  CHAR prod_squashed[MAX_PATH];
2506  CHAR component[MAX_PATH];
2507  CHAR comp_base85[MAX_PATH];
2508  CHAR comp_squashed[MAX_PATH];
2509  CHAR keypath[MAX_PATH];
2511  LPSTR usersid;
2512  LONG res;
2513  UINT r;
2515  DWORD error;
2516 
2517  static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
2518 
2519  if (!pMsiQueryComponentStateA)
2520  {
2521  win_skip("MsiQueryComponentStateA not implemented\n");
2522  return;
2523  }
2524 
2525  create_test_guid(prodcode, prod_squashed);
2526  compose_base85_guid(component, comp_base85, comp_squashed);
2527  usersid = get_user_sid();
2528 
2529  if (is_wow64)
2531 
2532  /* NULL szProductCode */
2533  state = MAGIC_ERROR;
2534  SetLastError(0xdeadbeef);
2535  r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2536  error = GetLastError();
2537  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2538  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2539  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2540 
2541  /* empty szProductCode */
2542  state = MAGIC_ERROR;
2543  SetLastError(0xdeadbeef);
2544  r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2545  error = GetLastError();
2546  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2547  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2548  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2549 
2550  /* random szProductCode */
2551  state = MAGIC_ERROR;
2552  SetLastError(0xdeadbeef);
2553  r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2554  error = GetLastError();
2555  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2556  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2557  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2558 
2559  /* GUID-length szProductCode */
2560  state = MAGIC_ERROR;
2561  SetLastError(0xdeadbeef);
2562  r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2563  error = GetLastError();
2564  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2565  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2566  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2567 
2568  /* GUID-length with brackets */
2569  state = MAGIC_ERROR;
2570  SetLastError(0xdeadbeef);
2571  r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2572  error = GetLastError();
2573  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2574  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2575  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2576 
2577  /* actual GUID */
2578  state = MAGIC_ERROR;
2579  SetLastError(0xdeadbeef);
2580  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2581  error = GetLastError();
2582  ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2583  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2584  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2585 
2586  state = MAGIC_ERROR;
2587  SetLastError(0xdeadbeef);
2588  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2589  error = GetLastError();
2590  ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2591  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2592  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2593 
2594  lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2595  lstrcatA(keypath, prod_squashed);
2596 
2597  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2598  if (res == ERROR_ACCESS_DENIED)
2599  {
2600  skip("Not enough rights to perform tests\n");
2601  LocalFree(usersid);
2602  return;
2603  }
2604  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2605 
2606  state = MAGIC_ERROR;
2607  SetLastError(0xdeadbeef);
2608  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2609  error = GetLastError();
2610  ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2611  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2612  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2613 
2614  delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2615  RegCloseKey(prodkey);
2616 
2617  /* create local system product key */
2618  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
2619  lstrcatA(keypath, prod_squashed);
2620  lstrcatA(keypath, "\\InstallProperties");
2621 
2622  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2623  if (res == ERROR_ACCESS_DENIED)
2624  {
2625  skip("Not enough rights to perform tests\n");
2626  LocalFree(usersid);
2627  return;
2628  }
2629  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2630 
2631  /* local system product key exists */
2632  state = MAGIC_ERROR;
2633  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2634  error = GetLastError();
2635  ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2636  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2637  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2638 
2639  res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2640  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2641 
2642  /* LocalPackage value exists */
2643  state = MAGIC_ERROR;
2644  SetLastError(0xdeadbeef);
2645  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2646  error = GetLastError();
2647  ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2648  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2649  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2650 
2651  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
2652  lstrcatA(keypath, comp_squashed);
2653 
2654  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2655  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2656 
2657  /* component key exists */
2658  state = MAGIC_ERROR;
2659  SetLastError(0xdeadbeef);
2660  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2661  error = GetLastError();
2662  ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2663  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2664  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2665 
2666  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2667  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2668 
2669  /* component\product exists */
2670  state = MAGIC_ERROR;
2671  SetLastError(0xdeadbeef);
2672  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2673  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2674  error = GetLastError();
2676  "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2677  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2678 
2679  /* NULL component, product exists */
2680  state = MAGIC_ERROR;
2681  SetLastError(0xdeadbeef);
2682  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
2683  error = GetLastError();
2684  ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2685  ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
2686  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2687 
2688  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2689  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2690 
2691  /* INSTALLSTATE_LOCAL */
2692  state = MAGIC_ERROR;
2693  SetLastError(0xdeadbeef);
2694  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2695  error = GetLastError();
2696  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2697  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2698  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2699 
2700  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
2701  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2702 
2703  /* INSTALLSTATE_SOURCE */
2704  state = MAGIC_ERROR;
2705  SetLastError(0xdeadbeef);
2706  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2707  error = GetLastError();
2708  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2709  ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2710  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2711 
2712  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
2713  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2714 
2715  /* bad INSTALLSTATE_SOURCE */
2716  state = MAGIC_ERROR;
2717  SetLastError(0xdeadbeef);
2718  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2719  error = GetLastError();
2720  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2721  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2722  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2723 
2724  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
2725  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2726 
2727  /* INSTALLSTATE_SOURCE */
2728  state = MAGIC_ERROR;
2729  SetLastError(0xdeadbeef);
2730  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2731  error = GetLastError();
2732  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2733  ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
2734  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2735 
2736  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
2737  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2738 
2739  /* registry component */
2740  state = MAGIC_ERROR;
2741  SetLastError(0xdeadbeef);
2742  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
2743  error = GetLastError();
2744  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2745  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2746  ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
2747 
2748  RegDeleteValueA(prodkey, "LocalPackage");
2749  delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2750  RegDeleteValueA(compkey, prod_squashed);
2751  delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2752  RegCloseKey(prodkey);
2753  RegCloseKey(compkey);
2754 
2755  /* MSIINSTALLCONTEXT_USERUNMANAGED */
2756 
2757  state = MAGIC_ERROR;
2758  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2759  ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2760  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2761 
2762  lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2763  lstrcatA(keypath, prod_squashed);
2764 
2765  res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2766  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2767 
2768  state = MAGIC_ERROR;
2769  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2770  ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2771  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2772 
2773  RegDeleteKeyA(prodkey, "");
2774  RegCloseKey(prodkey);
2775 
2776  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2777  lstrcatA(keypath, usersid);
2778  lstrcatA(keypath, "\\Products\\");
2779  lstrcatA(keypath, prod_squashed);
2780  lstrcatA(keypath, "\\InstallProperties");
2781 
2782  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2783  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2784 
2785  res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2786  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2787 
2788  RegCloseKey(prodkey);
2789 
2790  state = MAGIC_ERROR;
2791  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2792  ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2793  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2794 
2795  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2796  lstrcatA(keypath, usersid);
2797  lstrcatA(keypath, "\\Components\\");
2798  lstrcatA(keypath, comp_squashed);
2799 
2800  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2801  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2802 
2803  /* component key exists */
2804  state = MAGIC_ERROR;
2805  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2806  ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2807  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2808 
2809  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
2810  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2811 
2812  /* component\product exists */
2813  state = MAGIC_ERROR;
2814  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2815  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2817  "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
2818 
2819  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
2820  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2821 
2822  state = MAGIC_ERROR;
2823  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
2824  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2825  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2826 
2827  /* MSIINSTALLCONTEXT_USERMANAGED */
2828 
2829  state = MAGIC_ERROR;
2830  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2831  ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2832  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2833 
2834  lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2835  lstrcatA(keypath, prod_squashed);
2836 
2837  res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2838  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2839 
2840  state = MAGIC_ERROR;
2841  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2842  ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2843  ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
2844 
2845  RegDeleteKeyA(prodkey, "");
2846  RegCloseKey(prodkey);
2847 
2848  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2849  lstrcatA(keypath, usersid);
2850  lstrcatA(keypath, "\\Installer\\Products\\");
2851  lstrcatA(keypath, prod_squashed);
2852 
2853  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2854  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2855 
2856  state = MAGIC_ERROR;
2857  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2858  ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2859  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2860 
2861  delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2862  RegCloseKey(prodkey);
2863 
2864  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2865  lstrcatA(keypath, usersid);
2866  lstrcatA(keypath, "\\Products\\");
2867  lstrcatA(keypath, prod_squashed);
2868  lstrcatA(keypath, "\\InstallProperties");
2869 
2870  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2871  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2872 
2873  res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
2874  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2875 
2876  state = MAGIC_ERROR;
2877  r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
2878  ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2879  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2880 
2881  RegDeleteValueA(prodkey, "LocalPackage");
2882  RegDeleteValueA(prodkey, "ManagedLocalPackage");
2883  delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2884  RegDeleteValueA(compkey, prod_squashed);
2885  delete_key(compkey, "", access & KEY_WOW64_64KEY);
2886  RegCloseKey(prodkey);
2887  RegCloseKey(compkey);
2888  LocalFree(usersid);
2889 }
2890 
2891 static void test_MsiGetComponentPath(void)
2892 {
2893  HKEY compkey, prodkey, installprop;
2894  CHAR prodcode[MAX_PATH];
2895  CHAR prod_squashed[MAX_PATH];
2896  CHAR component[MAX_PATH];
2897  CHAR comp_base85[MAX_PATH];
2898  CHAR comp_squashed[MAX_PATH];
2899  CHAR keypath[MAX_PATH];
2900  CHAR path[MAX_PATH];
2902  LPSTR usersid;
2903  DWORD size, val;
2905  LONG res;
2906 
2907  create_test_guid(prodcode, prod_squashed);
2908  compose_base85_guid(component, comp_base85, comp_squashed);
2909  usersid = get_user_sid();
2910 
2911  if (is_wow64)
2913 
2914  /* NULL szProduct */
2915  size = MAX_PATH;
2916  state = MsiGetComponentPathA(NULL, component, path, &size);
2917  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2918  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2919 
2920  /* NULL szComponent */
2921  size = MAX_PATH;
2922  state = MsiGetComponentPathA(prodcode, NULL, path, &size);
2923  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2924  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2925 
2926  size = MAX_PATH;
2928  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2929  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2930 
2931  /* NULL lpPathBuf */
2932  size = MAX_PATH;
2933  state = MsiGetComponentPathA(prodcode, component, NULL, &size);
2934  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2935  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2936 
2937  size = MAX_PATH;
2938  state = MsiLocateComponentA(component, NULL, &size);
2939  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2940  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2941 
2942  /* NULL pcchBuf */
2943  size = MAX_PATH;
2944  state = MsiGetComponentPathA(prodcode, component, path, NULL);
2945  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2946  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2947 
2948  size = MAX_PATH;
2949  state = MsiLocateComponentA(component, path, NULL);
2950  ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
2951  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2952 
2953  /* all params valid */
2954  size = MAX_PATH;
2955  state = MsiGetComponentPathA(prodcode, component, path, &size);
2956  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2957  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2958 
2959  size = MAX_PATH;
2960  state = MsiLocateComponentA(component, path, &size);
2961  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2962  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2963 
2964  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2965  lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2966  lstrcatA(keypath, comp_squashed);
2967 
2968  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2969  if (res == ERROR_ACCESS_DENIED)
2970  {
2971  skip("Not enough rights to perform tests\n");
2972  LocalFree(usersid);
2973  return;
2974  }
2975  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2976 
2977  /* local system component key exists */
2978  size = MAX_PATH;
2979  state = MsiGetComponentPathA(prodcode, component, path, &size);
2980  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2981  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2982 
2983  size = MAX_PATH;
2984  state = MsiLocateComponentA(component, path, &size);
2985  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2986  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2987 
2988  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2989  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2990 
2991  /* product value exists */
2992  path[0] = 0;
2993  size = MAX_PATH;
2994  state = MsiGetComponentPathA(prodcode, component, path, &size);
2995  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2996  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2997  ok(size == 10, "Expected 10, got %d\n", size);
2998 
2999  path[0] = 0;
3000  size = MAX_PATH;
3001  state = MsiLocateComponentA(component, path, &size);
3002  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3003  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3004  ok(size == 10, "Expected 10, got %d\n", size);
3005 
3006  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3007  lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3008  lstrcatA(keypath, prod_squashed);
3009  lstrcatA(keypath, "\\InstallProperties");
3010 
3011  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3012  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3013 
3014  val = 1;
3015  res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3016  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3017 
3018  /* install properties key exists */
3019  path[0] = 0;
3020  size = MAX_PATH;
3021  state = MsiGetComponentPathA(prodcode, component, path, &size);
3022  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3023  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3024  ok(size == 10, "Expected 10, got %d\n", size);
3025 
3026  path[0] = 0;
3027  size = MAX_PATH;
3028  state = MsiLocateComponentA(component, path, &size);
3029  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3030  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3031  ok(size == 10, "Expected 10, got %d\n", size);
3032 
3033  create_file("C:\\imapath", "C:\\imapath", 11);
3034 
3035  /* file exists */
3036  path[0] = 'a';
3037  size = 0;
3038  state = MsiGetComponentPathA(prodcode, component, path, &size);
3039  ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
3040  ok(path[0] == 'a', "got %s\n", path);
3041  ok(size == 10, "Expected 10, got %d\n", size);
3042 
3043  path[0] = 0;
3044  size = MAX_PATH;
3045  state = MsiGetComponentPathA(prodcode, component, path, &size);
3046  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3047  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3048  ok(size == 10, "Expected 10, got %d\n", size);
3049 
3050  size = 0;
3051  path[0] = 'a';
3052  state = MsiLocateComponentA(component, path, &size);
3053  ok(state == INSTALLSTATE_MOREDATA, "Expected INSTALLSTATE_MOREDATA, got %d\n", state);
3054  ok(path[0] == 'a', "got %s\n", path);
3055  ok(size == 10, "Expected 10, got %d\n", size);
3056 
3057  path[0] = 0;
3058  size = MAX_PATH;
3059  state = MsiLocateComponentA(component, path, &size);
3060  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3061  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3062  ok(size == 10, "Expected 10, got %d\n", size);
3063 
3064  RegDeleteValueA(compkey, prod_squashed);
3065  delete_key(compkey, "", access & KEY_WOW64_64KEY);
3066  RegDeleteValueA(installprop, "WindowsInstaller");
3067  delete_key(installprop, "", access & KEY_WOW64_64KEY);
3068  RegCloseKey(compkey);
3069  RegCloseKey(installprop);
3070  DeleteFileA("C:\\imapath");
3071 
3072  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3073  lstrcatA(keypath, "Installer\\UserData\\");
3074  lstrcatA(keypath, usersid);
3075  lstrcatA(keypath, "\\Components\\");
3076  lstrcatA(keypath, comp_squashed);
3077 
3078  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3079  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3080 
3081  /* user managed component key exists */
3082  size = MAX_PATH;
3083  state = MsiGetComponentPathA(prodcode, component, path, &size);
3084  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3085  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3086 
3087  size = MAX_PATH;
3088  state = MsiLocateComponentA(component, path, &size);
3089  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3090  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3091 
3092  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3093  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3094 
3095  /* product value exists */
3096  path[0] = 0;
3097  size = MAX_PATH;
3098  state = MsiGetComponentPathA(prodcode, component, path, &size);
3099  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3100  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3101  ok(size == 10, "Expected 10, got %d\n", size);
3102 
3103  path[0] = 0;
3104  size = MAX_PATH;
3105  state = MsiLocateComponentA(component, path, &size);
3106  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3107  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3108  ok(size == 10, "Expected 10, got %d\n", size);
3109 
3110  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3111  lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3112  lstrcatA(keypath, prod_squashed);
3113  lstrcatA(keypath, "\\InstallProperties");
3114 
3115  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3116  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3117 
3118  val = 1;
3119  res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3120  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3121 
3122  /* install properties key exists */
3123  path[0] = 0;
3124  size = MAX_PATH;
3125  state = MsiGetComponentPathA(prodcode, component, path, &size);
3126  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3127  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3128  ok(size == 10, "Expected 10, got %d\n", size);
3129 
3130  path[0] = 0;
3131  size = MAX_PATH;
3132  state = MsiLocateComponentA(component, path, &size);
3133  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3134  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3135  ok(size == 10, "Expected 10, got %d\n", size);
3136 
3137  create_file("C:\\imapath", "C:\\imapath", 11);
3138 
3139  /* file exists */
3140  path[0] = 0;
3141  size = MAX_PATH;
3142  state = MsiGetComponentPathA(prodcode, component, path, &size);
3143  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3144  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3145  ok(size == 10, "Expected 10, got %d\n", size);
3146 
3147  path[0] = 0;
3148  size = MAX_PATH;
3149  state = MsiLocateComponentA(component, path, &size);
3150  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3151  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3152  ok(size == 10, "Expected 10, got %d\n", size);
3153 
3154  RegDeleteValueA(compkey, prod_squashed);
3155  delete_key(compkey, "", access & KEY_WOW64_64KEY);
3156  RegDeleteValueA(installprop, "WindowsInstaller");
3157  delete_key(installprop, "", access & KEY_WOW64_64KEY);
3158  RegCloseKey(compkey);
3159  RegCloseKey(installprop);
3160  DeleteFileA("C:\\imapath");
3161 
3162  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3163  lstrcatA(keypath, "Installer\\Managed\\");
3164  lstrcatA(keypath, usersid);
3165  lstrcatA(keypath, "\\Installer\\Products\\");
3166  lstrcatA(keypath, prod_squashed);
3167 
3168  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3169  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3170 
3171  /* user managed product key exists */
3172  size = MAX_PATH;
3173  state = MsiGetComponentPathA(prodcode, component, path, &size);
3174  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3175  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3176 
3177  size = MAX_PATH;
3178  state = MsiLocateComponentA(component, path, &size);
3179  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3180  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3181 
3182  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3183  lstrcatA(keypath, "Installer\\UserData\\");
3184  lstrcatA(keypath, usersid);
3185  lstrcatA(keypath, "\\Components\\");
3186  lstrcatA(keypath, comp_squashed);
3187 
3188  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3189  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3190 
3191  /* user managed component key exists */
3192  size = MAX_PATH;
3193  state = MsiGetComponentPathA(prodcode, component, path, &size);
3194  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3195  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3196 
3197  size = MAX_PATH;
3198  state = MsiLocateComponentA(component, path, &size);
3199  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3200  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3201 
3202  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3203  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3204 
3205  /* product value exists */
3206  path[0] = 0;
3207  size = MAX_PATH;
3208  state = MsiGetComponentPathA(prodcode, component, path, &size);
3209  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3210  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3211  ok(size == 10, "Expected 10, got %d\n", size);
3212 
3213  path[0] = 0;
3214  size = MAX_PATH;
3215  state = MsiLocateComponentA(component, path, &size);
3216  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3217  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3218  ok(size == 10, "Expected 10, got %d\n", size);
3219 
3220  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3221  lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
3222  lstrcatA(keypath, prod_squashed);
3223  lstrcatA(keypath, "\\InstallProperties");
3224 
3225  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
3226  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3227 
3228  val = 1;
3229  res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3230  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3231 
3232  /* install properties key exists */
3233  path[0] = 0;
3234  size = MAX_PATH;
3235  state = MsiGetComponentPathA(prodcode, component, path, &size);
3236  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3237  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3238  ok(size == 10, "Expected 10, got %d\n", size);
3239 
3240  path[0] = 0;
3241  size = MAX_PATH;
3242  state = MsiLocateComponentA(component, path, &size);
3243  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3244  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3245  ok(size == 10, "Expected 10, got %d\n", size);
3246 
3247  create_file("C:\\imapath", "C:\\imapath", 11);
3248 
3249  /* file exists */
3250  path[0] = 0;
3251  size = MAX_PATH;
3252  state = MsiGetComponentPathA(prodcode, component, path, &size);
3253  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3254  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3255  ok(size == 10, "Expected 10, got %d\n", size);
3256 
3257  path[0] = 0;
3258  size = MAX_PATH;
3259  state = MsiLocateComponentA(component, path, &size);
3260  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3261  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3262  ok(size == 10, "Expected 10, got %d\n", size);
3263 
3264  RegDeleteValueA(compkey, prod_squashed);
3265  delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3266  delete_key(compkey, "", access & KEY_WOW64_64KEY);
3267  RegDeleteValueA(installprop, "WindowsInstaller");
3268  delete_key(installprop, "", access & KEY_WOW64_64KEY);
3269  RegCloseKey(prodkey);
3270  RegCloseKey(compkey);
3271  RegCloseKey(installprop);
3272  DeleteFileA("C:\\imapath");
3273 
3274  lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3275  lstrcatA(keypath, prod_squashed);
3276 
3277  res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3278  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3279 
3280  /* user unmanaged product key exists */
3281  size = MAX_PATH;
3282  state = MsiGetComponentPathA(prodcode, component, path, &size);
3283  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3284  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3285 
3286  size = MAX_PATH;
3287  state = MsiLocateComponentA(component, path, &size);
3288  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3289  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3290 
3291  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3292  lstrcatA(keypath, "Installer\\UserData\\");
3293  lstrcatA(keypath, usersid);
3294  lstrcatA(keypath, "\\Components\\");
3295  lstrcatA(keypath, comp_squashed);
3296 
3297  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3298  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3299 
3300  /* user unmanaged component key exists */
3301  size = MAX_PATH;
3302  state = MsiGetComponentPathA(prodcode, component, path, &size);
3303  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3304  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3305 
3306  size = MAX_PATH;
3307  state = MsiLocateComponentA(component, path, &size);
3308  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3309  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3310 
3311  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3312  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3313 
3314  /* product value exists */
3315  path[0] = 0;
3316  size = MAX_PATH;
3317  state = MsiGetComponentPathA(prodcode, component, path, &size);
3318  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3319  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3320  ok(size == 10, "Expected 10, got %d\n", size);
3321 
3322  path[0] = 0;
3323  size = MAX_PATH;
3324  state = MsiLocateComponentA(component, path, &size);
3325  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3326  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3327  ok(size == 10, "Expected 10, got %d\n", size);
3328 
3329  create_file("C:\\imapath", "C:\\imapath", 11);
3330 
3331  /* file exists */
3332  path[0] = 0;
3333  size = MAX_PATH;
3334  state = MsiGetComponentPathA(prodcode, component, path, &size);
3335  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3336  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3337  ok(size == 10, "Expected 10, got %d\n", size);
3338 
3339  path[0] = 0;
3340  size = MAX_PATH;
3341  state = MsiLocateComponentA(component, path, &size);
3342  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3343  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3344  ok(size == 10, "Expected 10, got %d\n", size);
3345 
3346  RegDeleteValueA(compkey, prod_squashed);
3347  RegDeleteKeyA(prodkey, "");
3348  delete_key(compkey, "", access & KEY_WOW64_64KEY);
3349  RegCloseKey(prodkey);
3350  RegCloseKey(compkey);
3351  DeleteFileA("C:\\imapath");
3352 
3353  lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3354  lstrcatA(keypath, prod_squashed);
3355 
3356  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3357  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3358 
3359  /* local classes product key exists */
3360  size = MAX_PATH;
3361  state = MsiGetComponentPathA(prodcode, component, path, &size);
3362  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3363  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3364 
3365  size = MAX_PATH;
3366  state = MsiLocateComponentA(component, path, &size);
3367  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3368  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3369 
3370  lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3371  lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
3372  lstrcatA(keypath, comp_squashed);
3373 
3374  res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3375  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3376 
3377  /* local user component key exists */
3378  size = MAX_PATH;
3379  state = MsiGetComponentPathA(prodcode, component, path, &size);
3380  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3381  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3382 
3383  size = MAX_PATH;
3384  state = MsiLocateComponentA(component, path, &size);
3385  ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3386  ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
3387 
3388  res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3389  ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3390 
3391  /* product value exists */
3392  path[0] = 0;
3393  size = MAX_PATH;
3394  state = MsiGetComponentPathA(prodcode, component, path, &size);
3395  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3396  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3397  ok(size == 10, "Expected 10, got %d\n", size);
3398 
3399  path[0] = 0;
3400  size = MAX_PATH;
3401  state = MsiLocateComponentA(component, path, &size);
3402  ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
3403  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3404  ok(size == 10, "Expected 10, got %d\n", size);
3405 
3406  create_file("C:\\imapath", "C:\\imapath", 11);
3407 
3408  /* file exists */
3409  path[0] = 0;
3410  size = MAX_PATH;
3411  state = MsiGetComponentPathA(prodcode, component, path, &size);
3412  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3413  ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
3414  ok(size == 10, "Expected 10, got %d\n", size);
3415 
3416  path[0] = 0;
3417  size = MAX_PATH;
3418  state = MsiLocateComponentA(component, path, &size);
3419  ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
3420