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