1 /*
2  * Copyright (C) 2006 James Hawkins
3  * Copyright 2010 Hans Leidekker for CodeWeavers
4  *
5  * Tests concentrating on standard actions
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #define _WIN32_MSI 300
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #include <windows.h>
27 #include <msiquery.h>
28 #include <msidefs.h>
29 #include <msi.h>
30 #include <fci.h>
31 #include <srrestoreptapi.h>
32 #include <wtypes.h>
33 #include <shellapi.h>
34 #include <winsvc.h>
35 
36 #include "wine/test.h"
37 
38 static UINT (WINAPI *pMsiQueryComponentStateA)
39     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *);
40 static UINT (WINAPI *pMsiSourceListEnumSourcesA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiSourceListGetInfoA)
43     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
44 static INSTALLSTATE (WINAPI *pMsiGetComponentPathExA)
45     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPSTR, LPDWORD);
46 static UINT (WINAPI *pMsiQueryFeatureStateExA)
47     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *);
48 
49 static BOOL (WINAPI *pCheckTokenMembership)(HANDLE,PSID,PBOOL);
50 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR *);
51 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE);
52 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
53 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
54 
55 static HMODULE hsrclient;
56 static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
57 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA *, STATEMGRSTATUS *);
58 
59 static BOOL is_wow64;
60 static const BOOL is_64bit = sizeof(void *) > sizeof(int);
61 
62 static const char *msifile = "msitest.msi";
63 static CHAR CURR_DIR[MAX_PATH];
64 static CHAR PROG_FILES_DIR[MAX_PATH];
65 static CHAR COMMON_FILES_DIR[MAX_PATH];
66 static CHAR APP_DATA_DIR[MAX_PATH];
67 static CHAR WINDOWS_DIR[MAX_PATH];
68 
69 /* msi database data */
70 
71 static const char component_dat[] =
72     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
73     "s72\tS38\ts72\ti2\tS255\tS72\n"
74     "Component\tComponent\n"
75     "Five\t{8CC92E9D-14B2-4CA4-B2AA-B11D02078087}\tNEWDIR\t2\t\tfive.txt\n"
76     "Four\t{FD37B4EA-7209-45C0-8917-535F35A2F080}\tCABOUTDIR\t2\t\tfour.txt\n"
77     "One\t{783B242E-E185-4A56-AF86-C09815EC053C}\tMSITESTDIR\t2\tNOT REINSTALL\tone.txt\n"
78     "Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
79     "Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
80     "dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
81     "component\t\tMSITESTDIR\t0\t1\tfile\n"
82     "service_comp\t{935A0A91-22A3-4F87-BCA8-928FFDFE2353}\tMSITESTDIR\t0\t\tservice_file\n"
83     "service_comp2\t{3F7B04A4-9521-4649-BDC9-0C8722740A49}\tMSITESTDIR\t0\t\tservice_file2\n"
84     "service_comp3\t{DBCD1502-20E3-423F-B53E-F37E263CDC7E}\tMSITESTDIR\t0\t\t\n";
85 
86 static const char directory_dat[] =
87     "Directory\tDirectory_Parent\tDefaultDir\n"
88     "s72\tS72\tl255\n"
89     "Directory\tDirectory\n"
90     "CABOUTDIR\tMSITESTDIR\tcabout\n"
91     "CHANGEDDIR\tMSITESTDIR\tchanged:second\n"
92     "FIRSTDIR\tMSITESTDIR\tfirst\n"
93     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
94     "NEWDIR\tCABOUTDIR\tnew\n"
95     "ProgramFilesFolder\tTARGETDIR\t.\n"
96     "TARGETDIR\t\tSourceDir";
97 
98 static const char feature_dat[] =
99     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
100     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
101     "Feature\tFeature\n"
102     "Five\t\tFive\tThe Five Feature\t5\t3\tNEWDIR\t0\n"
103     "Four\t\tFour\tThe Four Feature\t4\t3\tCABOUTDIR\t0\n"
104     "One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
105     "Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
106     "Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
107     "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
108     "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
109 
110 static const char feature_comp_dat[] =
111     "Feature_\tComponent_\n"
112     "s38\ts72\n"
113     "FeatureComponents\tFeature_\tComponent_\n"
114     "Five\tFive\n"
115     "Four\tFour\n"
116     "One\tOne\n"
117     "Three\tThree\n"
118     "Two\tTwo\n"
119     "feature\tcomponent\n"
120     "service_feature\tservice_comp\n"
121     "service_feature\tservice_comp2\n"
122     "service_feature\tservice_comp3";
123 
124 static const char file_dat[] =
125     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
126     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
127     "File\tFile\n"
128     "five.txt\tFive\tfive.txt\t1000\t\t\t16384\t5\n"
129     "four.txt\tFour\tfour.txt\t1000\t\t\t16384\t4\n"
130     "one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
131     "three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
132     "two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
133     "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
134     "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t6\n"
135     "service_file2\tservice_comp2\tservice2.exe\t100\t\t\t8192\t7";
136 
137 static const char install_exec_seq_dat[] =
138     "Action\tCondition\tSequence\n"
139     "s72\tS255\tI2\n"
140     "InstallExecuteSequence\tAction\n"
141     "AllocateRegistrySpace\tNOT Installed\t1550\n"
142     "CostFinalize\t\t1000\n"
143     "CostInitialize\t\t800\n"
144     "FileCost\t\t900\n"
145     "ResolveSource\t\t950\n"
146     "MoveFiles\t\t1700\n"
147     "InstallFiles\t\t4000\n"
148     "DuplicateFiles\t\t4500\n"
149     "WriteEnvironmentStrings\t\t4550\n"
150     "CreateShortcuts\t\t4600\n"
151     "InstallServices\t\t5000\n"
152     "InstallFinalize\t\t6600\n"
153     "InstallInitialize\t\t1500\n"
154     "InstallValidate\t\t1400\n"
155     "LaunchConditions\t\t100\n"
156     "WriteRegistryValues\tSourceDir And SOURCEDIR\t5000";
157 
158 static const char media_dat[] =
159     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
160     "i2\ti4\tL64\tS255\tS32\tS72\n"
161     "Media\tDiskId\n"
162     "1\t3\t\t\tDISK1\t\n"
163     "2\t7\t\tmsitest.cab\tDISK2\t\n";
164 
165 static const char property_dat[] =
166     "Property\tValue\n"
167     "s72\tl0\n"
168     "Property\tProperty\n"
169     "DefaultUIFont\tDlgFont8\n"
170     "HASUIRUN\t0\n"
171     "INSTALLLEVEL\t3\n"
172     "InstallMode\tTypical\n"
173     "Manufacturer\tWine\n"
174     "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
175     "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
176     "ProductID\tnone\n"
177     "ProductLanguage\t1033\n"
178     "ProductName\tMSITEST\n"
179     "ProductVersion\t1.1.1\n"
180     "PROMPTROLLBACKCOST\tP\n"
181     "Setup\tSetup\n"
182     "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
183     "AdminProperties\tPOSTADMIN\n"
184     "ROOTDRIVE\tC:\\\n"
185     "SERVNAME\tTestService\n"
186     "SERVNAME2\tTestService2\n"
187     "SERVDISP\tTestServiceDisp\n"
188     "SERVDISP2\tTestServiceDisp2\n"
189     "MSIFASTINSTALL\t1\n"
190     "regdata15\t#x01\n";
191 
192 static const char environment_dat[] =
193     "Environment\tName\tValue\tComponent_\n"
194     "s72\tl255\tL255\ts72\n"
195     "Environment\tEnvironment\n"
196     "Var1\t=-MSITESTVAR1\t1\tOne\n"
197     "Var2\tMSITESTVAR2\t1\tOne\n"
198     "Var3\t=-MSITESTVAR3\t1\tOne\n"
199     "Var4\tMSITESTVAR4\t1\tOne\n"
200     "Var5\t-MSITESTVAR5\t\tOne\n"
201     "Var6\tMSITESTVAR6\t\tOne\n"
202     "Var7\t!-MSITESTVAR7\t\tOne\n"
203     "Var8\t!-*MSITESTVAR8\t\tOne\n"
204     "Var9\t=-MSITESTVAR9\t\tOne\n"
205     "Var10\t=MSITESTVAR10\t\tOne\n"
206     "Var11\t+-MSITESTVAR11\t[~];1\tOne\n"
207     "Var12\t+-MSITESTVAR11\t[~];2\tOne\n"
208     "Var13\t+-MSITESTVAR12\t[~];1\tOne\n"
209     "Var14\t=MSITESTVAR13\t[~];1\tOne\n"
210     "Var15\t=MSITESTVAR13\t[~];2\tOne\n"
211     "Var16\t=MSITESTVAR14\t;1;\tOne\n"
212     "Var17\t=MSITESTVAR15\t;;1;;\tOne\n"
213     "Var18\t=MSITESTVAR16\t 1 \tOne\n"
214     "Var19\t+-MSITESTVAR17\t1\tOne\n"
215     "Var20\t+-MSITESTVAR17\t;;2;;[~]\tOne\n"
216     "Var21\t+-MSITESTVAR18\t1\tOne\n"
217     "Var22\t+-MSITESTVAR18\t[~];;2;;\tOne\n"
218     "Var23\t+-MSITESTVAR19\t1\tOne\n"
219     "Var24\t+-MSITESTVAR19\t[~]2\tOne\n"
220     "Var25\t+-MSITESTVAR20\t1\tOne\n"
221     "Var26\t+-MSITESTVAR20\t2[~]\tOne\n"
222     "Var27\t+-MSITESTVAR21\t[~];1\tOne\n";
223 
224 static const char service_install_dat[] =
225     "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
226     "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
227     "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
228     "ServiceInstall\tServiceInstall\n"
229     "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService\t\t-a arg\tservice_comp\tdescription\n"
230     "TestService2\t[SERVNAME2]\t[SERVDISP2]\t2\t3\t0\t\tservice1[~]+group1[~]service2[~]+group2[~][~]\tTestService2\t\t-a arg\tservice_comp2\tdescription\n";
231 
232 static const char service_install2_dat[] =
233     "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
234     "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
235     "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
236     "ServiceInstall\tServiceInstall\n"
237     "TestService\tTestService\tTestService\t2\t3\t32768\t\t\tTestService\t\t\tservice_comp\t\n"
238     "TestService4\tTestService4\tTestService4\t2\t3\t0\t\t\tTestService4\t\t\tservice_comp3\t\n";
239 
240 static const char service_control_dat[] =
241     "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
242     "s72\tl255\ti2\tL255\tI2\ts72\n"
243     "ServiceControl\tServiceControl\n"
244     "ServiceControl\tTestService3\t8\t\t0\tservice_comp\n"
245     "ServiceControl2\tTestService3\t128\t\t0\tservice_comp2";
246 
247 static const char sss_service_control_dat[] =
248     "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
249     "s72\tl255\ti2\tL255\tI2\ts72\n"
250     "ServiceControl\tServiceControl\n"
251     "ServiceControl\tSpooler\t1\t\t1\tservice_comp\n"
252     "ServiceControl2\tSpooler\t2\t\t1\tservice_comp\n"
253     "ServiceControl3\tSpooler\t16\t\t1\tservice_comp\n"
254     "ServiceControl4\tSpooler\t32\t\t1\tservice_comp\n";
255 
256 static const char sss_install_exec_seq_dat[] =
257     "Action\tCondition\tSequence\n"
258     "s72\tS255\tI2\n"
259     "InstallExecuteSequence\tAction\n"
260     "LaunchConditions\t\t100\n"
261     "CostInitialize\t\t800\n"
262     "FileCost\t\t900\n"
263     "ResolveSource\t\t950\n"
264     "CostFinalize\t\t1000\n"
265     "InstallValidate\t\t1400\n"
266     "InstallInitialize\t\t1500\n"
267     "StopServices\t\t4000\n"
268     "DeleteServices\t\t5000\n"
269     "MoveFiles\t\t5100\n"
270     "InstallFiles\t\t5200\n"
271     "DuplicateFiles\t\t5300\n"
272     "StartServices\t\t5400\n"
273     "RegisterProduct\t\t5500\n"
274     "PublishFeatures\t\t5600\n"
275     "PublishProduct\t\t5700\n"
276     "InstallFinalize\t\t6000\n";
277 
278 static const char sds_install_exec_seq_dat[] =
279     "Action\tCondition\tSequence\n"
280     "s72\tS255\tI2\n"
281     "InstallExecuteSequence\tAction\n"
282     "LaunchConditions\t\t100\n"
283     "CostInitialize\t\t800\n"
284     "FileCost\t\t900\n"
285     "ResolveSource\t\t950\n"
286     "CostFinalize\t\t1000\n"
287     "InstallValidate\t\t1400\n"
288     "InstallInitialize\t\t1500\n"
289     "StopServices\t\t5000\n"
290     "DeleteServices\t\t5050\n"
291     "MoveFiles\t\t5100\n"
292     "InstallFiles\t\t5200\n"
293     "DuplicateFiles\t\t5300\n"
294     "InstallServices\t\t5400\n"
295     "StartServices\t\t5450\n"
296     "RegisterProduct\t\t5500\n"
297     "PublishFeatures\t\t5600\n"
298     "PublishProduct\t\t5700\n"
299     "InstallFinalize\t\t6000\n";
300 
301 static const char rof_component_dat[] =
302     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
303     "s72\tS38\ts72\ti2\tS255\tS72\n"
304     "Component\tComponent\n"
305     "maximus\t\tMSITESTDIR\t0\t1\tmaximus\n";
306 
307 static const char rof_feature_dat[] =
308     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
309     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
310     "Feature\tFeature\n"
311     "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
312     "montecristo\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0";
313 
314 static const char rof_feature_comp_dat[] =
315     "Feature_\tComponent_\n"
316     "s38\ts72\n"
317     "FeatureComponents\tFeature_\tComponent_\n"
318     "feature\tmaximus\n"
319     "montecristo\tmaximus";
320 
321 static const char rof_file_dat[] =
322     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
323     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
324     "File\tFile\n"
325     "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1";
326 
327 static const char rof_media_dat[] =
328     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
329     "i2\ti4\tL64\tS255\tS32\tS72\n"
330     "Media\tDiskId\n"
331     "1\t1\t\t\tDISK1\t\n";
332 
333 static const char ci2_feature_comp_dat[] =
334     "Feature_\tComponent_\n"
335     "s38\ts72\n"
336     "FeatureComponents\tFeature_\tComponent_\n"
337     "feature\taugustus";
338 
339 static const char ci2_file_dat[] =
340     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
341     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
342     "File\tFile\n"
343     "augustus\taugustus\taugustus\t500\t\t\t8192\t1";
344 
345 static const char pp_install_exec_seq_dat[] =
346     "Action\tCondition\tSequence\n"
347     "s72\tS255\tI2\n"
348     "InstallExecuteSequence\tAction\n"
349     "ValidateProductID\t\t700\n"
350     "CostInitialize\t\t800\n"
351     "FileCost\t\t900\n"
352     "CostFinalize\t\t1000\n"
353     "InstallValidate\t\t1400\n"
354     "InstallInitialize\t\t1500\n"
355     "ProcessComponents\tPROCESS_COMPONENTS=1 Or FULL=1\t1600\n"
356     "UnpublishFeatures\tUNPUBLISH_FEATURES=1 Or FULL=1\t1800\n"
357     "RemoveFiles\t\t3500\n"
358     "InstallFiles\t\t4000\n"
359     "RegisterUser\tREGISTER_USER=1 Or FULL=1\t6000\n"
360     "RegisterProduct\tREGISTER_PRODUCT=1 Or FULL=1\t6100\n"
361     "PublishFeatures\tPUBLISH_FEATURES=1 Or FULL=1\t6300\n"
362     "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n"
363     "InstallFinalize\t\t6600";
364 
365 static const char pp_component_dat[] =
366     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
367     "s72\tS38\ts72\ti2\tS255\tS72\n"
368     "Component\tComponent\n"
369     "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\t\tmaximus\n";
370 
371 static const char ppc_component_dat[] =
372     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
373     "s72\tS38\ts72\ti2\tS255\tS72\n"
374     "Component\tComponent\n"
375     "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\t\tmaximus\n"
376     "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n";
377 
378 static const char ppc_file_dat[] =
379     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
380     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
381     "File\tFile\n"
382     "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n"
383     "augustus\taugustus\taugustus\t500\t\t\t8192\t2";
384 
385 static const char ppc_media_dat[] =
386     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
387     "i2\ti4\tL64\tS255\tS32\tS72\n"
388     "Media\tDiskId\n"
389     "1\t2\t\t\tDISK1\t\n";
390 
391 static const char ppc_feature_comp_dat[] =
392     "Feature_\tComponent_\n"
393     "s38\ts72\n"
394     "FeatureComponents\tFeature_\tComponent_\n"
395     "feature\tmaximus\n"
396     "feature\taugustus\n"
397     "montecristo\tmaximus";
398 
399 static const char cwd_component_dat[] =
400     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
401     "s72\tS38\ts72\ti2\tS255\tS72\n"
402     "Component\tComponent\n"
403     "augustus\t\tMSITESTDIR\t0\t\taugustus\n";
404 
405 static const char rem_component_dat[] =
406     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
407     "s72\tS38\ts72\ti2\tS255\tS72\n"
408     "Component\tComponent\n"
409     "hydrogen\t{C844BD1E-1907-4C00-8BC9-150BD70DF0A1}\tMSITESTDIR\t0\t\thydrogen\n"
410     "helium\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\thelium\n"
411     "lithium\t\tMSITESTDIR\t2\t\tlithium\n";
412 
413 static const char rem_feature_comp_dat[] =
414     "Feature_\tComponent_\n"
415     "s38\ts72\n"
416     "FeatureComponents\tFeature_\tComponent_\n"
417     "feature\thydrogen\n"
418     "feature\thelium\n"
419     "feature\tlithium";
420 
421 static const char rem_file_dat[] =
422     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
423     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
424     "File\tFile\n"
425     "hydrogen\thydrogen\thydrogen\t0\t\t\t8192\t1\n"
426     "helium\thelium\thelium\t0\t\t\t8192\t1\n"
427     "lithium\tlithium\tlithium\t0\t\t\t8192\t1";
428 
429 static const char rem_install_exec_seq_dat[] =
430     "Action\tCondition\tSequence\n"
431     "s72\tS255\tI2\n"
432     "InstallExecuteSequence\tAction\n"
433     "ValidateProductID\t\t700\n"
434     "CostInitialize\t\t800\n"
435     "FileCost\t\t900\n"
436     "CostFinalize\t\t1000\n"
437     "InstallValidate\t\t1400\n"
438     "InstallInitialize\t\t1500\n"
439     "ProcessComponents\t\t1600\n"
440     "UnpublishFeatures\t\t1800\n"
441     "RemoveFiles\t\t3500\n"
442     "InstallFiles\t\t4000\n"
443     "RegisterProduct\t\t6100\n"
444     "PublishFeatures\t\t6300\n"
445     "PublishProduct\t\t6400\n"
446     "InstallFinalize\t\t6600";
447 
448 static const char rem_remove_files_dat[] =
449     "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"
450     "s72\ts72\tS255\ts72\tI2\n"
451     "RemoveFile\tFileKey\n"
452     "furlong\thydrogen\tfurlong\tMSITESTDIR\t1\n"
453     "firkin\thelium\tfirkin\tMSITESTDIR\t1\n"
454     "fortnight\tlithium\tfortnight\tMSITESTDIR\t1\n"
455     "becquerel\thydrogen\tbecquerel\tMSITESTDIR\t2\n"
456     "dioptre\thelium\tdioptre\tMSITESTDIR\t2\n"
457     "attoparsec\tlithium\tattoparsec\tMSITESTDIR\t2\n"
458     "storeys\thydrogen\tstoreys\tMSITESTDIR\t3\n"
459     "block\thelium\tblock\tMSITESTDIR\t3\n"
460     "siriometer\tlithium\tsiriometer\tMSITESTDIR\t3\n"
461     "nanoacre\thydrogen\t\tCABOUTDIR\t3\n";
462 
463 static const char mov_move_file_dat[] =
464     "FileKey\tComponent_\tSourceName\tDestName\tSourceFolder\tDestFolder\tOptions\n"
465     "s72\ts72\tS255\tS255\tS72\ts72\ti2\n"
466     "MoveFile\tFileKey\n"
467     "abkhazia\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t0\n"
468     "bahamas\taugustus\tnonexistent\tdest\tSourceDir\tMSITESTDIR\t1\n"
469     "cambodia\taugustus\tcameroon\tcanada\tSourceDir\tMSITESTDIR\t0\n"
470     "denmark\taugustus\tdjibouti\tdominica\tSourceDir\tMSITESTDIR\t1\n"
471     "ecuador\taugustus\tegypt\telsalvador\tNotAProp\tMSITESTDIR\t1\n"
472     "fiji\taugustus\tfinland\tfrance\tSourceDir\tNotAProp\t1\n"
473     "gabon\taugustus\tgambia\tgeorgia\tSOURCEFULL\tMSITESTDIR\t1\n"
474     "haiti\taugustus\thonduras\thungary\tSourceDir\tDESTFULL\t1\n"
475     "iceland\taugustus\tindia\tindonesia\tMSITESTDIR\tMSITESTDIR\t1\n"
476     "jamaica\taugustus\tjapan\tjordan\tFILEPATHBAD\tMSITESTDIR\t1\n"
477     "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n"
478     "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n"
479     "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n"
480     "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n"
481     "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n"
482     "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n"
483     "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n"
484     "singlenodest\taugustus\tb?r\t\tSourceDir\tMSITESTDIR\t1\n";
485 
486 static const char df_directory_dat[] =
487     "Directory\tDirectory_Parent\tDefaultDir\n"
488     "s72\tS72\tl255\n"
489     "Directory\tDirectory\n"
490     "THIS\tMSITESTDIR\tthis\n"
491     "DOESNOT\tTHIS\tdoesnot\n"
492     "NONEXISTENT\tDOESNOT\texist\n"
493     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
494     "ProgramFilesFolder\tTARGETDIR\t.\n"
495     "TARGETDIR\t\tSourceDir";
496 
497 static const char df_duplicate_file_dat[] =
498     "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
499     "s72\ts72\ts72\tS255\tS72\n"
500     "DuplicateFile\tFileKey\n"
501     "maximus\tmaximus\tmaximus\taugustus\t\n"
502     "caesar\tmaximus\tmaximus\t\tNONEXISTENT\n"
503     "augustus\tnosuchcomponent\tmaximus\t\tMSITESTDIR\n";
504 
505 static const char wrv_component_dat[] =
506     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
507     "s72\tS38\ts72\ti2\tS255\tS72\n"
508     "Component\tComponent\n"
509     "augustus\t\tMSITESTDIR\t0\t\taugustus\n"
510     "caesar\t\tMSITESTDIR\t1\t\t\n";
511 
512 static const char wrv_feature_dat[] =
513     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
514     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
515     "Feature\tFeature\n"
516     "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n"
517     "feature2\t\tFeature2\tFeature2\t2\t1\tTARGETDIR\t1";
518 
519 static const char wrv_feature_comp_dat[] =
520     "Feature_\tComponent_\n"
521     "s38\ts72\n"
522     "FeatureComponents\tFeature_\tComponent_\n"
523     "feature\taugustus\n"
524     "feature2\tcaesar";
525 
526 static const char wrv_registry_dat[] =
527     "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
528     "s72\ti2\tl255\tL255\tL0\ts72\n"
529     "Registry\tRegistry\n"
530     "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus\n"
531     "regdata1\t2\tSOFTWARE\\Wine\\msitest\t*\t\taugustus\n"
532     "regdata2\t2\tSOFTWARE\\Wine\\msitest\t*\t#%\taugustus\n"
533     "regdata3\t2\tSOFTWARE\\Wine\\msitest\t*\t#x\taugustus\n"
534     "regdata4\t2\tSOFTWARE\\Wine\\msitest\\VisualStudio\\10.0\\AD7Metrics\\Exception\\{049EC4CC-30D2-4032-9256-EE18EB41B62B}\\Common Language Runtime Exceptions\\System.Workflow.ComponentModel.Serialization\\System.Workflow.ComponentModel.Serialization.WorkflowMarkupSerializationException\tlong\tkey\taugustus\n"
535     "regdata5\t2\tSOFTWARE\\Wine\\msitest\tValue1\t[~]one[~]\taugustus\n"
536     "regdata6\t2\tSOFTWARE\\Wine\\msitest\tValue2\t[~]two\taugustus\n"
537     "regdata7\t2\tSOFTWARE\\Wine\\msitest\tValue3\tone[~]\taugustus\n"
538     "regdata8\t2\tSOFTWARE\\Wine\\msitest\tValue4\tone[~]two\taugustus\n"
539     "regdata9\t2\tSOFTWARE\\Wine\\msitest\tValue5\t[~]one[~]two[~]three\taugustus\n"
540     "regdata10\t2\tSOFTWARE\\Wine\\msitest\tValue6\t[~]\taugustus\n"
541     "regdata11\t2\tSOFTWARE\\Wine\\msitest\tValue7\t[~]two\taugustus\n"
542     "regdata12\t2\tSOFTWARE\\Wine\\msitest\tValue8\t#1\taugustus\n"
543     "regdata13\t2\tSOFTWARE\\Wine\\msitest\tValue9\t#x1\taugustus\n"
544     "regdata14\t2\tSOFTWARE\\Wine\\msitest\tValue10\t#x01\taugustus\n"
545     "regdata15\t2\tSOFTWARE\\Wine\\msitest\tValue11\t[regdata15]\taugustus\n"
546     "regdata16\t2\tSOFTWARE\\Wine\\msitest\tValue12\t#1\tcaesar\n";
547 
548 static const char cf_directory_dat[] =
549     "Directory\tDirectory_Parent\tDefaultDir\n"
550     "s72\tS72\tl255\n"
551     "Directory\tDirectory\n"
552     "FIRSTDIR\tMSITESTDIR\tfirst\n"
553     "SECONDDIR\tMSITESTDIR\tsecond\n"
554     "THIRDDIR\tMSITESTDIR\tthird\n"
555     "MSITESTDIR\tProgramFilesFolder\tmsitest\n"
556     "ProgramFilesFolder\tTARGETDIR\t.\n"
557     "TARGETDIR\t\tSourceDir";
558 
559 static const char cf_component_dat[] =
560     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
561     "s72\tS38\ts72\ti2\tS255\tS72\n"
562     "Component\tComponent\n"
563     "One\t{F8CD42AC-9C38-48FE-8664-B35FD121012A}\tFIRSTDIR\t0\t\tone.txt\n"
564     "Two\t{DE2DB02E-2DDF-4E34-8CF6-DCA13E29DF52}\tSECONDDIR\t0\t\ttwo.txt\n";
565 
566 static const char cf_feature_dat[] =
567     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
568     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
569     "Feature\tFeature\n"
570     "One\t\tOne\tThe One Feature\t1\t3\tFIRSTDIR\t0\n"
571     "Two\t\tTwo\tThe Two Feature\t1\t3\tSECONDDIR\t0\n";
572 
573 static const char cf_feature_comp_dat[] =
574     "Feature_\tComponent_\n"
575     "s38\ts72\n"
576     "FeatureComponents\tFeature_\tComponent_\n"
577     "One\tOne\n"
578     "Two\tTwo\n";
579 
580 static const char cf_file_dat[] =
581     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
582     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
583     "File\tFile\n"
584     "one.txt\tOne\tone.txt\t0\t\t\t0\t1\n"
585     "two.txt\tTwo\ttwo.txt\t0\t\t\t0\t2\n";
586 
587 static const char cf_create_folders_dat[] =
588     "Directory_\tComponent_\n"
589     "s72\ts72\n"
590     "CreateFolder\tDirectory_\tComponent_\n"
591     "FIRSTDIR\tOne\n"
592     "SECONDDIR\tTwo\n"
593     "THIRDDIR\tTwo\n";
594 
595 static const char cf_install_exec_seq_dat[] =
596     "Action\tCondition\tSequence\n"
597     "s72\tS255\tI2\n"
598     "InstallExecuteSequence\tAction\n"
599     "CostFinalize\t\t1000\n"
600     "ValidateProductID\t\t700\n"
601     "CostInitialize\t\t800\n"
602     "FileCost\t\t900\n"
603     "RemoveFiles\t\t3500\n"
604     "CreateFolders\t\t3700\n"
605     "RemoveFolders\t\t3800\n"
606     "InstallFiles\t\t4000\n"
607     "RegisterUser\t\t6000\n"
608     "RegisterProduct\t\t6100\n"
609     "PublishFeatures\t\t6300\n"
610     "PublishProduct\t\t6400\n"
611     "InstallFinalize\t\t6600\n"
612     "InstallInitialize\t\t1500\n"
613     "ProcessComponents\t\t1600\n"
614     "UnpublishFeatures\t\t1800\n"
615     "InstallValidate\t\t1400\n"
616     "LaunchConditions\t\t100\n";
617 
618 static const char sr_selfreg_dat[] =
619     "File_\tCost\n"
620     "s72\tI2\n"
621     "SelfReg\tFile_\n"
622     "one.txt\t1\n";
623 
624 static const char sr_install_exec_seq_dat[] =
625     "Action\tCondition\tSequence\n"
626     "s72\tS255\tI2\n"
627     "InstallExecuteSequence\tAction\n"
628     "CostFinalize\t\t1000\n"
629     "CostInitialize\t\t800\n"
630     "FileCost\t\t900\n"
631     "ResolveSource\t\t950\n"
632     "MoveFiles\t\t1700\n"
633     "SelfUnregModules\t\t3900\n"
634     "InstallFiles\t\t4000\n"
635     "DuplicateFiles\t\t4500\n"
636     "WriteEnvironmentStrings\t\t4550\n"
637     "CreateShortcuts\t\t4600\n"
638     "InstallFinalize\t\t6600\n"
639     "InstallInitialize\t\t1500\n"
640     "InstallValidate\t\t1400\n"
641     "LaunchConditions\t\t100\n";
642 
643 static const char font_media_dat[] =
644     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
645     "i2\ti4\tL64\tS255\tS32\tS72\n"
646     "Media\tDiskId\n"
647     "1\t3\t\t\tDISK1\t\n";
648 
649 static const char font_file_dat[] =
650     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
651     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
652     "File\tFile\n"
653     "font.ttf\tfonts\tfont.ttf\t1000\t\t\t8192\t1\n";
654 
655 static const char font_feature_dat[] =
656     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
657     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
658     "Feature\tFeature\n"
659     "fonts\t\t\tfont feature\t1\t2\tMSITESTDIR\t0\n";
660 
661 static const char font_component_dat[] =
662     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
663     "s72\tS38\ts72\ti2\tS255\tS72\n"
664     "Component\tComponent\n"
665     "fonts\t{F5920ED0-1183-4B8F-9330-86CE56557C05}\tMSITESTDIR\t0\t\tfont.ttf\n";
666 
667 static const char font_feature_comp_dat[] =
668     "Feature_\tComponent_\n"
669     "s38\ts72\n"
670     "FeatureComponents\tFeature_\tComponent_\n"
671     "fonts\tfonts\n";
672 
673 static const char font_dat[] =
674     "File_\tFontTitle\n"
675     "s72\tS128\n"
676     "Font\tFile_\n"
677     "font.ttf\tmsi test font\n";
678 
679 static const char font_install_exec_seq_dat[] =
680     "Action\tCondition\tSequence\n"
681     "s72\tS255\tI2\n"
682     "InstallExecuteSequence\tAction\n"
683     "ValidateProductID\t\t700\n"
684     "CostInitialize\t\t800\n"
685     "FileCost\t\t900\n"
686     "CostFinalize\t\t1000\n"
687     "InstallValidate\t\t1400\n"
688     "InstallInitialize\t\t1500\n"
689     "ProcessComponents\t\t1600\n"
690     "UnpublishFeatures\t\t1800\n"
691     "RemoveFiles\t\t3500\n"
692     "InstallFiles\t\t4000\n"
693     "RegisterFonts\t\t4100\n"
694     "UnregisterFonts\t\t4200\n"
695     "RegisterUser\t\t6000\n"
696     "RegisterProduct\t\t6100\n"
697     "PublishFeatures\t\t6300\n"
698     "PublishProduct\t\t6400\n"
699     "InstallFinalize\t\t6600";
700 
701 static const char vp_property_dat[] =
702     "Property\tValue\n"
703     "s72\tl0\n"
704     "Property\tProperty\n"
705     "HASUIRUN\t0\n"
706     "INSTALLLEVEL\t3\n"
707     "InstallMode\tTypical\n"
708     "Manufacturer\tWine\n"
709     "PIDTemplate\t###-#######\n"
710     "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n"
711     "ProductLanguage\t1033\n"
712     "ProductName\tMSITEST\n"
713     "ProductVersion\t1.1.1\n"
714     "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
715     "MSIFASTINSTALL\t1\n";
716 
717 static const char vp_custom_action_dat[] =
718     "Action\tType\tSource\tTarget\tISComments\n"
719     "s72\ti2\tS64\tS0\tS255\n"
720     "CustomAction\tAction\n"
721     "SetProductID1\t51\tProductID\t1\t\n"
722     "SetProductID2\t51\tProductID\t2\t\n"
723     "TestProductID1\t19\t\t\tHalts installation\n"
724     "TestProductID2\t19\t\t\tHalts installation\n";
725 
726 static const char vp_install_exec_seq_dat[] =
727     "Action\tCondition\tSequence\n"
728     "s72\tS255\tI2\n"
729     "InstallExecuteSequence\tAction\n"
730     "LaunchConditions\t\t100\n"
731     "CostInitialize\t\t800\n"
732     "FileCost\t\t900\n"
733     "CostFinalize\t\t1000\n"
734     "InstallValidate\t\t1400\n"
735     "InstallInitialize\t\t1500\n"
736     "SetProductID1\tSET_PRODUCT_ID=1\t3000\n"
737     "SetProductID2\tSET_PRODUCT_ID=2\t3100\n"
738     "ValidateProductID\t\t3200\n"
739     "InstallExecute\t\t3300\n"
740     "TestProductID1\tProductID=1\t3400\n"
741     "TestProductID2\tProductID=\"123-1234567\"\t3500\n"
742     "InstallFiles\t\t4000\n"
743     "InstallFinalize\t\t6000\n";
744 
745 static const char odbc_file_dat[] =
746     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
747     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
748     "File\tFile\n"
749     "ODBCdriver.dll\todbc\tODBCdriver.dll\t1000\t\t\t8192\t1\n"
750     "ODBCdriver2.dll\todbc\tODBCdriver2.dll\t1000\t\t\t8192\t2\n"
751     "ODBCtranslator.dll\todbc\tODBCtranslator.dll\t1000\t\t\t8192\t3\n"
752     "ODBCtranslator2.dll\todbc\tODBCtranslator2.dll\t1000\t\t\t8192\t4\n"
753     "ODBCsetup.dll\todbc\tODBCsetup.dll\t1000\t\t\t8192\t5\n";
754 
755 static const char odbc_feature_dat[] =
756     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
757     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
758     "Feature\tFeature\n"
759     "odbc\t\t\todbc feature\t1\t2\tMSITESTDIR\t0\n";
760 
761 static const char odbc_feature_comp_dat[] =
762     "Feature_\tComponent_\n"
763     "s38\ts72\n"
764     "FeatureComponents\tFeature_\tComponent_\n"
765     "odbc\todbc\n";
766 
767 static const char odbc_component_dat[] =
768     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
769     "s72\tS38\ts72\ti2\tS255\tS72\n"
770     "Component\tComponent\n"
771     "odbc\t{B6F3E4AE-35D1-4B72-9044-989F03E20A43}\tMSITESTDIR\t0\t\tODBCdriver.dll\n";
772 
773 static const char odbc_driver_dat[] =
774     "Driver\tComponent_\tDescription\tFile_\tFile_Setup\n"
775     "s72\ts72\ts255\ts72\tS72\n"
776     "ODBCDriver\tDriver\n"
777     "ODBC test driver\todbc\tODBC test driver\tODBCdriver.dll\t\n"
778     "ODBC test driver2\todbc\tODBC test driver2\tODBCdriver2.dll\tODBCsetup.dll\n";
779 
780 static const char odbc_translator_dat[] =
781     "Translator\tComponent_\tDescription\tFile_\tFile_Setup\n"
782     "s72\ts72\ts255\ts72\tS72\n"
783     "ODBCTranslator\tTranslator\n"
784     "ODBC test translator\todbc\tODBC test translator\tODBCtranslator.dll\t\n"
785     "ODBC test translator2\todbc\tODBC test translator2\tODBCtranslator2.dll\tODBCsetup.dll\n";
786 
787 static const char odbc_datasource_dat[] =
788     "DataSource\tComponent_\tDescription\tDriverDescription\tRegistration\n"
789     "s72\ts72\ts255\ts255\ti2\n"
790     "ODBCDataSource\tDataSource\n"
791     "ODBC data source\todbc\tODBC data source\tODBC driver\t0\n";
792 
793 static const char odbc_install_exec_seq_dat[] =
794     "Action\tCondition\tSequence\n"
795     "s72\tS255\tI2\n"
796     "InstallExecuteSequence\tAction\n"
797     "LaunchConditions\t\t100\n"
798     "CostInitialize\t\t800\n"
799     "FileCost\t\t900\n"
800     "CostFinalize\t\t1000\n"
801     "InstallValidate\t\t1400\n"
802     "InstallInitialize\t\t1500\n"
803     "ProcessComponents\t\t1600\n"
804     "InstallODBC\t\t3000\n"
805     "RemoveODBC\t\t3100\n"
806     "RemoveFiles\t\t3900\n"
807     "InstallFiles\t\t4000\n"
808     "RegisterProduct\t\t5000\n"
809     "PublishFeatures\t\t5100\n"
810     "PublishProduct\t\t5200\n"
811     "InstallFinalize\t\t6000\n";
812 
813 static const char odbc_media_dat[] =
814     "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
815     "i2\ti4\tL64\tS255\tS32\tS72\n"
816     "Media\tDiskId\n"
817     "1\t5\t\t\tDISK1\t\n";
818 
819 static const char tl_file_dat[] =
820     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
821     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
822     "File\tFile\n"
823     "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n";
824 
825 static const char tl_feature_dat[] =
826     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
827     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
828     "Feature\tFeature\n"
829     "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n";
830 
831 static const char tl_feature_comp_dat[] =
832     "Feature_\tComponent_\n"
833     "s38\ts72\n"
834     "FeatureComponents\tFeature_\tComponent_\n"
835     "typelib\ttypelib\n";
836 
837 static const char tl_component_dat[] =
838     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
839     "s72\tS38\ts72\ti2\tS255\tS72\n"
840     "Component\tComponent\n"
841     "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n";
842 
843 static const char tl_typelib_dat[] =
844     "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n"
845     "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n"
846     "TypeLib\tLibID\tLanguage\tComponent_\n"
847     "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n";
848 
849 static const char tl_install_exec_seq_dat[] =
850     "Action\tCondition\tSequence\n"
851     "s72\tS255\tI2\n"
852     "InstallExecuteSequence\tAction\n"
853     "LaunchConditions\t\t100\n"
854     "CostInitialize\t\t800\n"
855     "FileCost\t\t900\n"
856     "CostFinalize\t\t1000\n"
857     "InstallValidate\t\t1400\n"
858     "InstallInitialize\t\t1500\n"
859     "ProcessComponents\t\t1600\n"
860     "RemoveFiles\t\t1700\n"
861     "InstallFiles\t\t2000\n"
862     "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n"
863     "UnregisterTypeLibraries\t\t3100\n"
864     "RegisterProduct\t\t5100\n"
865     "PublishFeatures\t\t5200\n"
866     "PublishProduct\t\t5300\n"
867     "InstallFinalize\t\t6000\n";
868 
869 static const char crs_file_dat[] =
870     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
871     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
872     "File\tFile\n"
873     "target.txt\tshortcut\ttarget.txt\t1000\t\t\t8192\t1\n";
874 
875 static const char crs_feature_dat[] =
876     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
877     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
878     "Feature\tFeature\n"
879     "shortcut\t\t\tshortcut feature\t1\t2\tMSITESTDIR\t0\n";
880 
881 static const char crs_feature_comp_dat[] =
882     "Feature_\tComponent_\n"
883     "s38\ts72\n"
884     "FeatureComponents\tFeature_\tComponent_\n"
885     "shortcut\tshortcut\n";
886 
887 static const char crs_component_dat[] =
888     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
889     "s72\tS38\ts72\ti2\tS255\tS72\n"
890     "Component\tComponent\n"
891     "shortcut\t{5D20E3C6-7206-498F-AC28-87AF2F9AD4CC}\tMSITESTDIR\t0\t\ttarget.txt\n";
892 
893 static const char crs_shortcut_dat[] =
894     "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
895     "s72\ts72\tl128\ts72\ts72\tL255\tL255\tI2\tS72\tI2\tI2\tS72\n"
896     "Shortcut\tShortcut\n"
897     "shortcut\tMSITESTDIR\tshortcut\tshortcut\t[MSITESTDIR]target.txt\t\t\t\t\t\t\t\n";
898 
899 static const char crs_install_exec_seq_dat[] =
900     "Action\tCondition\tSequence\n"
901     "s72\tS255\tI2\n"
902     "InstallExecuteSequence\tAction\n"
903     "LaunchConditions\t\t100\n"
904     "CostInitialize\t\t800\n"
905     "FileCost\t\t900\n"
906     "CostFinalize\t\t1000\n"
907     "InstallValidate\t\t1400\n"
908     "InstallInitialize\t\t1500\n"
909     "ProcessComponents\t\t1600\n"
910     "RemoveFiles\t\t1700\n"
911     "InstallFiles\t\t2000\n"
912     "RemoveShortcuts\t\t3000\n"
913     "CreateShortcuts\t\t3100\n"
914     "RegisterProduct\t\t5000\n"
915     "PublishFeatures\t\t5100\n"
916     "PublishProduct\t\t5200\n"
917     "InstallFinalize\t\t6000\n";
918 
919 static const char pub_file_dat[] =
920     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
921     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
922     "File\tFile\n"
923     "english.txt\tpublish\tenglish.txt\t1000\t\t\t8192\t1\n";
924 
925 static const char pub_feature_dat[] =
926     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
927     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
928     "Feature\tFeature\n"
929     "publish\t\t\tpublish feature\t1\t2\tMSITESTDIR\t0\n";
930 
931 static const char pub_feature_comp_dat[] =
932     "Feature_\tComponent_\n"
933     "s38\ts72\n"
934     "FeatureComponents\tFeature_\tComponent_\n"
935     "publish\tpublish\n";
936 
937 static const char pub_component_dat[] =
938     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
939     "s72\tS38\ts72\ti2\tS255\tS72\n"
940     "Component\tComponent\n"
941     "publish\t{B4EA0ACF-6238-426E-9C6D-7869F0F9C768}\tMSITESTDIR\t0\t\tenglish.txt\n";
942 
943 static const char pub_publish_component_dat[] =
944     "ComponentId\tQualifier\tComponent_\tAppData\tFeature_\n"
945     "s38\ts255\ts72\tL255\ts38\n"
946     "PublishComponent\tComponentId\tQualifier\tComponent_\n"
947     "{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}\tenglish.txt\tpublish\t\tpublish\n";
948 
949 static const char pub_install_exec_seq_dat[] =
950     "Action\tCondition\tSequence\n"
951     "s72\tS255\tI2\n"
952     "InstallExecuteSequence\tAction\n"
953     "LaunchConditions\t\t100\n"
954     "CostInitialize\t\t800\n"
955     "FileCost\t\t900\n"
956     "CostFinalize\t\t1000\n"
957     "InstallValidate\t\t1400\n"
958     "InstallInitialize\t\t1500\n"
959     "ProcessComponents\t\t1600\n"
960     "RemoveFiles\t\t1700\n"
961     "InstallFiles\t\t2000\n"
962     "PublishComponents\t\t3000\n"
963     "UnpublishComponents\t\t3100\n"
964     "RegisterProduct\t\t5000\n"
965     "PublishFeatures\t\t5100\n"
966     "PublishProduct\t\t5200\n"
967     "InstallFinalize\t\t6000\n";
968 
969 static const char rd_file_dat[] =
970     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
971     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
972     "File\tFile\n"
973     "original.txt\tduplicate\toriginal.txt\t1000\t\t\t8192\t1\n"
974     "original2.txt\tduplicate\toriginal2.txt\t1000\t\t\t8192\t2\n"
975     "original3.txt\tduplicate2\toriginal3.txt\t1000\t\t\t8192\t3\n";
976 
977 static const char rd_feature_dat[] =
978     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
979     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
980     "Feature\tFeature\n"
981     "duplicate\t\t\tduplicate feature\t1\t2\tMSITESTDIR\t0\n";
982 
983 static const char rd_feature_comp_dat[] =
984     "Feature_\tComponent_\n"
985     "s38\ts72\n"
986     "FeatureComponents\tFeature_\tComponent_\n"
987     "duplicate\tduplicate\n";
988 
989 static const char rd_component_dat[] =
990     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
991     "s72\tS38\ts72\ti2\tS255\tS72\n"
992     "Component\tComponent\n"
993     "duplicate\t{EB45D06A-ADFE-44E3-8D41-B7DE150E41AD}\tMSITESTDIR\t0\t\toriginal.txt\n"
994     "duplicate2\t{B8BA60E0-B2E9-488E-9D0E-E60F25F04F97}\tMSITESTDIR\t0\tDUPLICATE2=1\toriginal3.txt\n";
995 
996 static const char rd_duplicate_file_dat[] =
997     "FileKey\tComponent_\tFile_\tDestName\tDestFolder\n"
998     "s72\ts72\ts72\tS255\tS72\n"
999     "DuplicateFile\tFileKey\n"
1000     "duplicate\tduplicate\toriginal.txt\tduplicate.txt\t\n"
1001     "duplicate2\tduplicate\toriginal2.txt\t\tMSITESTDIR\n"
1002     "duplicate3\tduplicate2\toriginal3.txt\tduplicate2.txt\t\n";
1003 
1004 static const char rd_install_exec_seq_dat[] =
1005     "Action\tCondition\tSequence\n"
1006     "s72\tS255\tI2\n"
1007     "InstallExecuteSequence\tAction\n"
1008     "LaunchConditions\t\t100\n"
1009     "CostInitialize\t\t800\n"
1010     "FileCost\t\t900\n"
1011     "CostFinalize\t\t1000\n"
1012     "InstallValidate\t\t1400\n"
1013     "InstallInitialize\t\t1500\n"
1014     "ProcessComponents\t\t1600\n"
1015     "RemoveDuplicateFiles\t\t1900\n"
1016     "InstallFiles\t\t2000\n"
1017     "DuplicateFiles\t\t2100\n"
1018     "RegisterProduct\t\t5000\n"
1019     "PublishFeatures\t\t5100\n"
1020     "PublishProduct\t\t5200\n"
1021     "InstallFinalize\t\t6000\n";
1022 
1023 static const char rrv_file_dat[] =
1024     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1025     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1026     "File\tFile\n"
1027     "registry.txt\tregistry\tregistry.txt\t1000\t\t\t8192\t1\n";
1028 
1029 static const char rrv_feature_dat[] =
1030     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1031     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1032     "Feature\tFeature\n"
1033     "registry\t\t\tregistry feature\t1\t2\tMSITESTDIR\t0\n";
1034 
1035 static const char rrv_feature_comp_dat[] =
1036     "Feature_\tComponent_\n"
1037     "s38\ts72\n"
1038     "FeatureComponents\tFeature_\tComponent_\n"
1039     "registry\tregistry\n";
1040 
1041 static const char rrv_component_dat[] =
1042     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1043     "s72\tS38\ts72\ti2\tS255\tS72\n"
1044     "Component\tComponent\n"
1045     "registry\t{DA97585B-962D-45EB-AD32-DA15E60CA9EE}\tMSITESTDIR\t0\t\tregistry.txt\n";
1046 
1047 static const char rrv_registry_dat[] =
1048     "Registry\tRoot\tKey\tName\tValue\tComponent_\n"
1049     "s72\ti2\tl255\tL255\tL0\ts72\n"
1050     "Registry\tRegistry\n"
1051     "reg1\t2\tSOFTWARE\\Wine\\keyA\t\tA\tregistry\n"
1052     "reg2\t2\tSOFTWARE\\Wine\\keyA\tvalueA\tA\tregistry\n"
1053     "reg3\t2\tSOFTWARE\\Wine\\key1\t-\t\tregistry\n";
1054 
1055 static const char rrv_remove_registry_dat[] =
1056     "RemoveRegistry\tRoot\tKey\tName\tComponent_\n"
1057     "s72\ti2\tl255\tL255\ts72\n"
1058     "RemoveRegistry\tRemoveRegistry\n"
1059     "reg1\t2\tSOFTWARE\\Wine\\keyB\t\tregistry\n"
1060     "reg2\t2\tSOFTWARE\\Wine\\keyB\tValueB\tregistry\n"
1061     "reg3\t2\tSOFTWARE\\Wine\\key2\t-\tregistry\n";
1062 
1063 static const char rrv_install_exec_seq_dat[] =
1064     "Action\tCondition\tSequence\n"
1065     "s72\tS255\tI2\n"
1066     "InstallExecuteSequence\tAction\n"
1067     "LaunchConditions\t\t100\n"
1068     "CostInitialize\t\t800\n"
1069     "FileCost\t\t900\n"
1070     "CostFinalize\t\t1000\n"
1071     "InstallValidate\t\t1400\n"
1072     "InstallInitialize\t\t1500\n"
1073     "ProcessComponents\t\t1600\n"
1074     "RemoveFiles\t\t1700\n"
1075     "InstallFiles\t\t2000\n"
1076     "RemoveRegistryValues\t\t3000\n"
1077     "RegisterProduct\t\t5000\n"
1078     "PublishFeatures\t\t5100\n"
1079     "PublishProduct\t\t5200\n"
1080     "InstallFinalize\t\t6000\n";
1081 
1082 static const char frp_file_dat[] =
1083     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1084     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1085     "File\tFile\n"
1086     "product.txt\tproduct\tproduct.txt\t1000\t\t\t8192\t1\n";
1087 
1088 static const char frp_feature_dat[] =
1089     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1090     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1091     "Feature\tFeature\n"
1092     "product\t\t\tproduct feature\t1\t2\tMSITESTDIR\t0\n";
1093 
1094 static const char frp_feature_comp_dat[] =
1095     "Feature_\tComponent_\n"
1096     "s38\ts72\n"
1097     "FeatureComponents\tFeature_\tComponent_\n"
1098     "product\tproduct\n";
1099 
1100 static const char frp_component_dat[] =
1101     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1102     "s72\tS38\ts72\ti2\tS255\tS72\n"
1103     "Component\tComponent\n"
1104     "product\t{44725EE0-EEA8-40BD-8162-A48224A2FEA1}\tMSITESTDIR\t0\t\tproduct.txt\n";
1105 
1106 static const char frp_custom_action_dat[] =
1107     "Action\tType\tSource\tTarget\tISComments\n"
1108     "s72\ti2\tS64\tS0\tS255\n"
1109     "CustomAction\tAction\n"
1110     "TestProp\t19\t\t\tPROP set\n";
1111 
1112 static const char frp_upgrade_dat[] =
1113     "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"
1114     "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"
1115     "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"
1116     "{4C0EAA15-0264-4E5A-8758-609EF142B92D}\t1.1.1\t2.2.2\t\t768\t\tPROP\n";
1117 
1118 static const char frp_install_exec_seq_dat[] =
1119     "Action\tCondition\tSequence\n"
1120     "s72\tS255\tI2\n"
1121     "InstallExecuteSequence\tAction\n"
1122     "FindRelatedProducts\t\t50\n"
1123     "TestProp\tPROP AND NOT REMOVE\t51\n"
1124     "LaunchConditions\t\t100\n"
1125     "CostInitialize\t\t800\n"
1126     "FileCost\t\t900\n"
1127     "CostFinalize\t\t1000\n"
1128     "InstallValidate\t\t1400\n"
1129     "InstallInitialize\t\t1500\n"
1130     "ProcessComponents\t\t1600\n"
1131     "RemoveFiles\t\t1700\n"
1132     "InstallFiles\t\t2000\n"
1133     "RegisterProduct\t\t5000\n"
1134     "PublishFeatures\t\t5100\n"
1135     "PublishProduct\t\t5200\n"
1136     "InstallFinalize\t\t6000\n";
1137 
1138 static const char riv_file_dat[] =
1139     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1140     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1141     "File\tFile\n"
1142     "inifile.txt\tinifile\tinifile.txt\t1000\t\t\t8192\t1\n";
1143 
1144 static const char riv_feature_dat[] =
1145     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1146     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1147     "Feature\tFeature\n"
1148     "inifile\t\t\tinifile feature\t1\t2\tMSITESTDIR\t0\n";
1149 
1150 static const char riv_feature_comp_dat[] =
1151     "Feature_\tComponent_\n"
1152     "s38\ts72\n"
1153     "FeatureComponents\tFeature_\tComponent_\n"
1154     "inifile\tinifile\n";
1155 
1156 static const char riv_component_dat[] =
1157     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1158     "s72\tS38\ts72\ti2\tS255\tS72\n"
1159     "Component\tComponent\n"
1160     "inifile\t{A0F15705-4F57-4437-88C4-6C8B37ACC6DE}\tMSITESTDIR\t0\t\tinifile.txt\n";
1161 
1162 static const char riv_ini_file_dat[] =
1163     "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1164     "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n"
1165     "IniFile\tIniFile\n"
1166     "inifile1\ttest.ini\tMSITESTDIR\tsection1\tkey1\tvalue1\t0\tinifile\n";
1167 
1168 static const char riv_remove_ini_file_dat[] =
1169     "RemoveIniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"
1170     "s72\tl255\tS72\tl96\tl128\tL255\ti2\ts72\n"
1171     "RemoveIniFile\tRemoveIniFile\n"
1172     "inifile1\ttest.ini\tMSITESTDIR\tsectionA\tkeyA\tvalueA\t2\tinifile\n";
1173 
1174 static const char riv_install_exec_seq_dat[] =
1175     "Action\tCondition\tSequence\n"
1176     "s72\tS255\tI2\n"
1177     "InstallExecuteSequence\tAction\n"
1178     "LaunchConditions\t\t100\n"
1179     "CostInitialize\t\t800\n"
1180     "FileCost\t\t900\n"
1181     "CostFinalize\t\t1000\n"
1182     "InstallValidate\t\t1400\n"
1183     "InstallInitialize\t\t1500\n"
1184     "ProcessComponents\t\t1600\n"
1185     "RemoveFiles\t\t1700\n"
1186     "InstallFiles\t\t2000\n"
1187     "RemoveIniValues\t\t3000\n"
1188     "RegisterProduct\t\t5000\n"
1189     "PublishFeatures\t\t5100\n"
1190     "PublishProduct\t\t5200\n"
1191     "InstallFinalize\t\t6000\n";
1192 
1193 static const char res_file_dat[] =
1194     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1195     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1196     "File\tFile\n"
1197     "envvar.txt\tenvvar\tenvvar.txt\t1000\t\t\t8192\t1\n";
1198 
1199 static const char res_feature_dat[] =
1200     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1201     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1202     "Feature\tFeature\n"
1203     "envvar\t\t\tenvvar feature\t1\t2\tMSITESTDIR\t0\n";
1204 
1205 static const char res_feature_comp_dat[] =
1206     "Feature_\tComponent_\n"
1207     "s38\ts72\n"
1208     "FeatureComponents\tFeature_\tComponent_\n"
1209     "envvar\tenvvar\n";
1210 
1211 static const char res_component_dat[] =
1212     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1213     "s72\tS38\ts72\ti2\tS255\tS72\n"
1214     "Component\tComponent\n"
1215     "envvar\t{45EE9AF4-E5D1-445F-8BB7-B22D4EEBD29E}\tMSITESTDIR\t0\t\tenvvar.txt\n";
1216 
1217 static const char res_environment_dat[] =
1218     "Environment\tName\tValue\tComponent_\n"
1219     "s72\tl255\tL255\ts72\n"
1220     "Environment\tEnvironment\n"
1221     "var1\t=-MSITESTVAR1\t1\tenvvar\n"
1222     "var2\t=+-MSITESTVAR2\t1\tenvvar\n"
1223     "var3\t=MSITESTVAR3\t1\tenvvar\n"
1224     "var4\t=-MSITESTVAR4\t\tenvvar\n"
1225     "var5\t=MSITESTVAR5\t\tenvvar\n"
1226     "Var6\t-MSITESTVAR6\t1;[~]\tenvvar\n"
1227     "Var7\t-MSITESTVAR7\t[~];1\tenvvar\n"
1228     "Var8\t-MSITESTVAR8\t1;[~]\tenvvar\n"
1229     "Var9\t-MSITESTVAR9\t[~];1\tenvvar\n"
1230     "Var10\t-MSITESTVAR10\t1\tenvvar\n"
1231     "Var11\t-MSITESTVAR11\t2\tenvvar\n";
1232 
1233 static const char res_install_exec_seq_dat[] =
1234     "Action\tCondition\tSequence\n"
1235     "s72\tS255\tI2\n"
1236     "InstallExecuteSequence\tAction\n"
1237     "LaunchConditions\t\t100\n"
1238     "CostInitialize\t\t800\n"
1239     "FileCost\t\t900\n"
1240     "CostFinalize\t\t1000\n"
1241     "InstallValidate\t\t1400\n"
1242     "InstallInitialize\t\t1500\n"
1243     "ProcessComponents\t\t1600\n"
1244     "RemoveFiles\t\t1700\n"
1245     "InstallFiles\t\t2000\n"
1246     "RemoveEnvironmentStrings\t\t3000\n"
1247     "RegisterProduct\t\t5000\n"
1248     "PublishFeatures\t\t5100\n"
1249     "PublishProduct\t\t5200\n"
1250     "InstallFinalize\t\t6000\n";
1251 
1252 static const char rci_file_dat[] =
1253     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1254     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1255     "File\tFile\n"
1256     "class.txt\tclass\tclass.txt\t1000\t\t\t8192\t1\n";
1257 
1258 static const char rci_feature_dat[] =
1259     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1260     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1261     "Feature\tFeature\n"
1262     "class\t\t\tclass feature\t1\t2\tMSITESTDIR\t0\n";
1263 
1264 static const char rci_feature_comp_dat[] =
1265     "Feature_\tComponent_\n"
1266     "s38\ts72\n"
1267     "FeatureComponents\tFeature_\tComponent_\n"
1268     "class\tclass\n";
1269 
1270 static const char rci_component_dat[] =
1271     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1272     "s72\tS38\ts72\ti2\tS255\tS72\n"
1273     "Component\tComponent\n"
1274     "class\t{89A98345-F8A1-422E-A48B-0250B5809F2D}\tMSITESTDIR\t0\t\tclass.txt\n";
1275 
1276 static const char rci_appid_dat[] =
1277     "AppId\tRemoteServerName\tLocalService\tServiceParameters\tDllSurrogate\tActivateAtStorage\tRunAsInteractiveUser\n"
1278     "s38\tS255\tS255\tS255\tS255\tI2\tI2\n"
1279     "AppId\tAppId\n"
1280     "{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\t\t\t\t\t\t\n";
1281 
1282 static const char rci_class_dat[] =
1283     "CLSID\tContext\tComponent_\tProgId_Default\tDescription\tAppId_\tFileTypeMask\tIcon_\tIconIndex\tDefInprocHandler\tArgument\tFeature_\tAttributes\n"
1284     "s38\ts32\ts72\tS255\tL255\tS38\tS255\tS72\tI2\tS32\tS255\ts38\tI2\n"
1285     "Class\tCLSID\tContext\tComponent_\n"
1286     "{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tLocalServer\tclass\t\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tclass\t\n";
1287 
1288 static const char rci_install_exec_seq_dat[] =
1289     "Action\tCondition\tSequence\n"
1290     "s72\tS255\tI2\n"
1291     "InstallExecuteSequence\tAction\n"
1292     "LaunchConditions\t\t100\n"
1293     "CostInitialize\t\t800\n"
1294     "FileCost\t\t900\n"
1295     "CostFinalize\t\t1000\n"
1296     "InstallValidate\t\t1400\n"
1297     "InstallInitialize\t\t1500\n"
1298     "ProcessComponents\t\t1600\n"
1299     "RemoveFiles\t\t1700\n"
1300     "InstallFiles\t\t2000\n"
1301     "UnregisterClassInfo\t\t3000\n"
1302     "RegisterClassInfo\t\t4000\n"
1303     "RegisterProduct\t\t5000\n"
1304     "PublishFeatures\t\t5100\n"
1305     "PublishProduct\t\t5200\n"
1306     "InstallFinalize\t\t6000\n";
1307 
1308 static const char rei_file_dat[] =
1309     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1310     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1311     "File\tFile\n"
1312     "extension.txt\textension\textension.txt\t1000\t\t\t8192\t1\n";
1313 
1314 static const char rei_feature_dat[] =
1315     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1316     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1317     "Feature\tFeature\n"
1318     "extension\t\t\textension feature\t1\t2\tMSITESTDIR\t0\n";
1319 
1320 static const char rei_feature_comp_dat[] =
1321     "Feature_\tComponent_\n"
1322     "s38\ts72\n"
1323     "FeatureComponents\tFeature_\tComponent_\n"
1324     "extension\textension\n";
1325 
1326 static const char rei_component_dat[] =
1327     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1328     "s72\tS38\ts72\ti2\tS255\tS72\n"
1329     "Component\tComponent\n"
1330     "extension\t{9A3060D4-60BA-4A82-AB55-9FB148AD013C}\tMSITESTDIR\t0\t\textension.txt\n";
1331 
1332 static const char rei_extension_dat[] =
1333     "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1334     "s255\ts72\tS255\tS64\ts38\n"
1335     "Extension\tExtension\tComponent_\n"
1336     "extension\textension\tProg.Id.1\t\textension\n";
1337 
1338 static const char rei_verb_dat[] =
1339     "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1340     "s255\ts32\tI2\tL255\tL255\n"
1341     "Verb\tExtension_\tVerb\n"
1342     "extension\tOpen\t1\t&Open\t/argument\n";
1343 
1344 static const char rei_progid_dat[] =
1345     "ProgId\tProgId_Parent\tClass_\tDescription\tIcon_\tIconIndex\n"
1346     "s255\tS255\tS38\tL255\tS72\tI2\n"
1347     "ProgId\tProgId\n"
1348     "Prog.Id.1\t\t\tdescription\t\t\n";
1349 
1350 static const char rei_install_exec_seq_dat[] =
1351     "Action\tCondition\tSequence\n"
1352     "s72\tS255\tI2\n"
1353     "InstallExecuteSequence\tAction\n"
1354     "LaunchConditions\t\t100\n"
1355     "CostInitialize\t\t800\n"
1356     "FileCost\t\t900\n"
1357     "CostFinalize\t\t1000\n"
1358     "InstallValidate\t\t1400\n"
1359     "InstallInitialize\t\t1500\n"
1360     "ProcessComponents\t\t1600\n"
1361     "RemoveFiles\t\t1700\n"
1362     "InstallFiles\t\t2000\n"
1363     "UnregisterExtensionInfo\t\t3000\n"
1364     "RegisterExtensionInfo\t\t4000\n"
1365     "RegisterProduct\t\t5000\n"
1366     "PublishFeatures\t\t5100\n"
1367     "PublishProduct\t\t5200\n"
1368     "InstallFinalize\t\t6000\n";
1369 
1370 static const char rpi_file_dat[] =
1371     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1372     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1373     "File\tFile\n"
1374     "progid.txt\tprogid\tprogid.txt\t1000\t\t\t8192\t1\n";
1375 
1376 static const char rpi_feature_dat[] =
1377     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1378     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1379     "Feature\tFeature\n"
1380     "progid\t\t\tprogid feature\t1\t2\tMSITESTDIR\t0\n";
1381 
1382 static const char rpi_feature_comp_dat[] =
1383     "Feature_\tComponent_\n"
1384     "s38\ts72\n"
1385     "FeatureComponents\tFeature_\tComponent_\n"
1386     "progid\tprogid\n";
1387 
1388 static const char rpi_component_dat[] =
1389     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1390     "s72\tS38\ts72\ti2\tS255\tS72\n"
1391     "Component\tComponent\n"
1392     "progid\t{89A98345-F8A1-422E-A48B-0250B5809F2D}\tMSITESTDIR\t0\t\tprogid.txt\n";
1393 
1394 static const char rpi_appid_dat[] =
1395     "AppId\tRemoteServerName\tLocalService\tServiceParameters\tDllSurrogate\tActivateAtStorage\tRunAsInteractiveUser\n"
1396     "s38\tS255\tS255\tS255\tS255\tI2\tI2\n"
1397     "AppId\tAppId\n"
1398     "{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\t\t\t\t\t\t\n";
1399 
1400 static const char rpi_class_dat[] =
1401     "CLSID\tContext\tComponent_\tProgId_Default\tDescription\tAppId_\tFileTypeMask\tIcon_\tIconIndex\tDefInprocHandler\tArgument\tFeature_\tAttributes\n"
1402     "s38\ts32\ts72\tS255\tL255\tS38\tS255\tS72\tI2\tS32\tS255\ts38\tI2\n"
1403     "Class\tCLSID\tContext\tComponent_\n"
1404     "{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tLocalServer\tprogid\tWinetest.Class.1\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tprogid\t\n"
1405     "{904E6BC9-F57F-4412-B460-D40DE2F256E2}\tLocalServer\tprogid\tWinetest.VerClass\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tprogid\t\n"
1406     "{57C413FB-CA02-498A-81F6-7E769BDB7C97}\tLocalServer\tprogid\t\tdescription\t{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}\tmask1;mask2\t\t\t2\t\tprogid\t\n";
1407 
1408 static const char rpi_extension_dat[] =
1409     "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1410     "s255\ts72\tS255\tS64\ts38\n"
1411     "Extension\tExtension\tComponent_\n"
1412     "winetest\tprogid\tWinetest.Extension\t\tprogid\n";
1413 
1414 static const char rpi_verb_dat[] =
1415     "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1416     "s255\ts32\tI2\tL255\tL255\n"
1417     "Verb\tExtension_\tVerb\n"
1418     "winetest\tOpen\t1\t&Open\t/argument\n";
1419 
1420 static const char rpi_progid_dat[] =
1421     "ProgId\tProgId_Parent\tClass_\tDescription\tIcon_\tIconIndex\n"
1422     "s255\tS255\tS38\tL255\tS72\tI2\n"
1423     "ProgId\tProgId\n"
1424     "Winetest.Class.1\t\t{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tdescription\t\t\n"
1425     "Winetest.Class\tWinetest.Class.1\t\tdescription\t\t\n"
1426     "Winetest.Class.2\t\t{110913E7-86D1-4BF3-9922-BA103FCDDDFA}\tdescription\t\t\n"
1427     "Winetest.VerClass.1\t\t{904E6BC9-F57F-4412-B460-D40DE2F256E2}\tdescription\t\t\n"
1428     "Winetest.VerClass\tWinetest.VerClass.1\t\tdescription\t\t\n"
1429     "Winetest.NoProgIdClass.1\t\t{57C413FB-CA02-498A-81F6-7E769BDB7C97}\tdescription\t\t\n"
1430     "Winetest.NoProgIdClass\tWinetest.NoProgIdClass.1\t\tdescription\t\t\n"
1431     "Winetest.Orphaned\t\t\tdescription\t\t\n"
1432     "Winetest.Orphaned2\t\t\tdescription\t\t\n"
1433     "Winetest.Extension\t\t\tdescription\t\t\n";
1434 
1435 static const char rpi_install_exec_seq_dat[] =
1436     "Action\tCondition\tSequence\n"
1437     "s72\tS255\tI2\n"
1438     "InstallExecuteSequence\tAction\n"
1439     "LaunchConditions\t\t100\n"
1440     "CostInitialize\t\t800\n"
1441     "FileCost\t\t900\n"
1442     "CostFinalize\t\t1000\n"
1443     "InstallValidate\t\t1400\n"
1444     "InstallInitialize\t\t1500\n"
1445     "ProcessComponents\t\t1600\n"
1446     "RemoveFiles\t\t1700\n"
1447     "UnregisterClassInfo\t\t3000\n"
1448     "UnregisterExtensionInfo\t\t3200\n"
1449     "UnregisterProgIdInfo\t\t3400\n"
1450     "InstallFiles\t\t3600\n"
1451     "RegisterClassInfo\t\t4000\n"
1452     "RegisterExtensionInfo\t\t4200\n"
1453     "RegisterProgIdInfo\t\t4400\n"
1454     "RegisterProduct\t\t5000\n"
1455     "PublishFeatures\t\t5100\n"
1456     "PublishProduct\t\t5200\n"
1457     "InstallFinalize\t\t6000\n";
1458 
1459 static const char rmi_file_dat[] =
1460     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1461     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1462     "File\tFile\n"
1463     "mime.txt\tmime\tmime.txt\t1000\t\t\t8192\t1\n";
1464 
1465 static const char rmi_feature_dat[] =
1466     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1467     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1468     "Feature\tFeature\n"
1469     "mime\t\t\tmime feature\t1\t2\tMSITESTDIR\t0\n";
1470 
1471 static const char rmi_feature_comp_dat[] =
1472     "Feature_\tComponent_\n"
1473     "s38\ts72\n"
1474     "FeatureComponents\tFeature_\tComponent_\n"
1475     "mime\tmime\n";
1476 
1477 static const char rmi_component_dat[] =
1478     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1479     "s72\tS38\ts72\ti2\tS255\tS72\n"
1480     "Component\tComponent\n"
1481     "mime\t{A1D630CE-13A7-4882-AFDD-148E2BBAFC6D}\tMSITESTDIR\t0\t\tmime.txt\n";
1482 
1483 static const char rmi_extension_dat[] =
1484     "Extension\tComponent_\tProgId_\tMIME_\tFeature_\n"
1485     "s255\ts72\tS255\tS64\ts38\n"
1486     "Extension\tExtension\tComponent_\n"
1487     "mime\tmime\t\tmime/type\tmime\n";
1488 
1489 static const char rmi_verb_dat[] =
1490     "Extension_\tVerb\tSequence\tCommand\tArgument\n"
1491     "s255\ts32\tI2\tL255\tL255\n"
1492     "Verb\tExtension_\tVerb\n"
1493     "mime\tOpen\t1\t&Open\t/argument\n";
1494 
1495 static const char rmi_mime_dat[] =
1496     "ContentType\tExtension_\tCLSID\n"
1497     "s64\ts255\tS38\n"
1498     "MIME\tContentType\n"
1499     "mime/type\tmime\t\n";
1500 
1501 static const char rmi_install_exec_seq_dat[] =
1502     "Action\tCondition\tSequence\n"
1503     "s72\tS255\tI2\n"
1504     "InstallExecuteSequence\tAction\n"
1505     "LaunchConditions\t\t100\n"
1506     "CostInitialize\t\t800\n"
1507     "FileCost\t\t900\n"
1508     "CostFinalize\t\t1000\n"
1509     "InstallValidate\t\t1400\n"
1510     "InstallInitialize\t\t1500\n"
1511     "ProcessComponents\t\t1600\n"
1512     "RemoveFiles\t\t1700\n"
1513     "InstallFiles\t\t2000\n"
1514     "UnregisterExtensionInfo\t\t3000\n"
1515     "UnregisterMIMEInfo\t\t3500\n"
1516     "RegisterExtensionInfo\t\t4000\n"
1517     "RegisterMIMEInfo\t\t4500\n"
1518     "RegisterProduct\t\t5000\n"
1519     "PublishFeatures\t\t5100\n"
1520     "PublishProduct\t\t5200\n"
1521     "InstallFinalize\t\t6000\n";
1522 
1523 static const char pa_file_dat[] =
1524     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1525     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1526     "File\tFile\n"
1527     "win32.txt\twin32\twin32.txt\t1000\t\t\t8192\t1\n"
1528     "manifest.txt\twin32\tmanifest.txt\t1000\t\t\t8192\t1\n"
1529     "win32_local.txt\twin32_local\twin32_local.txt\t1000\t\t\t8192\t1\n"
1530     "manifest_local.txt\twin32_local\tmanifest_local.txt\t1000\t\t\t8192\t1\n"
1531     "dotnet.txt\tdotnet\tdotnet.txt\t1000\t\t\t8192\t1\n"
1532     "dotnet_local.txt\tdotnet_local\tdotnet_local.txt\t1000\t\t\t8192\t1\n"
1533     "application_win32.txt\twin32_local\tapplication_win32.txt\t1000\t\t\t8192\t1\n"
1534     "application_dotnet.txt\tdotnet_local\tapplication_dotnet.txt\t1000\t\t\t8192\t1\n";
1535 
1536 static const char pa_feature_dat[] =
1537     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1538     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1539     "Feature\tFeature\n"
1540     "assembly\t\t\tassembly feature\t1\t2\tMSITESTDIR\t0\n";
1541 
1542 static const char pa_feature_comp_dat[] =
1543     "Feature_\tComponent_\n"
1544     "s38\ts72\n"
1545     "FeatureComponents\tFeature_\tComponent_\n"
1546     "assembly\twin32\n"
1547     "assembly\twin32_local\n"
1548     "assembly\tdotnet\n"
1549     "assembly\tdotnet_local\n";
1550 
1551 static const char pa_component_dat[] =
1552     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1553     "s72\tS38\ts72\ti2\tS255\tS72\n"
1554     "Component\tComponent\n"
1555     "win32\t{F515549E-7E61-425D-AAC1-9BEF2E066D06}\tMSITESTDIR\t0\t\twin32.txt\n"
1556     "win32_local\t{D34D3FBA-6789-4E57-AD1A-1281297DC201}\tMSITESTDIR\t0\t\twin32_local.txt\n"
1557     "dotnet\t{8943164F-2B31-4C09-A894-493A8CBDE0A4}\tMSITESTDIR\t0\t\tdotnet.txt\n"
1558     "dotnet_local\t{4E8567E8-8EAE-4E36-90F1-B99D33C663F8}\tMSITESTDIR\t0\t\tdotnet_local.txt\n";
1559 
1560 static const char pa_msi_assembly_dat[] =
1561     "Component_\tFeature_\tFile_Manifest\tFile_Application\tAttributes\n"
1562     "s72\ts38\tS72\tS72\tI2\n"
1563     "MsiAssembly\tComponent_\n"
1564     "win32\tassembly\tmanifest.txt\t\t1\n"
1565     "win32_local\tassembly\tmanifest_local.txt\tapplication_win32.txt\t1\n"
1566     "dotnet\tassembly\t\t\t0\n"
1567     "dotnet_local\tassembly\t\tapplication_dotnet.txt\t0\n";
1568 
1569 static const char pa_msi_assembly_name_dat[] =
1570     "Component_\tName\tValue\n"
1571     "s72\ts255\ts255\n"
1572     "MsiAssemblyName\tComponent_\tName\n"
1573     "win32\tName\tWine.Win32.Assembly\n"
1574     "win32\tprocessorArchitecture\tx86\n"
1575     "win32\tpublicKeyToken\tabcdef0123456789\n"
1576     "win32\ttype\twin32\n"
1577     "win32\tversion\t1.0.0.0\n"
1578     "win32_local\tName\tWine.Win32.Local.Assembly\n"
1579     "win32_local\tprocessorArchitecture\tx86\n"
1580     "win32_local\tpublicKeyToken\tabcdef0123456789\n"
1581     "win32_local\ttype\twin32\n"
1582     "win32_local\tversion\t1.0.0.0\n"
1583     "dotnet\tName\tWine.Dotnet.Assembly\n"
1584     "dotnet\tprocessorArchitecture\tMSIL\n"
1585     "dotnet\tpublicKeyToken\tabcdef0123456789\n"
1586     "dotnet\tculture\tneutral\n"
1587     "dotnet\tversion\t1.0.0.0\n"
1588     "dotnet_local\tName\tWine.Dotnet.Local.Assembly\n"
1589     "dotnet_local\tprocessorArchitecture\tMSIL\n"
1590     "dotnet_local\tpublicKeyToken\tabcdef0123456789\n"
1591     "dotnet_local\tculture\tneutral\n"
1592     "dotnet_local\tversion\t1.0.0.0\n";
1593 
1594 static const char pa_install_exec_seq_dat[] =
1595     "Action\tCondition\tSequence\n"
1596     "s72\tS255\tI2\n"
1597     "InstallExecuteSequence\tAction\n"
1598     "LaunchConditions\t\t100\n"
1599     "CostInitialize\t\t800\n"
1600     "FileCost\t\t900\n"
1601     "CostFinalize\t\t1000\n"
1602     "InstallValidate\t\t1400\n"
1603     "InstallInitialize\t\t1500\n"
1604     "ProcessComponents\t\t1600\n"
1605     "MsiPublishAssemblies\t\t3000\n"
1606     "MsiUnpublishAssemblies\t\t4000\n"
1607     "RegisterProduct\t\t5000\n"
1608     "PublishFeatures\t\t5100\n"
1609     "PublishProduct\t\t5200\n"
1610     "InstallFinalize\t\t6000\n";
1611 
1612 static const char rep_file_dat[] =
1613     "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
1614     "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
1615     "File\tFile\n"
1616     "rep.txt\trep\trep.txt\t1000\t\t\t8192\t1\n";
1617 
1618 static const char rep_feature_dat[] =
1619     "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
1620     "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
1621     "Feature\tFeature\n"
1622     "rep\t\t\trep feature\t1\t2\tMSITESTDIR\t0\n";
1623 
1624 static const char rep_feature_comp_dat[] =
1625     "Feature_\tComponent_\n"
1626     "s38\ts72\n"
1627     "FeatureComponents\tFeature_\tComponent_\n"
1628     "rep\trep\n";
1629 
1630 static const char rep_component_dat[] =
1631     "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
1632     "s72\tS38\ts72\ti2\tS255\tS72\n"
1633     "Component\tComponent\n"
1634     "rep\t{A24FAF2A-3B2E-41EF-AA78-331542E1A29D}\tMSITESTDIR\t0\t\trep.txt\n";
1635 
1636 static const char rep_upgrade_dat[] =
1637     "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"
1638     "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"
1639     "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"
1640     "{2967C1CC-34D4-42EE-8D96-CD6836F192BF}\t\t\t\t256\t\tPRODUCT\n";
1641 
1642 static const char rep_property_dat[] =
1643     "Property\tValue\n"
1644     "s72\tl0\n"
1645     "Property\tProperty\n"
1646     "HASUIRUN\t0\n"
1647     "INSTALLLEVEL\t3\n"
1648     "InstallMode\tTypical\n"
1649     "Manufacturer\tWine\n"
1650     "PIDTemplate\t###-#######\n"
1651     "ProductCode\t{1699F0BB-0B61-4A89-AFE4-CFD60DFD76F3}\n"
1652     "ProductLanguage\t1033\n"
1653     "ProductName\tMSITEST\n"
1654     "ProductVersion\t1.1.1\n"
1655     "UpgradeCode\t{2967C1CC-34D4-42EE-8D96-CD6836F192BF}\n"
1656     "PRODUCT\t2F41860D-7B4C-4DA7-BED9-B64F26594C56\n"
1657     "MSIFASTINSTALL\t1\n";
1658 
1659 static const char rep_install_exec_seq_dat[] =
1660     "Action\tCondition\tSequence\n"
1661     "s72\tS255\tI2\n"
1662     "InstallExecuteSequence\tAction\n"
1663     "FindRelatedProducts\t\t100\n"
1664     "CostInitialize\t\t800\n"
1665     "FileCost\t\t900\n"
1666     "CostFinalize\t\t1000\n"
1667     "InstallValidate\t\t1400\n"
1668     "RemoveExistingProducts\t\t1499\n"
1669     "InstallInitialize\t\t1500\n"
1670     "ProcessComponents\t\t1600\n"
1671     "RemoveFiles\t\t1700\n"
1672     "InstallFiles\t\t2000\n"
1673     "UnregisterExtensionInfo\t\t3000\n"
1674     "UnregisterMIMEInfo\t\t3500\n"
1675     "RegisterExtensionInfo\t\t4000\n"
1676     "RegisterMIMEInfo\t\t4500\n"
1677     "RegisterProduct\t\t5000\n"
1678     "PublishFeatures\t\t5100\n"
1679     "PublishProduct\t\t5200\n"
1680     "InstallFinalize\t\t6000\n";
1681 
1682 typedef struct _msi_table
1683 {
1684     const char *filename;
1685     const char *data;
1686     unsigned int size;
1687 } msi_table;
1688 
1689 #define ADD_TABLE(x) {#x".idt", x##_dat, sizeof(x##_dat)}
1690 
1691 static const msi_table env_tables[] =
1692 {
1693     ADD_TABLE(component),
1694     ADD_TABLE(directory),
1695     ADD_TABLE(feature),
1696     ADD_TABLE(feature_comp),
1697     ADD_TABLE(file),
1698     ADD_TABLE(install_exec_seq),
1699     ADD_TABLE(media),
1700     ADD_TABLE(property),
1701     ADD_TABLE(environment)
1702 };
1703 
1704 static const msi_table pp_tables[] =
1705 {
1706     ADD_TABLE(pp_component),
1707     ADD_TABLE(directory),
1708     ADD_TABLE(rof_feature),
1709     ADD_TABLE(rof_feature_comp),
1710     ADD_TABLE(rof_file),
1711     ADD_TABLE(pp_install_exec_seq),
1712     ADD_TABLE(rof_media),
1713     ADD_TABLE(property),
1714 };
1715 
1716 static const msi_table ppc_tables[] =
1717 {
1718     ADD_TABLE(ppc_component),
1719     ADD_TABLE(directory),
1720     ADD_TABLE(rof_feature),
1721     ADD_TABLE(ppc_feature_comp),
1722     ADD_TABLE(ppc_file),
1723     ADD_TABLE(pp_install_exec_seq),
1724     ADD_TABLE(ppc_media),
1725     ADD_TABLE(property),
1726 };
1727 
1728 static const msi_table rem_tables[] =
1729 {
1730     ADD_TABLE(rem_component),
1731     ADD_TABLE(directory),
1732     ADD_TABLE(rof_feature),
1733     ADD_TABLE(rem_feature_comp),
1734     ADD_TABLE(rem_file),
1735     ADD_TABLE(rem_install_exec_seq),
1736     ADD_TABLE(rof_media),
1737     ADD_TABLE(property),
1738     ADD_TABLE(rem_remove_files),
1739 };
1740 
1741 static const msi_table mov_tables[] =
1742 {
1743     ADD_TABLE(cwd_component),
1744     ADD_TABLE(directory),
1745     ADD_TABLE(rof_feature),
1746     ADD_TABLE(ci2_feature_comp),
1747     ADD_TABLE(ci2_file),
1748     ADD_TABLE(install_exec_seq),
1749     ADD_TABLE(rof_media),
1750     ADD_TABLE(property),
1751     ADD_TABLE(mov_move_file),
1752 };
1753 
1754 static const msi_table df_tables[] =
1755 {
1756     ADD_TABLE(rof_component),
1757     ADD_TABLE(df_directory),
1758     ADD_TABLE(rof_feature),
1759     ADD_TABLE(rof_feature_comp),
1760     ADD_TABLE(rof_file),
1761     ADD_TABLE(install_exec_seq),
1762     ADD_TABLE(rof_media),
1763     ADD_TABLE(property),
1764     ADD_TABLE(df_duplicate_file),
1765 };
1766 
1767 static const msi_table wrv_tables[] =
1768 {
1769     ADD_TABLE(wrv_component),
1770     ADD_TABLE(directory),
1771     ADD_TABLE(wrv_feature),
1772     ADD_TABLE(wrv_feature_comp),
1773     ADD_TABLE(ci2_file),
1774     ADD_TABLE(install_exec_seq),
1775     ADD_TABLE(rof_media),
1776     ADD_TABLE(property),
1777     ADD_TABLE(wrv_registry),
1778 };
1779 
1780 static const msi_table cf_tables[] =
1781 {
1782     ADD_TABLE(cf_component),
1783     ADD_TABLE(cf_directory),
1784     ADD_TABLE(cf_feature),
1785     ADD_TABLE(cf_feature_comp),
1786     ADD_TABLE(cf_file),
1787     ADD_TABLE(cf_create_folders),
1788     ADD_TABLE(cf_install_exec_seq),
1789     ADD_TABLE(media),
1790     ADD_TABLE(property)
1791 };
1792 
1793 static const msi_table sss_tables[] =
1794 {
1795     ADD_TABLE(component),
1796     ADD_TABLE(directory),
1797     ADD_TABLE(feature),
1798     ADD_TABLE(feature_comp),
1799     ADD_TABLE(file),
1800     ADD_TABLE(sss_install_exec_seq),
1801     ADD_TABLE(sss_service_control),
1802     ADD_TABLE(media),
1803     ADD_TABLE(property)
1804 };
1805 
1806 static const msi_table sds_tables[] =
1807 {
1808     ADD_TABLE(component),
1809     ADD_TABLE(directory),
1810     ADD_TABLE(feature),
1811     ADD_TABLE(feature_comp),
1812     ADD_TABLE(file),
1813     ADD_TABLE(sds_install_exec_seq),
1814     ADD_TABLE(service_control),
1815     ADD_TABLE(service_install),
1816     ADD_TABLE(media),
1817     ADD_TABLE(property)
1818 };
1819 
1820 static const msi_table sis_tables[] =
1821 {
1822     ADD_TABLE(component),
1823     ADD_TABLE(directory),
1824     ADD_TABLE(feature),
1825     ADD_TABLE(feature_comp),
1826     ADD_TABLE(file),
1827     ADD_TABLE(sds_install_exec_seq),
1828     ADD_TABLE(service_install2),
1829     ADD_TABLE(media),
1830     ADD_TABLE(property)
1831 };
1832 
1833 static const msi_table sr_tables[] =
1834 {
1835     ADD_TABLE(component),
1836     ADD_TABLE(directory),
1837     ADD_TABLE(feature),
1838     ADD_TABLE(feature_comp),
1839     ADD_TABLE(file),
1840     ADD_TABLE(sr_selfreg),
1841     ADD_TABLE(sr_install_exec_seq),
1842     ADD_TABLE(media),
1843     ADD_TABLE(property)
1844 };
1845 
1846 static const msi_table font_tables[] =
1847 {
1848     ADD_TABLE(font_component),
1849     ADD_TABLE(directory),
1850     ADD_TABLE(font_feature),
1851     ADD_TABLE(font_feature_comp),
1852     ADD_TABLE(font_file),
1853     ADD_TABLE(font),
1854     ADD_TABLE(font_install_exec_seq),
1855     ADD_TABLE(font_media),
1856     ADD_TABLE(property)
1857 };
1858 
1859 static const msi_table vp_tables[] =
1860 {
1861     ADD_TABLE(component),
1862     ADD_TABLE(directory),
1863     ADD_TABLE(feature),
1864     ADD_TABLE(feature_comp),
1865     ADD_TABLE(file),
1866     ADD_TABLE(vp_custom_action),
1867     ADD_TABLE(vp_install_exec_seq),
1868     ADD_TABLE(media),
1869     ADD_TABLE(vp_property)
1870 };
1871 
1872 static const msi_table odbc_tables[] =
1873 {
1874     ADD_TABLE(odbc_component),
1875     ADD_TABLE(directory),
1876     ADD_TABLE(odbc_feature),
1877     ADD_TABLE(odbc_feature_comp),
1878     ADD_TABLE(odbc_file),
1879     ADD_TABLE(odbc_driver),
1880     ADD_TABLE(odbc_translator),
1881     ADD_TABLE(odbc_datasource),
1882     ADD_TABLE(odbc_install_exec_seq),
1883     ADD_TABLE(odbc_media),
1884     ADD_TABLE(property)
1885 };
1886 
1887 static const msi_table tl_tables[] =
1888 {
1889     ADD_TABLE(tl_component),
1890     ADD_TABLE(directory),
1891     ADD_TABLE(tl_feature),
1892     ADD_TABLE(tl_feature_comp),
1893     ADD_TABLE(tl_file),
1894     ADD_TABLE(tl_typelib),
1895     ADD_TABLE(tl_install_exec_seq),
1896     ADD_TABLE(media),
1897     ADD_TABLE(property)
1898 };
1899 
1900 static const msi_table crs_tables[] =
1901 {
1902     ADD_TABLE(crs_component),
1903     ADD_TABLE(directory),
1904     ADD_TABLE(crs_feature),
1905     ADD_TABLE(crs_feature_comp),
1906     ADD_TABLE(crs_file),
1907     ADD_TABLE(crs_shortcut),
1908     ADD_TABLE(crs_install_exec_seq),
1909     ADD_TABLE(media),
1910     ADD_TABLE(property)
1911 };
1912 
1913 static const msi_table pub_tables[] =
1914 {
1915     ADD_TABLE(directory),
1916     ADD_TABLE(pub_component),
1917     ADD_TABLE(pub_feature),
1918     ADD_TABLE(pub_feature_comp),
1919     ADD_TABLE(pub_file),
1920     ADD_TABLE(pub_publish_component),
1921     ADD_TABLE(pub_install_exec_seq),
1922     ADD_TABLE(media),
1923     ADD_TABLE(property)
1924 };
1925 
1926 static const msi_table rd_tables[] =
1927 {
1928     ADD_TABLE(directory),
1929     ADD_TABLE(rd_component),
1930     ADD_TABLE(rd_feature),
1931     ADD_TABLE(rd_feature_comp),
1932     ADD_TABLE(rd_file),
1933     ADD_TABLE(rd_duplicate_file),
1934     ADD_TABLE(rd_install_exec_seq),
1935     ADD_TABLE(media),
1936     ADD_TABLE(property)
1937 };
1938 
1939 static const msi_table rrv_tables[] =
1940 {
1941     ADD_TABLE(directory),
1942     ADD_TABLE(rrv_component),
1943     ADD_TABLE(rrv_feature),
1944     ADD_TABLE(rrv_feature_comp),
1945     ADD_TABLE(rrv_file),
1946     ADD_TABLE(rrv_registry),
1947     ADD_TABLE(rrv_remove_registry),
1948     ADD_TABLE(rrv_install_exec_seq),
1949     ADD_TABLE(media),
1950     ADD_TABLE(property)
1951 };
1952 
1953 static const msi_table frp_tables[] =
1954 {
1955     ADD_TABLE(directory),
1956     ADD_TABLE(frp_component),
1957     ADD_TABLE(frp_feature),
1958     ADD_TABLE(frp_feature_comp),
1959     ADD_TABLE(frp_file),
1960     ADD_TABLE(frp_upgrade),
1961     ADD_TABLE(frp_custom_action),
1962     ADD_TABLE(frp_install_exec_seq),
1963     ADD_TABLE(media),
1964     ADD_TABLE(property)
1965 };
1966 
1967 static const msi_table riv_tables[] =
1968 {
1969     ADD_TABLE(directory),
1970     ADD_TABLE(riv_component),
1971     ADD_TABLE(riv_feature),
1972     ADD_TABLE(riv_feature_comp),
1973     ADD_TABLE(riv_file),
1974     ADD_TABLE(riv_ini_file),
1975     ADD_TABLE(riv_remove_ini_file),
1976     ADD_TABLE(riv_install_exec_seq),
1977     ADD_TABLE(media),
1978     ADD_TABLE(property)
1979 };
1980 
1981 static const msi_table res_tables[] =
1982 {
1983     ADD_TABLE(directory),
1984     ADD_TABLE(res_component),
1985     ADD_TABLE(res_feature),
1986     ADD_TABLE(res_feature_comp),
1987     ADD_TABLE(res_file),
1988     ADD_TABLE(res_environment),
1989     ADD_TABLE(res_install_exec_seq),
1990     ADD_TABLE(media),
1991     ADD_TABLE(property)
1992 };
1993 
1994 static const msi_table rci_tables[] =
1995 {
1996     ADD_TABLE(directory),
1997     ADD_TABLE(rci_component),
1998     ADD_TABLE(rci_feature),
1999     ADD_TABLE(rci_feature_comp),
2000     ADD_TABLE(rci_file),
2001     ADD_TABLE(rci_appid),
2002     ADD_TABLE(rci_class),
2003     ADD_TABLE(rci_install_exec_seq),
2004     ADD_TABLE(media),
2005     ADD_TABLE(property)
2006 };
2007 
2008 static const msi_table rei_tables[] =
2009 {
2010     ADD_TABLE(directory),
2011     ADD_TABLE(rei_component),
2012     ADD_TABLE(rei_feature),
2013     ADD_TABLE(rei_feature_comp),
2014     ADD_TABLE(rei_file),
2015     ADD_TABLE(rei_extension),
2016     ADD_TABLE(rei_verb),
2017     ADD_TABLE(rei_progid),
2018     ADD_TABLE(rei_install_exec_seq),
2019     ADD_TABLE(media),
2020     ADD_TABLE(property)
2021 };
2022 
2023 static const msi_table rpi_tables[] =
2024 {
2025     ADD_TABLE(directory),
2026     ADD_TABLE(rpi_component),
2027     ADD_TABLE(rpi_feature),
2028     ADD_TABLE(rpi_feature_comp),
2029     ADD_TABLE(rpi_file),
2030     ADD_TABLE(rpi_appid),
2031     ADD_TABLE(rpi_class),
2032     ADD_TABLE(rpi_extension),
2033     ADD_TABLE(rpi_verb),
2034     ADD_TABLE(rpi_progid),
2035     ADD_TABLE(rpi_install_exec_seq),
2036     ADD_TABLE(media),
2037     ADD_TABLE(property)
2038 };
2039 
2040 static const msi_table rmi_tables[] =
2041 {
2042     ADD_TABLE(directory),
2043     ADD_TABLE(rmi_component),
2044     ADD_TABLE(rmi_feature),
2045     ADD_TABLE(rmi_feature_comp),
2046     ADD_TABLE(rmi_file),
2047     ADD_TABLE(rmi_extension),
2048     ADD_TABLE(rmi_verb),
2049     ADD_TABLE(rmi_mime),
2050     ADD_TABLE(rmi_install_exec_seq),
2051     ADD_TABLE(media),
2052     ADD_TABLE(property)
2053 };
2054 
2055 static const msi_table pa_tables[] =
2056 {
2057     ADD_TABLE(directory),
2058     ADD_TABLE(pa_component),
2059     ADD_TABLE(pa_feature),
2060     ADD_TABLE(pa_feature_comp),
2061     ADD_TABLE(pa_file),
2062     ADD_TABLE(pa_msi_assembly),
2063     ADD_TABLE(pa_msi_assembly_name),
2064     ADD_TABLE(pa_install_exec_seq),
2065     ADD_TABLE(media),
2066     ADD_TABLE(property)
2067 };
2068 
2069 static const msi_table rep_tables[] =
2070 {
2071     ADD_TABLE(directory),
2072     ADD_TABLE(rep_component),
2073     ADD_TABLE(rep_feature),
2074     ADD_TABLE(rep_feature_comp),
2075     ADD_TABLE(rep_file),
2076     ADD_TABLE(rep_upgrade),
2077     ADD_TABLE(rep_property),
2078     ADD_TABLE(rep_install_exec_seq),
2079     ADD_TABLE(media)
2080 };
2081 
2082 /* based on RegDeleteTreeW from dlls/advapi32/registry.c */
2083 static LSTATUS action_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey, REGSAM access)
2084 {
2085     LONG ret;
2086     DWORD dwMaxSubkeyLen, dwMaxValueLen;
2087     DWORD dwMaxLen, dwSize;
2088     char szNameBuf[MAX_PATH], *lpszName = szNameBuf;
2089     HKEY hSubKey = hKey;
2090 
2091     if(lpszSubKey)
2092     {
2093         ret = RegOpenKeyExA(hKey, lpszSubKey, 0, access, &hSubKey);
2094         if (ret) return ret;
2095     }
2096 
2097     ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL,
2098             &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
2099     if (ret) goto cleanup;
2100 
2101     dwMaxSubkeyLen++;
2102     dwMaxValueLen++;
2103     dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
2104     if (dwMaxLen > sizeof(szNameBuf))
2105     {
2106         /* Name too big: alloc a buffer for it */
2107         if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen)))
2108         {
2109             ret = ERROR_NOT_ENOUGH_MEMORY;
2110             goto cleanup;
2111         }
2112     }
2113 
2114     /* Recursively delete all the subkeys */
2115     while (TRUE)
2116     {
2117         dwSize = dwMaxLen;
2118         if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL,
2119                           NULL, NULL, NULL)) break;
2120 
2121         ret = action_RegDeleteTreeA(hSubKey, lpszName, access);
2122         if (ret) goto cleanup;
2123     }
2124 
2125     if (lpszSubKey)
2126     {
2127         if (pRegDeleteKeyExA)
2128             ret = pRegDeleteKeyExA(hKey, lpszSubKey, access, 0);
2129         else
2130             ret = RegDeleteKeyA(hKey, lpszSubKey);
2131     }
2132     else
2133         while (TRUE)
2134         {
2135             dwSize = dwMaxLen;
2136             if (RegEnumValueA(hKey, 0, lpszName, &dwSize,
2137                   NULL, NULL, NULL, NULL)) break;
2138 
2139             ret = RegDeleteValueA(hKey, lpszName);
2140             if (ret) goto cleanup;
2141         }
2142 
2143 cleanup:
2144     if (lpszName != szNameBuf)
2145         HeapFree(GetProcessHeap(), 0, lpszName);
2146     if(lpszSubKey)
2147         RegCloseKey(hSubKey);
2148     return ret;
2149 }
2150 
2151 /* cabinet definitions */
2152 
2153 /* make the max size large so there is only one cab file */
2154 #define MEDIA_SIZE          0x7FFFFFFF
2155 #define FOLDER_THRESHOLD    900000
2156 
2157 /* the FCI callbacks */
2158 
2159 static void * CDECL mem_alloc(ULONG cb)
2160 {
2161     return HeapAlloc(GetProcessHeap(), 0, cb);
2162 }
2163 
2164 static void CDECL mem_free(void *memory)
2165 {
2166     HeapFree(GetProcessHeap(), 0, memory);
2167 }
2168 
2169 static BOOL CDECL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
2170 {
2171     sprintf(pccab->szCab, pv, pccab->iCab);
2172     return TRUE;
2173 }
2174 
2175 static LONG CDECL progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
2176 {
2177     return 0;
2178 }
2179 
2180 static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
2181                              BOOL fContinuation, void *pv)
2182 {
2183     return 0;
2184 }
2185 
2186 static INT_PTR CDECL fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
2187 {
2188     HANDLE handle;
2189     DWORD dwAccess = 0;
2190     DWORD dwShareMode = 0;
2191     DWORD dwCreateDisposition = OPEN_EXISTING;
2192 
2193     dwAccess = GENERIC_READ | GENERIC_WRITE;
2194     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
2195 
2196     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
2197         dwCreateDisposition = OPEN_EXISTING;
2198     else
2199         dwCreateDisposition = CREATE_NEW;
2200 
2201     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
2202                          dwCreateDisposition, 0, NULL);
2203 
2204     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
2205 
2206     return (INT_PTR)handle;
2207 }
2208 
2209 static UINT CDECL fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2210 {
2211     HANDLE handle = (HANDLE)hf;
2212     DWORD dwRead;
2213     BOOL res;
2214 
2215     res = ReadFile(handle, memory, cb, &dwRead, NULL);
2216     ok(res, "Failed to ReadFile\n");
2217 
2218     return dwRead;
2219 }
2220 
2221 static UINT CDECL fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
2222 {
2223     HANDLE handle = (HANDLE)hf;
2224     DWORD dwWritten;
2225     BOOL res;
2226 
2227     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
2228     ok(res, "Failed to WriteFile\n");
2229 
2230     return dwWritten;
2231 }
2232 
2233 static int CDECL fci_close(INT_PTR hf, int *err, void *pv)
2234 {
2235     HANDLE handle = (HANDLE)hf;
2236     ok(CloseHandle(handle), "Failed to CloseHandle\n");
2237 
2238     return 0;
2239 }
2240 
2241 static LONG CDECL fci_seek(INT_PTR hf, LONG dist, int seektype, int *err, void *pv)
2242 {
2243     HANDLE handle = (HANDLE)hf;
2244     DWORD ret;
2245 
2246     ret = SetFilePointer(handle, dist, NULL, seektype);
2247     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
2248 
2249     return ret;
2250 }
2251 
2252 static int CDECL fci_delete(char *pszFile, int *err, void *pv)
2253 {
2254     BOOL ret = DeleteFileA(pszFile);
2255     ok(ret, "Failed to DeleteFile %s\n", pszFile);
2256 
2257     return 0;
2258 }
2259 
2260 static void init_functionpointers(void)
2261 {
2262     HMODULE hmsi = GetModuleHandleA("msi.dll");
2263     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
2264     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
2265 
2266 #define GET_PROC(mod, func) \
2267     p ## func = (void*)GetProcAddress(mod, #func); \
2268     if(!p ## func) \
2269       trace("GetProcAddress(%s) failed\n", #func);
2270 
2271     GET_PROC(hmsi, MsiQueryComponentStateA);
2272     GET_PROC(hmsi, MsiSourceListEnumSourcesA);
2273     GET_PROC(hmsi, MsiSourceListGetInfoA);
2274     GET_PROC(hmsi, MsiGetComponentPathExA);
2275     GET_PROC(hmsi, MsiQueryFeatureStateExA);
2276 
2277     GET_PROC(hadvapi32, CheckTokenMembership);
2278     GET_PROC(hadvapi32, ConvertSidToStringSidA);
2279     GET_PROC(hadvapi32, OpenProcessToken);
2280     GET_PROC(hadvapi32, RegDeleteKeyExA)
2281     GET_PROC(hkernel32, IsWow64Process)
2282 
2283     hsrclient = LoadLibraryA("srclient.dll");
2284     GET_PROC(hsrclient, SRRemoveRestorePoint);
2285     GET_PROC(hsrclient, SRSetRestorePointA);
2286 
2287 #undef GET_PROC
2288 }
2289 
2290 static BOOL is_process_limited(void)
2291 {
2292     SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
2293     PSID Group = NULL;
2294     BOOL IsInGroup;
2295     HANDLE token;
2296 
2297     if (!pCheckTokenMembership || !pOpenProcessToken) return FALSE;
2298 
2299     if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
2300                                   DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
2301         !pCheckTokenMembership(NULL, Group, &IsInGroup))
2302     {
2303         trace("Could not check if the current user is an administrator\n");
2304         FreeSid(Group);
2305         return FALSE;
2306     }
2307     FreeSid(Group);
2308 
2309     if (!IsInGroup)
2310     {
2311         /* Only administrators have enough privileges for these tests */
2312         return TRUE;
2313     }
2314 
2315     if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
2316     {
2317         BOOL ret;
2318         TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
2319         DWORD size;
2320 
2321         ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
2322         CloseHandle(token);
2323         return (ret && type == TokenElevationTypeLimited);
2324     }
2325     return FALSE;
2326 }
2327 
2328 static char *get_user_sid(void)
2329 {
2330     HANDLE token;
2331     DWORD size = 0;
2332     TOKEN_USER *user;
2333     char *usersid = NULL;
2334 
2335     if (!pConvertSidToStringSidA)
2336     {
2337         win_skip("ConvertSidToStringSidA is not available\n");
2338         return NULL;
2339     }
2340     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
2341     GetTokenInformation(token, TokenUser, NULL, size, &size);
2342 
2343     user = HeapAlloc(GetProcessHeap(), 0, size);
2344     GetTokenInformation(token, TokenUser, user, size, &size);
2345     pConvertSidToStringSidA(user->User.Sid, &usersid);
2346     HeapFree(GetProcessHeap(), 0, user);
2347 
2348     CloseHandle(token);
2349     return usersid;
2350 }
2351 
2352 static BOOL CDECL get_temp_file(char *pszTempName, int cbTempName, void *pv)
2353 {
2354     LPSTR tempname;
2355 
2356     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2357     GetTempFileNameA(".", "xx", 0, tempname);
2358 
2359     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
2360     {
2361         lstrcpyA(pszTempName, tempname);
2362         HeapFree(GetProcessHeap(), 0, tempname);
2363         return TRUE;
2364     }
2365 
2366     HeapFree(GetProcessHeap(), 0, tempname);
2367 
2368     return FALSE;
2369 }
2370 
2371 static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
2372                                    USHORT *pattribs, int *err, void *pv)
2373 {
2374     BY_HANDLE_FILE_INFORMATION finfo;
2375     FILETIME filetime;
2376     HANDLE handle;
2377     DWORD attrs;
2378     BOOL res;
2379 
2380     handle = CreateFileA(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
2381                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
2382 
2383     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
2384 
2385     res = GetFileInformationByHandle(handle, &finfo);
2386     ok(res, "Expected GetFileInformationByHandle to succeed\n");
2387 
2388     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
2389     FileTimeToDosDateTime(&filetime, pdate, ptime);
2390 
2391     attrs = GetFileAttributesA(pszName);
2392     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
2393 
2394     return (INT_PTR)handle;
2395 }
2396 
2397 static BOOL add_file(HFCI hfci, const char *file, TCOMP compress)
2398 {
2399     char path[MAX_PATH];
2400     char filename[MAX_PATH];
2401 
2402     lstrcpyA(path, CURR_DIR);
2403     lstrcatA(path, "\\");
2404     lstrcatA(path, file);
2405 
2406     lstrcpyA(filename, file);
2407 
2408     return FCIAddFile(hfci, path, filename, FALSE, get_next_cabinet,
2409                       progress, get_open_info, compress);
2410 }
2411 
2412 static void set_cab_parameters(PCCAB pCabParams, const CHAR *name, DWORD max_size)
2413 {
2414     ZeroMemory(pCabParams, sizeof(CCAB));
2415 
2416     pCabParams->cb = max_size;
2417     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
2418     pCabParams->setID = 0xbeef;
2419     pCabParams->iCab = 1;
2420     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
2421     lstrcatA(pCabParams->szCabPath, "\\");
2422     lstrcpyA(pCabParams->szCab, name);
2423 }
2424 
2425 static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
2426 {
2427     CCAB cabParams;
2428     LPCSTR ptr;
2429     HFCI hfci;
2430     ERF erf;
2431     BOOL res;
2432 
2433     set_cab_parameters(&cabParams, name, max_size);
2434 
2435     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
2436                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
2437                       get_temp_file, &cabParams, NULL);
2438 
2439     ok(hfci != NULL, "Failed to create an FCI context\n");
2440 
2441     ptr = files;
2442     while (*ptr)
2443     {
2444         res = add_file(hfci, ptr, tcompTYPE_MSZIP);
2445         ok(res, "Failed to add file: %s\n", ptr);
2446         ptr += lstrlenA(ptr) + 1;
2447     }
2448 
2449     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
2450     ok(res, "Failed to flush the cabinet\n");
2451 
2452     res = FCIDestroy(hfci);
2453     ok(res, "Failed to destroy the cabinet\n");
2454 }
2455 
2456 static BOOL get_user_dirs(void)
2457 {
2458     HKEY hkey;
2459     DWORD type, size;
2460 
2461     if (RegOpenKeyA(HKEY_CURRENT_USER,
2462                     "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hkey))
2463         return FALSE;
2464 
2465     size = MAX_PATH;
2466     if (RegQueryValueExA(hkey, "AppData", 0, &type, (LPBYTE)APP_DATA_DIR, &size))
2467     {
2468         RegCloseKey(hkey);
2469         return FALSE;
2470     }
2471 
2472     RegCloseKey(hkey);
2473     return TRUE;
2474 }
2475 
2476 static BOOL get_system_dirs(void)
2477 {
2478     HKEY hkey;
2479     DWORD type, size;
2480 
2481     if (RegOpenKeyA(HKEY_LOCAL_MACHINE,
2482                     "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
2483         return FALSE;
2484 
2485     size = MAX_PATH;
2486     if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)PROG_FILES_DIR, &size) &&
2487         RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size))
2488     {
2489         RegCloseKey(hkey);
2490         return FALSE;
2491     }
2492 
2493     size = MAX_PATH;
2494     if (RegQueryValueExA(hkey, "CommonFilesDir (x86)", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size) &&
2495         RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size))
2496     {
2497         RegCloseKey(hkey);
2498         return FALSE;
2499     }
2500 
2501     RegCloseKey(hkey);
2502 
2503     if (!GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH))
2504         return FALSE;
2505 
2506     return TRUE;
2507 }
2508 
2509 static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
2510 {
2511     HANDLE file;
2512     DWORD written;
2513 
2514     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2515     if (file == INVALID_HANDLE_VALUE)
2516         return;
2517 
2518     WriteFile(file, data, strlen(data), &written, NULL);
2519 
2520     if (size)
2521     {
2522         SetFilePointer(file, size, NULL, FILE_BEGIN);
2523         SetEndOfFile(file);
2524     }
2525 
2526     CloseHandle(file);
2527 }
2528 
2529 #define create_file(name, size) create_file_data(name, name, size)
2530 
2531 static void create_test_files(void)
2532 {
2533     CreateDirectoryA("msitest", NULL);
2534     create_file("msitest\\one.txt", 100);
2535     CreateDirectoryA("msitest\\first", NULL);
2536     create_file("msitest\\first\\two.txt", 100);
2537     CreateDirectoryA("msitest\\second", NULL);
2538     create_file("msitest\\second\\three.txt", 100);
2539 
2540     create_file("four.txt", 100);
2541     create_file("five.txt", 100);
2542     create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
2543 
2544     create_file("msitest\\filename", 100);
2545     create_file("msitest\\service.exe", 100);
2546     create_file("msitest\\service2.exe", 100);
2547 
2548     DeleteFileA("four.txt");
2549     DeleteFileA("five.txt");
2550 }
2551 
2552 static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
2553 {
2554     CHAR path[MAX_PATH];
2555 
2556     lstrcpyA(path, PROG_FILES_DIR);
2557     lstrcatA(path, "\\");
2558     lstrcatA(path, rel_path);
2559 
2560     if (is_file)
2561         return DeleteFileA(path);
2562     else
2563         return RemoveDirectoryA(path);
2564 }
2565 
2566 static void delete_test_files(void)
2567 {
2568     DeleteFileA("msitest.msi");
2569     DeleteFileA("msitest.cab");
2570     DeleteFileA("msitest\\second\\three.txt");
2571     DeleteFileA("msitest\\first\\two.txt");
2572     DeleteFileA("msitest\\one.txt");
2573     DeleteFileA("msitest\\service.exe");
2574     DeleteFileA("msitest\\service2.exe");
2575     DeleteFileA("msitest\\filename");
2576     RemoveDirectoryA("msitest\\second");
2577     RemoveDirectoryA("msitest\\first");
2578     RemoveDirectoryA("msitest");
2579 }
2580 
2581 static void write_file(const CHAR *filename, const char *data, int data_size)
2582 {
2583     DWORD size;
2584     HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2585     WriteFile(hf, data, data_size, &size, NULL);
2586     CloseHandle(hf);
2587 }
2588 
2589 static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
2590 {
2591     MSIHANDLE summary;
2592     UINT r;
2593 
2594     r = MsiGetSummaryInformationA(db, NULL, 5, &summary);
2595     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2596 
2597     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
2598     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2599 
2600     r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
2601                                    "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
2602     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2603 
2604     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
2605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2606 
2607     r = MsiSummaryInfoSetPropertyA(summary, PID_WORDCOUNT, VT_I4, wordcount, NULL, NULL);
2608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2609 
2610     r = MsiSummaryInfoSetPropertyA(summary, PID_TITLE, VT_LPSTR, 0, NULL, "MSITEST");
2611     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2612 
2613     /* write the summary changes back to the stream */
2614     r = MsiSummaryInfoPersist(summary);
2615     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2616 
2617     MsiCloseHandle(summary);
2618 }
2619 
2620 #define create_database(name, tables, num_tables) \
2621     create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
2622 
2623 #define create_database_template(name, tables, num_tables, version, template) \
2624     create_database_wordcount(name, tables, num_tables, version, 0, template);
2625 
2626 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
2627                                       int num_tables, INT version, INT wordcount,
2628                                       const char *template)
2629 {
2630     MSIHANDLE db;
2631     UINT r;
2632     WCHAR *nameW;
2633     int j, len;
2634 
2635     len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
2636     if (!(nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return;
2637     MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
2638 
2639     r = MsiOpenDatabaseW(nameW, MSIDBOPEN_CREATE, &db);
2640     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2641 
2642     /* import the tables into the database */
2643     for (j = 0; j < num_tables; j++)
2644     {
2645         const msi_table *table = &tables[j];
2646 
2647         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
2648 
2649         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
2650         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2651 
2652         DeleteFileA(table->filename);
2653     }
2654 
2655     write_msi_summary_info(db, version, wordcount, template);
2656 
2657     r = MsiDatabaseCommit(db);
2658     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
2659 
2660     MsiCloseHandle(db);
2661     HeapFree( GetProcessHeap(), 0, nameW );
2662 }
2663 
2664 static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
2665 {
2666     RESTOREPOINTINFOA spec;
2667 
2668     spec.dwEventType = event_type;
2669     spec.dwRestorePtType = APPLICATION_INSTALL;
2670     spec.llSequenceNumber = status->llSequenceNumber;
2671     lstrcpyA(spec.szDescription, "msitest restore point");
2672 
2673     return pSRSetRestorePointA(&spec, status);
2674 }
2675 
2676 static void remove_restore_point(DWORD seq_number)
2677 {
2678     DWORD res;
2679 
2680     res = pSRRemoveRestorePoint(seq_number);
2681     if (res != ERROR_SUCCESS)
2682         trace("Failed to remove the restore point : %08x\n", res);
2683 }
2684 
2685 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
2686 {
2687     if (pRegDeleteKeyExA)
2688         return pRegDeleteKeyExA( key, subkey, access, 0 );
2689     return RegDeleteKeyA( key, subkey );
2690 }
2691 
2692 static BOOL file_exists(LPCSTR file)
2693 {
2694     return GetFileAttributesA(file) != INVALID_FILE_ATTRIBUTES;
2695 }
2696 
2697 static BOOL pf_exists(LPCSTR file)
2698 {
2699     CHAR path[MAX_PATH];
2700 
2701     lstrcpyA(path, PROG_FILES_DIR);
2702     lstrcatA(path, "\\");
2703     lstrcatA(path, file);
2704 
2705     return file_exists(path);
2706 }
2707 
2708 static void delete_pfmsitest_files(void)
2709 {
2710     SHFILEOPSTRUCTA shfl;
2711     CHAR path[MAX_PATH+11];
2712 
2713     lstrcpyA(path, PROG_FILES_DIR);
2714     lstrcatA(path, "\\msitest\\*");
2715     path[strlen(path) + 1] = '\0';
2716 
2717     shfl.hwnd = NULL;
2718     shfl.wFunc = FO_DELETE;
2719     shfl.pFrom = path;
2720     shfl.pTo = NULL;
2721     shfl.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_NORECURSION | FOF_SILENT | FOF_NOERRORUI;
2722 
2723     SHFileOperationA(&shfl);
2724 
2725     lstrcpyA(path, PROG_FILES_DIR);
2726     lstrcatA(path, "\\msitest");
2727     RemoveDirectoryA(path);
2728 }
2729 
2730 static void check_reg_str(HKEY prodkey, LPCSTR name, LPCSTR expected, BOOL bcase, DWORD line)
2731 {
2732     char val[MAX_PATH];
2733     DWORD size, type;
2734     LONG res;
2735 
2736     size = MAX_PATH;
2737     val[0] = '\0';
2738     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)val, &size);
2739 
2740     if (res != ERROR_SUCCESS ||
2741         (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ))
2742     {
2743         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2744         return;
2745     }
2746 
2747     if (!expected)
2748         ok_(__FILE__, line)(!val[0], "Expected empty string, got %s\n", val);
2749     else
2750     {
2751         if (bcase)
2752             ok_(__FILE__, line)(!lstrcmpA(val, expected), "Expected %s, got %s\n", expected, val);
2753         else
2754             ok_(__FILE__, line)(!lstrcmpiA(val, expected), "Expected %s, got %s\n", expected, val);
2755     }
2756 }
2757 
2758 static void check_reg_dword(HKEY prodkey, LPCSTR name, DWORD expected, DWORD line)
2759 {
2760     DWORD val, size, type;
2761     LONG res;
2762 
2763     size = sizeof(DWORD);
2764     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2765 
2766     if (res != ERROR_SUCCESS || type != REG_DWORD)
2767     {
2768         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2769         return;
2770     }
2771 
2772     ok_(__FILE__, line)(val == expected, "Expected %d, got %d\n", expected, val);
2773 }
2774 
2775 static void check_reg_dword4(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3,
2776                              DWORD expected4, DWORD line)
2777 {
2778     DWORD val, size, type;
2779     LONG res;
2780 
2781     size = sizeof(DWORD);
2782     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2783 
2784     if (res != ERROR_SUCCESS || type != REG_DWORD)
2785     {
2786         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2787         return;
2788     }
2789 
2790     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4,
2791         "Expected %d, %d, %d or %d, got %d\n", expected1, expected2, expected3, expected4, val);
2792 }
2793 
2794 static void check_reg_dword5(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD expected2, DWORD expected3,
2795                              DWORD expected4, DWORD expected5, DWORD line)
2796 {
2797     DWORD val, size, type;
2798     LONG res;
2799 
2800     size = sizeof(DWORD);
2801     res = RegQueryValueExA(prodkey, name, NULL, &type, (LPBYTE)&val, &size);
2802 
2803     if (res != ERROR_SUCCESS || type != REG_DWORD)
2804     {
2805         ok_(__FILE__, line)(FALSE, "Key doesn't exist or wrong type\n");
2806         return;
2807     }
2808 
2809     ok_(__FILE__, line)(val == expected1 || val == expected2 || val == expected3 || val == expected4 ||
2810         val == expected5,
2811         "Expected %d, %d, %d, %d or %d, got %d\n", expected1, expected2, expected3, expected4, expected5, val);
2812 }
2813 
2814 #define CHECK_REG_STR(prodkey, name, expected) \
2815     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
2816 
2817 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
2818     do { \
2819         check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
2820         RegDeleteValueA(prodkey, name); \
2821     } while(0)
2822 
2823 #define CHECK_REG_ISTR(prodkey, name, expected) \
2824     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
2825 
2826 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
2827     do { \
2828         check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
2829         RegDeleteValueA(prodkey, name); \
2830     } while(0)
2831 
2832 #define CHECK_REG_DWORD(prodkey, name, expected) \
2833     check_reg_dword(prodkey, name, expected, __LINE__);
2834 
2835 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
2836     do { \
2837         check_reg_dword(prodkey, name, expected, __LINE__); \
2838         RegDeleteValueA(prodkey, name); \
2839     } while(0)
2840 
2841 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
2842     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
2843 
2844 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
2845     do { \
2846         check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
2847         RegDeleteValueA(prodkey, name); \
2848     } while(0)
2849 
2850 #define CHECK_REG_DWORD4(prodkey, name, expected1, expected2, expected3, expected4) \
2851     check_reg_dword4(prodkey, name, expected1, expected2, expected3, expected4, __LINE__);
2852 
2853 #define CHECK_DEL_REG_DWORD5(prodkey, name, expected1, expected2, expected3, expected4 ,expected5) \
2854     do { \
2855         check_reg_dword5(prodkey, name, expected1, expected2, expected3, expected4, expected5, __LINE__); \
2856         RegDeleteValueA(prodkey, name); \
2857     } while(0)
2858 
2859 static void get_date_str(LPSTR date)
2860 {
2861     SYSTEMTIME systime;
2862 
2863     static const char date_fmt[] = "%d%02d%02d";
2864     GetLocalTime(&systime);
2865     sprintf(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay);
2866 }
2867 
2868 static void test_register_product(void)
2869 {
2870     UINT r;
2871     LONG res;
2872     HKEY hkey, props, usage;
2873     LPSTR usersid;
2874     char date[MAX_PATH], temp[MAX_PATH], keypath[MAX_PATH], path[MAX_PATH];
2875     DWORD size, type;
2876     REGSAM access = KEY_ALL_ACCESS;
2877 
2878     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
2879                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2880     static const CHAR uninstall_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion"
2881                                            "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
2882     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2883                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
2884     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
2885                                 "\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
2886     static const CHAR userugkey[] = "Software\\Microsoft\\Installer\\UpgradeCodes"
2887                                     "\\51AAE0C44620A5E4788506E91F249BD2";
2888 
2889     if (is_process_limited())
2890     {
2891         skip("process is limited\n");
2892         return;
2893     }
2894 
2895     if (!(usersid = get_user_sid()))
2896         return;
2897 
2898     get_date_str(date);
2899     GetTempPathA(MAX_PATH, temp);
2900 
2901     CreateDirectoryA("msitest", NULL);
2902     create_file("msitest\\maximus", 500);
2903 
2904     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
2905 
2906     if (is_wow64)
2907         access |= KEY_WOW64_64KEY;
2908 
2909     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
2910 
2911     /* RegisterProduct */
2912     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
2913     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2914     {
2915         skip("Not enough rights to perform tests\n");
2916         goto error;
2917     }
2918     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2919     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
2920     ok(delete_pf("msitest", FALSE), "Directory not created\n");
2921 
2922     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
2923     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
2924 
2925     if (is_64bit)
2926     {
2927         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
2928         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2929     }
2930     else
2931     {
2932         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
2933         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2934     }
2935 
2936     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
2937     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
2938     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
2939     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
2940     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2941     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
2942     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2943     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
2944     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
2945     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
2946     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
2947     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
2948     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
2949     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
2950     CHECK_DEL_REG_STR(hkey, "Size", NULL);
2951     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
2952     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
2953     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
2954     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
2955     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
2956     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
2957     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
2958     todo_wine
2959     {
2960         CHECK_DEL_REG_DWORD5(hkey, "EstimatedSize", 12, -12, 4, 10, 24);
2961     }
2962 
2963     delete_key(hkey, "", access);
2964     RegCloseKey(hkey);
2965 
2966     sprintf(keypath, userdata, usersid);
2967     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
2968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2969 
2970     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
2971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2972 
2973     size = sizeof(path);
2974     RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size);
2975     DeleteFileA(path);
2976     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
2977 
2978     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
2979     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
2980     CHECK_DEL_REG_STR(props, "InstallDate", date);
2981     CHECK_DEL_REG_STR(props, "InstallSource", temp);
2982     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2983     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
2984     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
2985     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
2986     CHECK_DEL_REG_STR(props, "Comments", NULL);
2987     CHECK_DEL_REG_STR(props, "Contact", NULL);
2988     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
2989     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
2990     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
2991     CHECK_DEL_REG_STR(props, "Readme", NULL);
2992     CHECK_DEL_REG_STR(props, "Size", NULL);
2993     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
2994     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
2995     CHECK_DEL_REG_DWORD(props, "Language", 1033);
2996     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
2997     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
2998     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
2999     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
3000     todo_wine
3001     {
3002         CHECK_DEL_REG_DWORD5(props, "EstimatedSize", 12, -12, 4, 10, 24);
3003     }
3004 
3005     delete_key(props, "", access);
3006     RegCloseKey(props);
3007 
3008     res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage);
3009     todo_wine
3010     {
3011         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3012     }
3013 
3014     delete_key(usage, "", access);
3015     RegCloseKey(usage);
3016     delete_key(hkey, "", access);
3017     RegCloseKey(hkey);
3018 
3019     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey);
3020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3021 
3022     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3023 
3024     delete_key(hkey, "", access);
3025     RegCloseKey(hkey);
3026 
3027     /* RegisterProduct, machine */
3028     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 ALLUSERS=1");
3029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3030     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3031     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3032 
3033     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, userugkey, 0, access, &hkey);
3034     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3035 
3036     if (is_64bit)
3037     {
3038         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
3039         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3040     }
3041     else
3042     {
3043         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
3044         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3045     }
3046 
3047     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
3048     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
3049     CHECK_DEL_REG_STR(hkey, "InstallDate", date);
3050     CHECK_DEL_REG_STR(hkey, "InstallSource", temp);
3051     CHECK_DEL_REG_ISTR(hkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3052     CHECK_DEL_REG_STR(hkey, "Publisher", "Wine");
3053     CHECK_DEL_REG_STR(hkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3054     CHECK_DEL_REG_STR(hkey, "AuthorizedCDFPrefix", NULL);
3055     CHECK_DEL_REG_STR(hkey, "Comments", NULL);
3056     CHECK_DEL_REG_STR(hkey, "Contact", NULL);
3057     CHECK_DEL_REG_STR(hkey, "HelpLink", NULL);
3058     CHECK_DEL_REG_STR(hkey, "HelpTelephone", NULL);
3059     CHECK_DEL_REG_STR(hkey, "InstallLocation", NULL);
3060     CHECK_DEL_REG_STR(hkey, "Readme", NULL);
3061     CHECK_DEL_REG_STR(hkey, "Size", NULL);
3062     CHECK_DEL_REG_STR(hkey, "URLInfoAbout", NULL);
3063     CHECK_DEL_REG_STR(hkey, "URLUpdateInfo", NULL);
3064     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3065     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3066     CHECK_DEL_REG_DWORD(hkey, "VersionMajor", 1);
3067     CHECK_DEL_REG_DWORD(hkey, "VersionMinor", 1);
3068     CHECK_DEL_REG_DWORD(hkey, "WindowsInstaller", 1);
3069     todo_wine
3070     {
3071         CHECK_DEL_REG_DWORD5(hkey, "EstimatedSize", 12, -12, 4, 10, 24);
3072     }
3073 
3074     delete_key(hkey, "", access);
3075     RegCloseKey(hkey);
3076 
3077     sprintf(keypath, userdata, "S-1-5-18");
3078     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3080 
3081     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
3082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3083 
3084     size = sizeof(path);
3085     RegQueryValueExA(props, "LocalPackage", NULL, &type, (LPBYTE)path, &size);
3086     DeleteFileA(path);
3087     RegDeleteValueA(props, "LocalPackage"); /* LocalPackage is nondeterministic */
3088 
3089     CHECK_DEL_REG_STR(props, "DisplayName", "MSITEST");
3090     CHECK_DEL_REG_STR(props, "DisplayVersion", "1.1.1");
3091     CHECK_DEL_REG_STR(props, "InstallDate", date);
3092     CHECK_DEL_REG_STR(props, "InstallSource", temp);
3093     CHECK_DEL_REG_ISTR(props, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3094     CHECK_DEL_REG_STR(props, "Publisher", "Wine");
3095     CHECK_DEL_REG_STR(props, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3096     CHECK_DEL_REG_STR(props, "AuthorizedCDFPrefix", NULL);
3097     CHECK_DEL_REG_STR(props, "Comments", NULL);
3098     CHECK_DEL_REG_STR(props, "Contact", NULL);
3099     CHECK_DEL_REG_STR(props, "HelpLink", NULL);
3100     CHECK_DEL_REG_STR(props, "HelpTelephone", NULL);
3101     CHECK_DEL_REG_STR(props, "InstallLocation", NULL);
3102     CHECK_DEL_REG_STR(props, "Readme", NULL);
3103     CHECK_DEL_REG_STR(props, "Size", NULL);
3104     CHECK_DEL_REG_STR(props, "URLInfoAbout", NULL);
3105     CHECK_DEL_REG_STR(props, "URLUpdateInfo", NULL);
3106     CHECK_DEL_REG_DWORD(props, "Language", 1033);
3107     CHECK_DEL_REG_DWORD(props, "Version", 0x1010001);
3108     CHECK_DEL_REG_DWORD(props, "VersionMajor", 1);
3109     CHECK_DEL_REG_DWORD(props, "VersionMinor", 1);
3110     CHECK_DEL_REG_DWORD(props, "WindowsInstaller", 1);
3111     todo_wine
3112     {
3113         CHECK_DEL_REG_DWORD5(props, "EstimatedSize", 12, -12, 4, 10, 24);
3114     }
3115 
3116     delete_key(props, "", access);
3117     RegCloseKey(props);
3118 
3119     res = RegOpenKeyExA(hkey, "Usage", 0, access, &usage);
3120     todo_wine
3121     {
3122         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3123     }
3124 
3125     delete_key(usage, "", access);
3126     RegCloseKey(usage);
3127     delete_key(hkey, "", access);
3128     RegCloseKey(hkey);
3129 
3130     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ugkey, 0, access, &hkey);
3131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3132 
3133     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3134 
3135     delete_key(hkey, "", access);
3136     RegCloseKey(hkey);
3137 
3138 error:
3139     DeleteFileA(msifile);
3140     DeleteFileA("msitest\\maximus");
3141     RemoveDirectoryA("msitest");
3142     HeapFree(GetProcessHeap(), 0, usersid);
3143 }
3144 
3145 static void test_publish_product(void)
3146 {
3147     static const char prodpath[] =
3148         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\%s\\Products"
3149         "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3150     static const char cuprodpath[] =
3151         "Software\\Microsoft\\Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3152     static const char cuupgrades[] =
3153         "Software\\Microsoft\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
3154     static const char badprod[] =
3155         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Products"
3156         "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3157     static const char machprod[] =
3158         "Software\\Classes\\Installer\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3159     static const char machup[] =
3160         "Software\\Classes\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2";
3161     UINT r;
3162     LONG res;
3163     LPSTR usersid;
3164     HKEY sourcelist, net, props;
3165     HKEY hkey, patches, media;
3166     CHAR keypath[MAX_PATH];
3167     CHAR temp[MAX_PATH];
3168     CHAR path[MAX_PATH];
3169     BOOL old_installer = FALSE;
3170     REGSAM access = KEY_ALL_ACCESS;
3171 
3172     if (is_process_limited())
3173     {
3174         skip("process is limited\n");
3175         return;
3176     }
3177 
3178     if (!(usersid = get_user_sid()))
3179         return;
3180 
3181     GetTempPathA(MAX_PATH, temp);
3182 
3183     CreateDirectoryA("msitest", NULL);
3184     create_file("msitest\\maximus", 500);
3185 
3186     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3187 
3188     if (is_wow64)
3189         access |= KEY_WOW64_64KEY;
3190 
3191     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3192 
3193     /* PublishProduct, current user */
3194     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
3195     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3196     {
3197         skip("Not enough rights to perform tests\n");
3198         goto error;
3199     }
3200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3201     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3202     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3203 
3204     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey);
3205     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3206 
3207     sprintf(keypath, prodpath, usersid);
3208     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3209     if (res == ERROR_FILE_NOT_FOUND)
3210     {
3211         res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
3212         if (res == ERROR_SUCCESS)
3213         {
3214             win_skip("Windows Installer < 3.0 detected\n");
3215             RegCloseKey(hkey);
3216             old_installer = TRUE;
3217             goto currentuser;
3218         }
3219         else
3220         {
3221             win_skip("Install failed, no need to continue\n");
3222             return;
3223         }
3224     }
3225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3226 
3227     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
3228     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3229 
3230     res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches);
3231     todo_wine
3232     {
3233         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3234         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
3235     }
3236 
3237     delete_key(patches, "", access);
3238     RegCloseKey(patches);
3239     delete_key(hkey, "", access);
3240     RegCloseKey(hkey);
3241 
3242 currentuser:
3243     res = RegOpenKeyA(HKEY_CURRENT_USER, cuprodpath, &hkey);
3244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3245 
3246     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
3247     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052C94DA02821EECD05F2F");
3248     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3249     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3250     if (!old_installer)
3251         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
3252     CHECK_DEL_REG_DWORD(hkey, "Assignment", 0);
3253     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
3254     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
3255     CHECK_DEL_REG_STR(hkey, "Clients", ":");
3256 
3257     res = RegOpenKeyA(hkey, "SourceList", &sourcelist);
3258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3259 
3260     lstrcpyA(path, "n;1;");
3261     lstrcatA(path, temp);
3262     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
3263     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
3264 
3265     res = RegOpenKeyA(sourcelist, "Net", &net);
3266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3267 
3268     CHECK_DEL_REG_STR(net, "1", temp);
3269 
3270     RegDeleteKeyA(net, "");
3271     RegCloseKey(net);
3272 
3273     res = RegOpenKeyA(sourcelist, "Media", &media);
3274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3275 
3276     CHECK_DEL_REG_STR(media, "1", "DISK1;");
3277 
3278     RegDeleteKeyA(media, "");
3279     RegCloseKey(media);
3280     RegDeleteKeyA(sourcelist, "");
3281     RegCloseKey(sourcelist);
3282     RegDeleteKeyA(hkey, "");
3283     RegCloseKey(hkey);
3284 
3285     res = RegOpenKeyA(HKEY_CURRENT_USER, cuupgrades, &hkey);
3286     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3287 
3288     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3289 
3290     RegDeleteKeyA(hkey, "");
3291     RegCloseKey(hkey);
3292 
3293     /* PublishProduct, machine */
3294     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
3295     if (old_installer)
3296         goto machprod;
3297     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3298     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3299     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3300 
3301     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, badprod, 0, access, &hkey);
3302     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3303 
3304     sprintf(keypath, prodpath, "S-1-5-18");
3305     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3307 
3308     res = RegOpenKeyExA(hkey, "InstallProperties", 0, access, &props);
3309     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3310 
3311     res = RegOpenKeyExA(hkey, "Patches", 0, access, &patches);
3312     todo_wine
3313     {
3314         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3315         CHECK_DEL_REG_STR(patches, "AllPatches", NULL);
3316     }
3317 
3318     delete_key(patches, "", access);
3319     RegCloseKey(patches);
3320     delete_key(hkey, "", access);
3321     RegCloseKey(hkey);
3322 
3323 machprod:
3324     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machprod, 0, access, &hkey);
3325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3326 
3327     CHECK_DEL_REG_STR(hkey, "ProductName", "MSITEST");
3328     CHECK_DEL_REG_STR(hkey, "PackageCode", "AC75740029052C94DA02821EECD05F2F");
3329     CHECK_DEL_REG_DWORD(hkey, "Language", 1033);
3330     CHECK_DEL_REG_DWORD(hkey, "Version", 0x1010001);
3331     if (!old_installer)
3332         CHECK_DEL_REG_DWORD(hkey, "AuthorizedLUAApp", 0);
3333     todo_wine CHECK_DEL_REG_DWORD(hkey, "Assignment", 1);
3334     CHECK_DEL_REG_DWORD(hkey, "AdvertiseFlags", 0x184);
3335     CHECK_DEL_REG_DWORD(hkey, "InstanceType", 0);
3336     CHECK_DEL_REG_STR(hkey, "Clients", ":");
3337 
3338     res = RegOpenKeyExA(hkey, "SourceList", 0, access, &sourcelist);
3339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3340 
3341     lstrcpyA(path, "n;1;");
3342     lstrcatA(path, temp);
3343     CHECK_DEL_REG_STR(sourcelist, "LastUsedSource", path);
3344     CHECK_DEL_REG_STR(sourcelist, "PackageName", "msitest.msi");
3345 
3346     res = RegOpenKeyExA(sourcelist, "Net", 0, access, &net);
3347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3348 
3349     CHECK_DEL_REG_STR(net, "1", temp);
3350 
3351     res = delete_key(net, "", access);
3352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3353     RegCloseKey(net);
3354 
3355     res = RegOpenKeyExA(sourcelist, "Media", 0, access, &media);
3356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3357 
3358     CHECK_DEL_REG_STR(media, "1", "DISK1;");
3359 
3360     res = delete_key(media, "", access);
3361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3362     RegCloseKey(media);
3363     res = delete_key(sourcelist, "", access);
3364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3365     RegCloseKey(sourcelist);
3366     res = delete_key(hkey, "", access);
3367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3368     RegCloseKey(hkey);
3369 
3370     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, machup, 0, access, &hkey);
3371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3372 
3373     CHECK_DEL_REG_STR(hkey, "84A88FD7F6998CE40A22FB59F6B9C2BB", NULL);
3374 
3375     res = delete_key(hkey, "", access);
3376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3377     RegCloseKey(hkey);
3378 
3379 error:
3380     DeleteFileA(msifile);
3381     DeleteFileA("msitest\\maximus");
3382     RemoveDirectoryA("msitest");
3383     HeapFree(GetProcessHeap(), 0, usersid);
3384 }
3385 
3386 static void test_publish_features(void)
3387 {
3388     static const char cupath[] =
3389         "Software\\Microsoft\\Installer\\Features\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3390     static const char udfeatpath[] =
3391         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\%s\\Products"
3392         "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
3393     static const char udpridpath[] =
3394         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\%s\\Products"
3395         "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3396     static const char featkey[] =
3397         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Features";
3398     static const char classfeat[] =
3399         "Software\\Classes\\Installer\\Features\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3400     UINT r;
3401     LONG res;
3402     HKEY hkey;
3403     LPSTR usersid;
3404     CHAR keypath[MAX_PATH];
3405     REGSAM access = KEY_ALL_ACCESS;
3406 
3407     if (is_process_limited())
3408     {
3409         skip("process is limited\n");
3410         return;
3411     }
3412 
3413     if (!(usersid = get_user_sid()))
3414         return;
3415 
3416     CreateDirectoryA("msitest", NULL);
3417     create_file("msitest\\maximus", 500);
3418 
3419     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3420 
3421     if (is_wow64)
3422         access |= KEY_WOW64_64KEY;
3423 
3424     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
3425 
3426     /* PublishFeatures, current user */
3427     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
3428     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3429     {
3430         skip("Not enough rights to perform tests\n");
3431         goto error;
3432     }
3433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3434     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3435     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3436 
3437     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey);
3438     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3439 
3440     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey);
3441     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3442 
3443     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3445 
3446     CHECK_REG_STR(hkey, "feature", "");
3447     CHECK_REG_STR(hkey, "montecristo", "");
3448 
3449     RegDeleteValueA(hkey, "feature");
3450     RegDeleteValueA(hkey, "montecristo");
3451     delete_key(hkey, "", access);
3452     RegCloseKey(hkey);
3453 
3454     sprintf(keypath, udfeatpath, usersid);
3455     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3457 
3458     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3459     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3460 
3461     RegDeleteValueA(hkey, "feature");
3462     RegDeleteValueA(hkey, "montecristo");
3463     delete_key(hkey, "", access);
3464     RegCloseKey(hkey);
3465     sprintf(keypath, udpridpath, usersid);
3466     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3467 
3468     /* PublishFeatures, machine */
3469     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
3470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3471     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3472     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3473 
3474     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, featkey, 0, access, &hkey);
3475     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3476 
3477     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
3478     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3479     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, classfeat, 0, access, &hkey);
3480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3481 
3482     CHECK_REG_STR(hkey, "feature", "");
3483     CHECK_REG_STR(hkey, "montecristo", "");
3484 
3485     RegDeleteValueA(hkey, "feature");
3486     RegDeleteValueA(hkey, "montecristo");
3487     delete_key(hkey, "", access);
3488     RegCloseKey(hkey);
3489 
3490     sprintf(keypath, udfeatpath, "S-1-5-18");
3491     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
3492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3493 
3494     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82@JU1j_KE");
3495     CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82@JU1j_KE");
3496 
3497     RegDeleteValueA(hkey, "feature");
3498     RegDeleteValueA(hkey, "montecristo");
3499     delete_key(hkey, "", access);
3500     RegCloseKey(hkey);
3501     sprintf(keypath, udpridpath, "S-1-5-18");
3502     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3503 
3504 error:
3505     DeleteFileA(msifile);
3506     DeleteFileA("msitest\\maximus");
3507     RemoveDirectoryA("msitest");
3508     HeapFree(GetProcessHeap(), 0, usersid);
3509 }
3510 
3511 static LPSTR reg_get_val_str(HKEY hkey, LPCSTR name)
3512 {
3513     DWORD len = 0;
3514     LPSTR val;
3515     LONG r;
3516 
3517     r = RegQueryValueExA(hkey, name, NULL, NULL, NULL, &len);
3518     if (r != ERROR_SUCCESS)
3519         return NULL;
3520 
3521     len += sizeof (WCHAR);
3522     val = HeapAlloc(GetProcessHeap(), 0, len);
3523     if (!val) return NULL;
3524     val[0] = 0;
3525     RegQueryValueExA(hkey, name, NULL, NULL, (LPBYTE)val, &len);
3526     return val;
3527 }
3528 
3529 static void get_owner_company(LPSTR *owner, LPSTR *company)
3530 {
3531     LONG res;
3532     HKEY hkey;
3533     REGSAM access = KEY_ALL_ACCESS;
3534 
3535     *owner = *company = NULL;
3536 
3537     if (is_wow64)
3538         access |= KEY_WOW64_64KEY;
3539 
3540     res = RegOpenKeyA(HKEY_CURRENT_USER,
3541                       "Software\\Microsoft\\MS Setup (ACME)\\User Info", &hkey);
3542     if (res == ERROR_SUCCESS)
3543     {
3544         *owner = reg_get_val_str(hkey, "DefName");
3545         *company = reg_get_val_str(hkey, "DefCompany");
3546         RegCloseKey(hkey);
3547     }
3548 
3549     if (!*owner || !*company)
3550     {
3551         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
3552                             "Software\\Microsoft\\Windows\\CurrentVersion", 0, access, &hkey);
3553         if (res == ERROR_SUCCESS)
3554         {
3555             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3556             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3557             RegCloseKey(hkey);
3558         }
3559     }
3560 
3561     if (!*owner || !*company)
3562     {
3563         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
3564                             "Software\\Microsoft\\Windows NT\\CurrentVersion", 0, access, &hkey);
3565         if (res == ERROR_SUCCESS)
3566         {
3567             *owner = reg_get_val_str(hkey, "RegisteredOwner");
3568             *company = reg_get_val_str(hkey, "RegisteredOrganization");
3569             RegCloseKey(hkey);
3570         }
3571     }
3572 }
3573 
3574 static void test_register_user(void)
3575 {
3576     UINT r;
3577     LONG res;
3578     HKEY props;
3579     LPSTR usersid;
3580     LPSTR owner, company;
3581     CHAR keypath[MAX_PATH];
3582     REGSAM access = KEY_ALL_ACCESS;
3583 
3584     static const CHAR keypropsfmt[] =
3585         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3586         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB\\InstallProperties";
3587     static const CHAR keypridfmt[] =
3588         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\"
3589         "UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
3590 
3591     if (is_process_limited())
3592     {
3593         skip("process is limited\n");
3594         return;
3595     }
3596 
3597     if (!(usersid = get_user_sid()))
3598         return;
3599 
3600     get_owner_company(&owner, &company);
3601 
3602     CreateDirectoryA("msitest", NULL);
3603     create_file("msitest\\maximus", 500);
3604 
3605     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3606 
3607     if (is_wow64)
3608         access |= KEY_WOW64_64KEY;
3609 
3610     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3611 
3612     /* RegisterUser, per-user */
3613     r = MsiInstallProductA(msifile, "REGISTER_USER=1");
3614     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3615     {
3616         skip("Not enough rights to perform tests\n");
3617         goto error;
3618     }
3619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3620     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3621     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3622 
3623     sprintf(keypath, keypropsfmt, usersid);
3624     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
3625     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3626 
3627     CHECK_REG_STR(props, "ProductID", "none");
3628     CHECK_REG_STR(props, "RegCompany", company);
3629     CHECK_REG_STR(props, "RegOwner", owner);
3630 
3631     RegDeleteValueA(props, "ProductID");
3632     RegDeleteValueA(props, "RegCompany");
3633     RegDeleteValueA(props, "RegOwner");
3634     delete_key(props, "", access);
3635     RegCloseKey(props);
3636     sprintf(keypath, keypridfmt, usersid);
3637     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3638 
3639     /* RegisterUser, machine */
3640     r = MsiInstallProductA(msifile, "REGISTER_USER=1 ALLUSERS=1");
3641     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3642     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3643     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3644 
3645     sprintf(keypath, keypropsfmt, "S-1-5-18");
3646     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
3647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3648 
3649     CHECK_REG_STR(props, "ProductID", "none");
3650     CHECK_REG_STR(props, "RegCompany", company);
3651     CHECK_REG_STR(props, "RegOwner", owner);
3652 
3653     RegDeleteValueA(props, "ProductID");
3654     RegDeleteValueA(props, "RegCompany");
3655     RegDeleteValueA(props, "RegOwner");
3656     delete_key(props, "", access);
3657     RegCloseKey(props);
3658     sprintf(keypath, keypridfmt, "S-1-5-18");
3659     delete_key(HKEY_LOCAL_MACHINE, keypath, access);
3660 
3661 error:
3662     HeapFree(GetProcessHeap(), 0, company);
3663     HeapFree(GetProcessHeap(), 0, owner);
3664 
3665     DeleteFileA(msifile);
3666     DeleteFileA("msitest\\maximus");
3667     RemoveDirectoryA("msitest");
3668     LocalFree(usersid);
3669 }
3670 
3671 static void test_process_components(void)
3672 {
3673     static const char keyfmt[] =
3674         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\%s\\Components\\%s";
3675     static const char compkey[] =
3676         "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components";
3677     UINT r;
3678     LONG res;
3679     DWORD size;
3680     HKEY comp, hkey;
3681     LPSTR usersid;
3682     CHAR val[MAX_PATH];
3683     CHAR keypath[MAX_PATH];
3684     CHAR program_files_maximus[MAX_PATH];
3685     REGSAM access = KEY_ALL_ACCESS;
3686 
3687     if (is_process_limited())
3688     {
3689         skip("process is limited\n");
3690         return;
3691     }
3692 
3693     if (!(usersid = get_user_sid()))
3694         return;
3695 
3696     CreateDirectoryA("msitest", NULL);
3697     create_file("msitest\\maximus", 500);
3698 
3699     create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table));
3700 
3701     if (is_wow64)
3702         access |= KEY_WOW64_64KEY;
3703 
3704     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3705 
3706     /* ProcessComponents, per-user */
3707     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
3708     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3709     {
3710         skip("Not enough rights to perform tests\n");
3711         goto error;
3712     }
3713     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3714     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3715     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3716 
3717     sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5");
3718     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3720 
3721     size = MAX_PATH;
3722     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3723                            NULL, NULL, (LPBYTE)val, &size);
3724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3725 
3726     lstrcpyA(program_files_maximus,PROG_FILES_DIR);
3727     lstrcatA(program_files_maximus,"\\msitest\\maximus");
3728 
3729     ok(!lstrcmpiA(val, program_files_maximus),
3730        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3731 
3732     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3733     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3734 
3735     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3736     delete_key(comp, "", access);
3737     RegCloseKey(comp);
3738 
3739     sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058");
3740     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3742 
3743     size = MAX_PATH;
3744     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3745                            NULL, NULL, (LPBYTE)val, &size);
3746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3747     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3748        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3749 
3750     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3751     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3752 
3753     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3754     delete_key(comp, "", access);
3755     RegCloseKey(comp);
3756 
3757     /* ProcessComponents, machine */
3758     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1");
3759     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3760     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
3761     ok(delete_pf("msitest", FALSE), "Directory not created\n");
3762 
3763     sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5");
3764     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3766 
3767     size = MAX_PATH;
3768     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3769                            NULL, NULL, (LPBYTE)val, &size);
3770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3771     ok(!lstrcmpiA(val, program_files_maximus),
3772        "Expected \"%s\", got \"%s\"\n", program_files_maximus, val);
3773 
3774     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3775     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3776 
3777     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3778     delete_key(comp, "", access);
3779     RegCloseKey(comp);
3780 
3781     sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058");
3782     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &comp);
3783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3784 
3785     size = MAX_PATH;
3786     res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB",
3787                            NULL, NULL, (LPBYTE)val, &size);
3788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3789     ok(!lstrcmpA(val, "01\\msitest\\augustus"),
3790        "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val);
3791 
3792     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, compkey, 0, access, &hkey);
3793     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3794 
3795     RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB");
3796     delete_key(comp, "", access);
3797     RegCloseKey(comp);
3798 
3799 error:
3800     DeleteFileA(msifile);
3801     DeleteFileA("msitest\\maximus");
3802     RemoveDirectoryA("msitest");
3803     LocalFree(usersid);
3804 }
3805 
3806 static void test_publish(void)
3807 {
3808     static const char subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3809     static const char subkey_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
3810     UINT r;
3811     LONG res;
3812     HKEY uninstall, prodkey, uninstall_32node = NULL;
3813     INSTALLSTATE state;
3814     char date[MAX_PATH], temp[MAX_PATH], prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
3815     REGSAM access = KEY_ALL_ACCESS;
3816     DWORD error;
3817 
3818     if (!pMsiQueryFeatureStateExA)
3819     {
3820         win_skip("MsiQueryFeatureStateExA is not available\n");
3821         return;
3822     }
3823     if (is_process_limited())
3824     {
3825         skip("process is limited\n");
3826         return;
3827     }
3828 
3829     get_date_str(date);
3830     GetTempPathA(MAX_PATH, temp);
3831 
3832     if (is_wow64)
3833         access |= KEY_WOW64_64KEY;
3834 
3835     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, KEY_ALL_ACCESS, &uninstall);
3836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3837 
3838     if (is_64bit)
3839     {
3840         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey_32node, 0, KEY_ALL_ACCESS, &uninstall_32node);
3841         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3842     }
3843 
3844     CreateDirectoryA("msitest", NULL);
3845     create_file("msitest\\maximus", 500);
3846 
3847     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
3848 
3849     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
3850 
3851     state = MsiQueryProductStateA(prodcode);
3852     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3853 
3854     state = MsiQueryFeatureStateA(prodcode, "feature");
3855     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3856 
3857     state = 0xdead;
3858     SetLastError(0xdeadbeef);
3859     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
3860     error = GetLastError();
3861     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
3862     ok(state == 0xdead, "got %d\n", state);
3863     ok(error == 0xdeadbeef, "got %u\n", error);
3864 
3865     state = 0xdead;
3866     SetLastError(0xdeadbeef);
3867     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
3868     error = GetLastError();
3869     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
3870     ok(state == 0xdead, "got %d\n", state);
3871     ok(error == ERROR_SUCCESS, "got %u\n", error);
3872 
3873     state = 0xdead;
3874     SetLastError(0xdeadbeef);
3875     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
3876     error = GetLastError();
3877     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
3878     ok(state == 0xdead, "got %d\n", state);
3879     ok(error == ERROR_SUCCESS, "got %u\n", error);
3880 
3881     state = MsiQueryFeatureStateA(prodcode, "feature");
3882     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3883 
3884     state = MsiQueryFeatureStateA(prodcode, "montecristo");
3885     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3886 
3887     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3888                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3889     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3890     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3891 
3892     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3893     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3894 
3895     /* nothing published */
3896     r = MsiInstallProductA(msifile, NULL);
3897     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
3898     {
3899         skip("Not enough rights to perform tests\n");
3900         goto error;
3901     }
3902     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
3903     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3904     ok(pf_exists("msitest"), "File not installed\n");
3905 
3906     state = MsiQueryProductStateA(prodcode);
3907     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3908 
3909     state = MsiQueryFeatureStateA(prodcode, "feature");
3910     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3911 
3912     state = MsiQueryFeatureStateA(prodcode, "montecristo");
3913     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3914 
3915     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3916                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3917     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3918     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3919 
3920     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3921     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
3922 
3923     /* PublishProduct and RegisterProduct */
3924     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1");
3925     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3926     ok(pf_exists("msitest\\maximus"), "File not installed\n");
3927     ok(pf_exists("msitest"), "File not installed\n");
3928 
3929     state = MsiQueryProductStateA(prodcode);
3930     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
3931 
3932     state = MsiQueryFeatureStateA(prodcode, "feature");
3933     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3934 
3935     state = MsiQueryFeatureStateA(prodcode, "montecristo");
3936     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3937 
3938     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3939                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
3940     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3941     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3942 
3943     if (is_64bit)
3944     {
3945         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3946         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3947     }
3948     else
3949     {
3950         res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
3951         if (is_wow64 && res == ERROR_FILE_NOT_FOUND) /* XP - Vista, Wow64 */
3952             res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
3953         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3954     }
3955 
3956     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
3957     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
3958     CHECK_REG_STR(prodkey, "InstallDate", date);
3959     CHECK_REG_STR(prodkey, "InstallSource", temp);
3960     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3961     CHECK_REG_STR(prodkey, "Publisher", "Wine");
3962     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
3963     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
3964     CHECK_REG_STR(prodkey, "Comments", NULL);
3965     CHECK_REG_STR(prodkey, "Contact", NULL);
3966     CHECK_REG_STR(prodkey, "HelpLink", NULL);
3967     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
3968     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
3969     CHECK_REG_STR(prodkey, "Readme", NULL);
3970     CHECK_REG_STR(prodkey, "Size", NULL);
3971     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
3972     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
3973     CHECK_REG_DWORD(prodkey, "Language", 1033);
3974     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
3975     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
3976     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
3977     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
3978     todo_wine
3979     {
3980         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
3981     }
3982 
3983     RegCloseKey(prodkey);
3984 
3985     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
3986     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3987     ok(pf_exists("msitest\\maximus"), "File deleted\n");
3988     ok(pf_exists("msitest"), "File deleted\n");
3989 
3990     state = MsiQueryProductStateA(prodcode);
3991     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3992 
3993     state = MsiQueryFeatureStateA(prodcode, "feature");
3994     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3995 
3996     state = MsiQueryFeatureStateA(prodcode, "montecristo");
3997     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
3998 
3999     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4000                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4001     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4002     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4003 
4004     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
4005     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4006 
4007     /* complete install */
4008     r = MsiInstallProductA(msifile, "FULL=1");
4009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4010     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4011     ok(pf_exists("msitest"), "File not installed\n");
4012 
4013     state = MsiQueryProductStateA(prodcode);
4014     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4015 
4016     state = MsiQueryFeatureStateA(prodcode, "feature");
4017     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4018 
4019     state = 0xdead;
4020     SetLastError(0xdeadbeef);
4021     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, "feature", &state);
4022     error = GetLastError();
4023     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
4024     ok(state == 0xdead, "got %d\n", state);
4025     ok(error == 0xdeadbeef, "got %u\n", error);
4026 
4027     state = 0xdead;
4028     SetLastError(0xdeadbeef);
4029     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, "feature", &state);
4030     error = GetLastError();
4031     ok(r == ERROR_UNKNOWN_PRODUCT, "got %u\n", r);
4032     ok(state == 0xdead, "got %d\n", state);
4033     ok(error == ERROR_SUCCESS, "got %u\n", error);
4034 
4035     state = 0xdead;
4036     SetLastError(0xdeadbeef);
4037     r = pMsiQueryFeatureStateExA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "feature", &state);
4038     error = GetLastError();
4039     ok(r == ERROR_SUCCESS, "got %u\n", r);
4040     ok(state == INSTALLSTATE_LOCAL, "got %d\n", state);
4041     ok(error == ERROR_SUCCESS, "got %u\n", error);
4042 
4043     state = MsiQueryFeatureStateA(prodcode, "montecristo");
4044     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4045 
4046     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4047                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4049     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4050 
4051     if (is_64bit)
4052     {
4053         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4054         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4055     }
4056     else
4057     {
4058         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4059         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4060     }
4061 
4062     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4063     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4064     CHECK_REG_STR(prodkey, "InstallDate", date);
4065     CHECK_REG_STR(prodkey, "InstallSource", temp);
4066     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4067     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4068     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4069     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4070     CHECK_REG_STR(prodkey, "Comments", NULL);
4071     CHECK_REG_STR(prodkey, "Contact", NULL);
4072     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4073     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4074     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4075     CHECK_REG_STR(prodkey, "Readme", NULL);
4076     CHECK_REG_STR(prodkey, "Size", NULL);
4077     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4078     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4079     CHECK_REG_DWORD(prodkey, "Language", 1033);
4080     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4081     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4082     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4083     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4084     todo_wine
4085     {
4086         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
4087     }
4088 
4089     RegCloseKey(prodkey);
4090 
4091     /* no UnpublishFeatures */
4092     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4093     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4094     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4095     ok(!pf_exists("msitest"), "Directory not deleted\n");
4096 
4097     state = MsiQueryProductStateA(prodcode);
4098     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4099 
4100     state = MsiQueryFeatureStateA(prodcode, "feature");
4101     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4102 
4103     state = MsiQueryFeatureStateA(prodcode, "montecristo");
4104     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4105 
4106     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4107                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4108     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4109     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4110 
4111     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
4112     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4113 
4114     /* complete install */
4115     r = MsiInstallProductA(msifile, "FULL=1");
4116     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4117     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4118     ok(pf_exists("msitest"), "File not installed\n");
4119 
4120     state = MsiQueryProductStateA(prodcode);
4121     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4122 
4123     state = MsiQueryFeatureStateA(prodcode, "feature");
4124     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4125 
4126     state = MsiQueryFeatureStateA(prodcode, "montecristo");
4127     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4128 
4129     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4130                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4131     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4132     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4133 
4134     if (is_64bit)
4135     {
4136         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4137         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4138     }
4139     else
4140     {
4141         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4142         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4143     }
4144 
4145     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4146     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4147     CHECK_REG_STR(prodkey, "InstallDate", date);
4148     CHECK_REG_STR(prodkey, "InstallSource", temp);
4149     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4150     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4151     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4152     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4153     CHECK_REG_STR(prodkey, "Comments", NULL);
4154     CHECK_REG_STR(prodkey, "Contact", NULL);
4155     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4156     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4157     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4158     CHECK_REG_STR(prodkey, "Readme", NULL);
4159     CHECK_REG_STR(prodkey, "Size", NULL);
4160     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4161     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4162     CHECK_REG_DWORD(prodkey, "Language", 1033);
4163     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4164     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4165     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4166     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4167     todo_wine
4168     {
4169         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
4170     }
4171 
4172     RegCloseKey(prodkey);
4173 
4174     /* UnpublishFeatures, only feature removed.  Only works when entire product is removed */
4175     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
4176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4177     ok(pf_exists("msitest\\maximus"), "File deleted\n");
4178     ok(pf_exists("msitest"), "Directory deleted\n");
4179 
4180     state = MsiQueryProductStateA(prodcode);
4181     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4182 
4183     state = MsiQueryFeatureStateA(prodcode, "feature");
4184     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4185 
4186     state = MsiQueryFeatureStateA(prodcode, "montecristo");
4187     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4188 
4189     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4190                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4191     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4192     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4193 
4194     if (is_64bit)
4195     {
4196         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4197         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4198     }
4199     else
4200     {
4201         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4202         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4203     }
4204 
4205     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4206     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4207     CHECK_REG_STR(prodkey, "InstallDate", date);
4208     CHECK_REG_STR(prodkey, "InstallSource", temp);
4209     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4210     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4211     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4212     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4213     CHECK_REG_STR(prodkey, "Comments", NULL);
4214     CHECK_REG_STR(prodkey, "Contact", NULL);
4215     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4216     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4217     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4218     CHECK_REG_STR(prodkey, "Readme", NULL);
4219     CHECK_REG_STR(prodkey, "Size", NULL);
4220     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4221     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4222     CHECK_REG_DWORD(prodkey, "Language", 1033);
4223     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4224     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4225     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4226     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4227     todo_wine
4228     {
4229         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
4230     }
4231 
4232     RegCloseKey(prodkey);
4233 
4234     /* complete install */
4235     r = MsiInstallProductA(msifile, "FULL=1");
4236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4237     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4238     ok(pf_exists("msitest"), "File not installed\n");
4239 
4240     state = MsiQueryProductStateA(prodcode);
4241     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4242 
4243     state = MsiQueryFeatureStateA(prodcode, "feature");
4244     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4245 
4246     state = MsiQueryFeatureStateA(prodcode, "montecristo");
4247     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4248 
4249     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4250                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4252     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4253 
4254     if (is_64bit)
4255     {
4256         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4257         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4258     }
4259     else
4260     {
4261         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4262         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4263     }
4264 
4265     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4266     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4267     CHECK_REG_STR(prodkey, "InstallDate", date);
4268     CHECK_REG_STR(prodkey, "InstallSource", temp);
4269     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4270     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4271     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4272     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4273     CHECK_REG_STR(prodkey, "Comments", NULL);
4274     CHECK_REG_STR(prodkey, "Contact", NULL);
4275     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4276     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4277     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4278     CHECK_REG_STR(prodkey, "Readme", NULL);
4279     CHECK_REG_STR(prodkey, "Size", NULL);
4280     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4281     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4282     CHECK_REG_DWORD(prodkey, "Language", 1033);
4283     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4284     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4285     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4286     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4287     todo_wine
4288     {
4289         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -20, 10, 24);
4290     }
4291 
4292     RegCloseKey(prodkey);
4293 
4294     /* UnpublishFeatures, both features removed */
4295     r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
4296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4297     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4298     ok(!pf_exists("msitest"), "Directory not deleted\n");
4299 
4300     state = MsiQueryProductStateA(prodcode);
4301     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4302 
4303     state = MsiQueryFeatureStateA(prodcode, "feature");
4304     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4305 
4306     state = MsiQueryFeatureStateA(prodcode, "montecristo");
4307     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4308 
4309     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4310                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4311     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4312     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4313 
4314     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
4315     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4316 
4317     /* complete install */
4318     r = MsiInstallProductA(msifile, "FULL=1");
4319     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4320     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4321     ok(pf_exists("msitest"), "File not installed\n");
4322 
4323     state = MsiQueryProductStateA(prodcode);
4324     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
4325 
4326     state = MsiQueryFeatureStateA(prodcode, "feature");
4327     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4328 
4329     state = MsiQueryFeatureStateA(prodcode, "montecristo");
4330     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4331 
4332     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4333                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4334     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4335     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
4336 
4337     if (is_64bit)
4338     {
4339         res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4340         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4341     }
4342     else
4343     {
4344         res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
4345         ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4346     }
4347 
4348     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
4349     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
4350     CHECK_REG_STR(prodkey, "InstallDate", date);
4351     CHECK_REG_STR(prodkey, "InstallSource", temp);
4352     CHECK_REG_ISTR(prodkey, "ModifyPath", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4353     CHECK_REG_STR(prodkey, "Publisher", "Wine");
4354     CHECK_REG_STR(prodkey, "UninstallString", "MsiExec.exe /I{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
4355     CHECK_REG_STR(prodkey, "AuthorizedCDFPrefix", NULL);
4356     CHECK_REG_STR(prodkey, "Comments", NULL);
4357     CHECK_REG_STR(prodkey, "Contact", NULL);
4358     CHECK_REG_STR(prodkey, "HelpLink", NULL);
4359     CHECK_REG_STR(prodkey, "HelpTelephone", NULL);
4360     CHECK_REG_STR(prodkey, "InstallLocation", NULL);
4361     CHECK_REG_STR(prodkey, "Readme", NULL);
4362     CHECK_REG_STR(prodkey, "Size", NULL);
4363     CHECK_REG_STR(prodkey, "URLInfoAbout", NULL);
4364     CHECK_REG_STR(prodkey, "URLUpdateInfo", NULL);
4365     CHECK_REG_DWORD(prodkey, "Language", 1033);
4366     CHECK_REG_DWORD(prodkey, "Version", 0x1010001);
4367     CHECK_REG_DWORD(prodkey, "VersionMajor", 1);
4368     CHECK_REG_DWORD(prodkey, "VersionMinor", 1);
4369     CHECK_REG_DWORD(prodkey, "WindowsInstaller", 1);
4370     todo_wine
4371     {
4372         CHECK_REG_DWORD4(prodkey, "EstimatedSize", 12, -12, 10, 24);
4373     }
4374 
4375     RegCloseKey(prodkey);
4376 
4377     /* complete uninstall */
4378     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4379     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4380     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4381     ok(!pf_exists("msitest"), "Directory not deleted\n");
4382 
4383     state = MsiQueryProductStateA(prodcode);
4384     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4385 
4386     state = MsiQueryFeatureStateA(prodcode, "feature");
4387     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4388 
4389     state = MsiQueryFeatureStateA(prodcode, "montecristo");
4390     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4391 
4392     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4393                                 "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
4394     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4395     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
4396 
4397     res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
4398     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
4399 
4400     /* make sure 'Program Files\msitest' is removed */
4401     delete_pfmsitest_files();
4402 
4403 error:
4404     RegCloseKey(uninstall);
4405     RegCloseKey(uninstall_32node);
4406     DeleteFileA(msifile);
4407     DeleteFileA("msitest\\maximus");
4408     RemoveDirectoryA("msitest");
4409 }
4410 
4411 static void test_publish_sourcelist(void)
4412 {
4413     UINT r;
4414     DWORD size;
4415     CHAR value[MAX_PATH];
4416     CHAR path[MAX_PATH];
4417     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
4418 
4419     if (!pMsiSourceListEnumSourcesA || !pMsiSourceListGetInfoA)
4420     {
4421         win_skip("MsiSourceListEnumSourcesA and/or MsiSourceListGetInfoA are not available\n");
4422         return;
4423     }
4424     if (is_process_limited())
4425     {
4426         skip("process is limited\n");
4427         return;
4428     }
4429 
4430     CreateDirectoryA("msitest", NULL);
4431     create_file("msitest\\maximus", 500);
4432 
4433     create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table));
4434 
4435     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4436 
4437     r = MsiInstallProductA(msifile, NULL);
4438     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4439     {
4440         skip("Not enough rights to perform tests\n");
4441         goto error;
4442     }
4443     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4444     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4445     ok(pf_exists("msitest"), "File not installed\n");
4446 
4447     /* nothing published */
4448     size = MAX_PATH;
4449     lstrcpyA(value, "aaa");
4450     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4451                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
4452     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4453     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4454     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4455 
4456     size = MAX_PATH;
4457     lstrcpyA(value, "aaa");
4458     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4459                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4460     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4461     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4462     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4463 
4464     r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1");
4465     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4466     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4467     ok(pf_exists("msitest"), "File not installed\n");
4468 
4469     /* after RegisterProduct */
4470     size = MAX_PATH;
4471     lstrcpyA(value, "aaa");
4472     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4473                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
4474     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4475     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4476     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4477 
4478     size = MAX_PATH;
4479     lstrcpyA(value, "aaa");
4480     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4481                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4482     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4483     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4484     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4485 
4486     r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1");
4487     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4488     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4489     ok(pf_exists("msitest"), "File not installed\n");
4490 
4491     /* after ProcessComponents */
4492     size = MAX_PATH;
4493     lstrcpyA(value, "aaa");
4494     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4495                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
4496     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4497     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4498     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4499 
4500     size = MAX_PATH;
4501     lstrcpyA(value, "aaa");
4502     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4503                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4504     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4505     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4506     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4507 
4508     r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1");
4509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4510     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4511     ok(pf_exists("msitest"), "File not installed\n");
4512 
4513     /* after PublishFeatures */
4514     size = MAX_PATH;
4515     lstrcpyA(value, "aaa");
4516     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4517                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
4518     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4519     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4520     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4521 
4522     size = MAX_PATH;
4523     lstrcpyA(value, "aaa");
4524     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4525                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4526     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4527     ok(size == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, size);
4528     ok(!lstrcmpA(value, "aaa"), "Expected \"aaa\", got \"%s\"\n", value);
4529 
4530     r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
4531     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4532     ok(pf_exists("msitest\\maximus"), "File not installed\n");
4533     ok(pf_exists("msitest"), "File not installed\n");
4534 
4535     /* after PublishProduct */
4536     size = MAX_PATH;
4537     lstrcpyA(value, "aaa");
4538     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4539                                MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEA, value, &size);
4540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4541     ok(!lstrcmpA(value, "msitest.msi"), "Expected 'msitest.msi', got %s\n", value);
4542     ok(size == 11, "Expected 11, got %d\n", size);
4543 
4544     size = MAX_PATH;
4545     lstrcpyA(value, "aaa");
4546     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4547                                MSICODE_PRODUCT, INSTALLPROPERTY_MEDIAPACKAGEPATHA, value, &size);
4548     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4549     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4550     ok(size == 0, "Expected 0, got %d\n", size);
4551 
4552     size = MAX_PATH;
4553     lstrcpyA(value, "aaa");
4554     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4555                                MSICODE_PRODUCT, INSTALLPROPERTY_DISKPROMPTA, value, &size);
4556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4557     ok(!lstrcmpA(value, ""), "Expected \"\", got \"%s\"\n", value);
4558     ok(size == 0, "Expected 0, got %d\n", size);
4559 
4560     lstrcpyA(path, CURR_DIR);
4561     lstrcatA(path, "\\");
4562 
4563     size = MAX_PATH;
4564     lstrcpyA(value, "aaa");
4565     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4566                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEA, value, &size);
4567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4568     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4569     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4570 
4571     size = MAX_PATH;
4572     lstrcpyA(value, "aaa");
4573     r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4574                                MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDTYPEA, value, &size);
4575     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4576     ok(!lstrcmpA(value, "n"), "Expected \"n\", got \"%s\"\n", value);
4577     ok(size == 1, "Expected 1, got %d\n", size);
4578 
4579     size = MAX_PATH;
4580     lstrcpyA(value, "aaa");
4581     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4582                                    MSICODE_PRODUCT | MSISOURCETYPE_URL, 0, value, &size);
4583     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4584     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4585     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4586 
4587     size = MAX_PATH;
4588     lstrcpyA(value, "aaa");
4589     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4590                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 0, value, &size);
4591     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4592     ok(!lstrcmpA(value, path), "Expected \"%s\", got \"%s\"\n", path, value);
4593     ok(size == lstrlenA(path), "Expected %d, got %d\n", lstrlenA(path), size);
4594 
4595     size = MAX_PATH;
4596     lstrcpyA(value, "aaa");
4597     r = pMsiSourceListEnumSourcesA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
4598                                    MSICODE_PRODUCT | MSISOURCETYPE_NETWORK, 1, value, &size);
4599     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4600     ok(!lstrcmpA(value, "aaa"), "Expected value to be unchanged, got %s\n", value);
4601     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
4602 
4603     /* complete uninstall */
4604     r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
4605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4606     ok(!pf_exists("msitest\\maximus"), "File not deleted\n");
4607     ok(!pf_exists("msitest"), "Directory not deleted\n");
4608 
4609     /* make sure 'Program Files\msitest' is removed */
4610     delete_pfmsitest_files();
4611 
4612 error:
4613     DeleteFileA(msifile);
4614     DeleteFileA("msitest\\maximus");
4615     RemoveDirectoryA("msitest");
4616 }
4617 
4618 static void create_pf_data(LPCSTR file, LPCSTR data, BOOL is_file)
4619 {
4620     CHAR path[MAX_PATH];
4621 
4622     lstrcpyA(path, PROG_FILES_DIR);
4623     lstrcatA(path, "\\");
4624     lstrcatA(path, file);
4625 
4626     if (is_file)
4627         create_file_data(path, data, 500);
4628     else
4629         CreateDirectoryA(path, NULL);
4630 }
4631 
4632 #define create_pf(file, is_file) create_pf_data(file, file, is_file)
4633 
4634 static void test_remove_files(void)
4635 {
4636     UINT r;
4637 
4638     if (is_process_limited())
4639     {
4640         skip("process is limited\n");
4641         return;
4642     }
4643 
4644     CreateDirectoryA("msitest", NULL);
4645     create_file("msitest\\hydrogen", 500);
4646     create_file("msitest\\helium", 500);
4647     create_file("msitest\\lithium", 500);
4648 
4649     create_database(msifile, rem_tables, sizeof(rem_tables) / sizeof(msi_table));
4650 
4651     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4652 
4653     r = MsiInstallProductA(msifile, NULL);
4654     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4655     {
4656         skip("Not enough rights to perform tests\n");
4657         goto error;
4658     }
4659     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4660     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4661     ok(!pf_exists("msitest\\helium"), "File installed\n");
4662     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4663     ok(pf_exists("msitest"), "File not installed\n");
4664 
4665     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4666     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4667     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4668     ok(!pf_exists("msitest\\helium"), "File not deleted\n");
4669     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4670     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4671 
4672     create_pf("msitest", FALSE);
4673     create_pf("msitest\\hydrogen", TRUE);
4674     create_pf("msitest\\helium", TRUE);
4675     create_pf("msitest\\lithium", TRUE);
4676 
4677     r = MsiInstallProductA(msifile, NULL);
4678     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4679     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4680     ok(pf_exists("msitest\\helium"), "File not installed\n");
4681     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4682     ok(pf_exists("msitest"), "File not installed\n");
4683 
4684     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4685     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4686     ok(!pf_exists("msitest\\hydrogen"), "File not deleted\n");
4687     ok(delete_pf("msitest\\helium", TRUE), "File deleted\n");
4688     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4689     ok(delete_pf("msitest", FALSE), "Directory deleted\n");
4690 
4691     create_pf("msitest", FALSE);
4692     create_pf("msitest\\furlong", TRUE);
4693     create_pf("msitest\\firkin", TRUE);
4694     create_pf("msitest\\fortnight", TRUE);
4695     create_pf("msitest\\becquerel", TRUE);
4696     create_pf("msitest\\dioptre", TRUE);
4697     create_pf("msitest\\attoparsec", TRUE);
4698     create_pf("msitest\\storeys", TRUE);
4699     create_pf("msitest\\block", TRUE);
4700     create_pf("msitest\\siriometer", TRUE);
4701     create_pf("msitest\\cabout", FALSE);
4702     create_pf("msitest\\cabout\\blocker", TRUE);
4703 
4704     r = MsiInstallProductA(msifile, NULL);
4705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4706     ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
4707     ok(!pf_exists("msitest\\helium"), "File installed\n");
4708     ok(pf_exists("msitest\\lithium"), "File not installed\n");
4709     ok(!pf_exists("msitest\\furlong"), "File not deleted\n");
4710     ok(!pf_exists("msitest\\firkin"), "File not deleted\n");
4711     ok(!pf_exists("msitest\\fortnight"), "File not deleted\n");
4712     ok(pf_exists("msitest\\becquerel"), "File not installed\n");
4713     ok(pf_exists("msitest\\dioptre"), "File not installed\n");
4714     ok(pf_exists("msitest\\attoparsec"), "File not installed\n");
4715     ok(!pf_exists("msitest\\storeys"), "File not deleted\n");
4716     ok(!pf_exists("msitest\\block"), "File not deleted\n");
4717     ok(!pf_exists("msitest\\siriometer"), "File not deleted\n");
4718     ok(pf_exists("msitest\\cabout"), "Directory removed\n");
4719     ok(pf_exists("msitest"), "File not installed\n");
4720 
4721     create_pf("msitest\\furlong", TRUE);
4722     create_pf("msitest\\firkin", TRUE);
4723     create_pf("msitest\\fortnight", TRUE);
4724     create_pf("msitest\\storeys", TRUE);
4725     create_pf("msitest\\block", TRUE);
4726     create_pf("msitest\\siriometer", TRUE);
4727 
4728     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4730     ok(!delete_pf("msitest\\hydrogen", TRUE), "File not deleted\n");
4731     ok(!delete_pf("msitest\\helium", TRUE), "File not deleted\n");
4732     ok(delete_pf("msitest\\lithium", TRUE), "File deleted\n");
4733     ok(delete_pf("msitest\\furlong", TRUE), "File deleted\n");
4734     ok(delete_pf("msitest\\firkin", TRUE), "File deleted\n");
4735     ok(delete_pf("msitest\\fortnight", TRUE), "File deleted\n");
4736     ok(!delete_pf("msitest\\becquerel", TRUE), "File not deleted\n");
4737     ok(!delete_pf("msitest\\dioptre", TRUE), "File not deleted\n");
4738     ok(delete_pf("msitest\\attoparsec", TRUE), "File deleted\n");
4739     ok(!delete_pf("msitest\\storeys", TRUE), "File not deleted\n");
4740     ok(!delete_pf("msitest\\block", TRUE), "File not deleted\n");
4741     ok(delete_pf("msitest\\siriometer", TRUE), "File deleted\n");
4742     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4743     ok(pf_exists("msitest"), "Directory deleted\n");
4744 
4745     r = MsiInstallProductA(msifile, NULL);
4746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4747     ok(delete_pf("msitest\\hydrogen", TRUE), "File not installed\n");
4748     ok(!delete_pf("msitest\\helium", TRUE), "File installed\n");
4749     ok(delete_pf("msitest\\lithium", TRUE), "File not installed\n");
4750     ok(pf_exists("msitest\\cabout"), "Directory deleted\n");
4751     ok(pf_exists("msitest"), "Directory deleted\n");
4752 
4753     delete_pf("msitest\\cabout\\blocker", TRUE);
4754 
4755     r = MsiInstallProductA(msifile, "REMOVE=ALL");
4756     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4757     ok(!delete_pf("msitest\\cabout", FALSE), "Directory not deleted\n");
4758     delete_pf("msitest", FALSE);
4759 
4760 error:
4761     DeleteFileA(msifile);
4762     DeleteFileA("msitest\\hydrogen");
4763     DeleteFileA("msitest\\helium");
4764     DeleteFileA("msitest\\lithium");
4765     RemoveDirectoryA("msitest");
4766 }
4767 
4768 static void test_move_files(void)
4769 {
4770     UINT r;
4771     char props[MAX_PATH];
4772 
4773     if (is_process_limited())
4774     {
4775         skip("process is limited\n");
4776         return;
4777     }
4778 
4779     CreateDirectoryA("msitest", NULL);
4780     create_file("msitest\\augustus", 100);
4781     create_file("cameroon", 100);
4782     create_file("djibouti", 100);
4783     create_file("egypt", 100);
4784     create_file("finland", 100);
4785     create_file("gambai", 100);
4786     create_file("honduras", 100);
4787     create_file("msitest\\india", 100);
4788     create_file("japan", 100);
4789     create_file("kenya", 100);
4790     CreateDirectoryA("latvia", NULL);
4791     create_file("nauru", 100);
4792     create_file("peru", 100);
4793     create_file("apple", 100);
4794     create_file("application", 100);
4795     create_file("ape", 100);
4796     create_file("foo", 100);
4797     create_file("fao", 100);
4798     create_file("fbod", 100);
4799     create_file("budding", 100);
4800     create_file("buddy", 100);
4801     create_file("bud", 100);
4802     create_file("bar", 100);
4803     create_file("bur", 100);
4804     create_file("bird", 100);
4805 
4806     create_database(msifile, mov_tables, sizeof(mov_tables) / sizeof(msi_table));
4807 
4808     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4809 
4810     /* if the source or dest property is not a full path,
4811      * windows tries to access it as a network resource
4812      */
4813 
4814     sprintf(props, "SOURCEFULL=\"%s\\\" DESTFULL=\"%s\\msitest\" "
4815             "FILEPATHBAD=\"%s\\japan\" FILEPATHGOOD=\"%s\\kenya\"",
4816             CURR_DIR, PROG_FILES_DIR, CURR_DIR, CURR_DIR);
4817 
4818     r = MsiInstallProductA(msifile, props);
4819     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4820     {
4821         skip("Not enough rights to perform tests\n");
4822         goto error;
4823     }
4824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4825     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
4826     ok(!delete_pf("msitest\\dest", TRUE), "File copied\n");
4827     ok(delete_pf("msitest\\canada", TRUE), "File not copied\n");
4828     ok(delete_pf("msitest\\dominica", TRUE), "File not moved\n");
4829     ok(!delete_pf("msitest\\elsalvador", TRUE), "File moved\n");
4830     ok(!delete_pf("msitest\\france", TRUE), "File moved\n");
4831     ok(!delete_pf("msitest\\georgia", TRUE), "File moved\n");
4832     ok(delete_pf("msitest\\hungary", TRUE), "File not moved\n");
4833     ok(!delete_pf("msitest\\indonesia", TRUE), "File moved\n");
4834     ok(!delete_pf("msitest\\jordan", TRUE), "File moved\n");
4835     ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n");
4836     ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n");
4837     ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n");
4838     ok(delete_pf("msitest\\poland", TRUE), "File not moved\n");
4839     /* either apple or application will be moved depending on directory order */
4840     if (!delete_pf("msitest\\apple", TRUE))
4841         ok(delete_pf("msitest\\application", TRUE), "File not moved\n");
4842     else
4843         ok(!delete_pf("msitest\\application", TRUE), "File should not exist\n");
4844     ok(delete_pf("msitest\\wildcard", TRUE), "File not moved\n");
4845     ok(!delete_pf("msitest\\ape", TRUE), "File moved\n");
4846     /* either fao or foo will be moved depending on directory order */
4847     if (delete_pf("msitest\\foo", TRUE))
4848         ok(!delete_pf("msitest\\fao", TRUE), "File should not exist\n");
4849     else
4850         ok(delete_pf("msitest\\fao", TRUE), "File not moved\n");
4851     ok(delete_pf("msitest\\single", TRUE), "File not moved\n");
4852     ok(!delete_pf("msitest\\fbod", TRUE), "File moved\n");
4853     ok(delete_pf("msitest\\budding", TRUE), "File not moved\n");
4854     ok(delete_pf("msitest\\buddy", TRUE), "File not moved\n");
4855     ok(!delete_pf("msitest\\bud", TRUE), "File moved\n");
4856     ok(delete_pf("msitest\\bar", TRUE), "File not moved\n");
4857     ok(delete_pf("msitest\\bur", TRUE), "File not moved\n");
4858     ok(!delete_pf("msitest\\bird", TRUE), "File moved\n");
4859     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4860     ok(DeleteFileA("cameroon"), "File moved\n");
4861     ok(!DeleteFileA("djibouti"), "File not moved\n");
4862     ok(DeleteFileA("egypt"), "File moved\n");
4863     ok(DeleteFileA("finland"), "File moved\n");
4864     ok(DeleteFileA("gambai"), "File moved\n");
4865     ok(!DeleteFileA("honduras"), "File not moved\n");
4866     ok(DeleteFileA("msitest\\india"), "File moved\n");
4867     ok(DeleteFileA("japan"), "File moved\n");
4868     ok(!DeleteFileA("kenya"), "File not moved\n");
4869     ok(RemoveDirectoryA("latvia"), "Directory moved\n");
4870     ok(!DeleteFileA("nauru"), "File not moved\n");
4871     ok(!DeleteFileA("peru"), "File not moved\n");
4872     ok(!DeleteFileA("apple"), "File not moved\n");
4873     ok(!DeleteFileA("application"), "File not moved\n");
4874     ok(DeleteFileA("ape"), "File moved\n");
4875     ok(!DeleteFileA("foo"), "File not moved\n");
4876     ok(!DeleteFileA("fao"), "File not moved\n");
4877     ok(DeleteFileA("fbod"), "File moved\n");
4878     ok(!DeleteFileA("budding"), "File not moved\n");
4879     ok(!DeleteFileA("buddy"), "File not moved\n");
4880     ok(DeleteFileA("bud"), "File moved\n");
4881     ok(!DeleteFileA("bar"), "File not moved\n");
4882     ok(!DeleteFileA("bur"), "File not moved\n");
4883     ok(DeleteFileA("bird"), "File moved\n");
4884 
4885 error:
4886     DeleteFileA("cameroon");
4887     DeleteFileA("djibouti");
4888     DeleteFileA("egypt");
4889     DeleteFileA("finland");
4890     DeleteFileA("gambai");
4891     DeleteFileA("honduras");
4892     DeleteFileA("japan");
4893     DeleteFileA("kenya");
4894     DeleteFileA("nauru");
4895     DeleteFileA("peru");
4896     DeleteFileA("apple");
4897     DeleteFileA("application");
4898     DeleteFileA("ape");
4899     DeleteFileA("foo");
4900     DeleteFileA("fao");
4901     DeleteFileA("fbod");
4902     DeleteFileA("budding");
4903     DeleteFileA("buddy");
4904     DeleteFileA("bud");
4905     DeleteFileA("bar");
4906     DeleteFileA("bur");
4907     DeleteFileA("bird");
4908     DeleteFileA("msitest\\india");
4909     DeleteFileA("msitest\\augustus");
4910     RemoveDirectoryA("latvia");
4911     RemoveDirectoryA("msitest");
4912     DeleteFileA(msifile);
4913 }
4914 
4915 static void test_duplicate_files(void)
4916 {
4917     UINT r;
4918 
4919     if (is_process_limited())
4920     {
4921         skip("process is limited\n");
4922         return;
4923     }
4924 
4925     CreateDirectoryA("msitest", NULL);
4926     create_file("msitest\\maximus", 500);
4927     create_database(msifile, df_tables, sizeof(df_tables) / sizeof(msi_table));
4928 
4929     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4930 
4931     /* fails if the destination folder is not a valid property */
4932 
4933     r = MsiInstallProductA(msifile, NULL);
4934     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
4935     {
4936         skip("Not enough rights to perform tests\n");
4937         goto error;
4938     }
4939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
4940     ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
4941     ok(delete_pf("msitest\\augustus", TRUE), "File not duplicated\n");
4942     ok(delete_pf("msitest\\this\\doesnot\\exist\\maximus", TRUE), "File not duplicated\n");
4943     ok(delete_pf("msitest\\this\\doesnot\\exist", FALSE), "Directory not created\n");
4944     ok(delete_pf("msitest\\this\\doesnot", FALSE), "Directory not created\n");
4945     ok(delete_pf("msitest\\this", FALSE), "Directory not created\n");
4946     ok(delete_pf("msitest", FALSE), "Directory not created\n");
4947 
4948 error:
4949     DeleteFileA("msitest\\maximus");
4950     RemoveDirectoryA("msitest");
4951     DeleteFileA(msifile);
4952 }
4953 
4954 static void test_write_registry_values(void)
4955 {
4956     UINT r;
4957     LONG res;
4958     HKEY hkey;
4959     DWORD type, size;
4960     CHAR path[MAX_PATH];
4961     BYTE buf[8];
4962 
4963     if (is_process_limited())
4964     {
4965         skip("process is limited\n");
4966         return;
4967     }
4968 
4969     CreateDirectoryA("msitest", NULL);
4970     create_file("msitest\\augustus", 500);
4971 
4972     create_database(msifile, wrv_tables, sizeof(wrv_tables) / sizeof(msi_table));
4973 
4974     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
4975 
4976     if (is_64bit)
4977         res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Wine\\msitest", 0, NULL, 0,
4978                               KEY_ALL_ACCESS, NULL, &hkey, NULL);
4979     else
4980         res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", 0, NULL, 0, KEY_ALL_ACCESS,
4981                               NULL, &hkey, NULL);
4982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4983 
4984     res = RegSetValueExA(hkey, "Value1", 0, REG_MULTI_SZ, (const BYTE *)"two\0", 5);
4985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4986     res = RegSetValueExA(hkey, "Value2", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
4987     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4988     res = RegSetValueExA(hkey, "Value3", 0, REG_MULTI_SZ, (const BYTE *)"two\0", 5);
4989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4990     res = RegSetValueExA(hkey, "Value4", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
4991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4992     res = RegSetValueExA(hkey, "Value5", 0, REG_MULTI_SZ, (const BYTE *)"one\0two\0", 9);
4993     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4994     res = RegSetValueExA(hkey, "Value6", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
4995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4996     res = RegSetValueExA(hkey, "Value7", 0, REG_SZ, (const BYTE *)"one", 4);
4997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4998     RegCloseKey(hkey);
4999 
5000     r = MsiInstallProductA(msifile, NULL);
5001     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5002     {
5003         skip("Not enough rights to perform tests\n");
5004         goto error;
5005     }
5006     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5007     ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
5008     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5009 
5010     if (is_64bit)
5011         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey);
5012     else
5013         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", 0, KEY_ALL_ACCESS, &hkey);
5014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5015 
5016     size = MAX_PATH;
5017     type = 0xdeadbeef;
5018     memset(path, 'a', MAX_PATH);
5019     res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size);
5020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5021     ok(!memcmp(path, "one\0two\0three\0\0", size), "Wrong multi-sz data\n");
5022     ok(size == 15, "Expected 15, got %d\n", size);
5023     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5024 
5025     res = RegQueryValueExA(hkey, "", NULL, NULL, NULL, NULL);
5026     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5027 
5028     res = action_RegDeleteTreeA(hkey, "VisualStudio", KEY_ALL_ACCESS);
5029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5030 
5031     size = MAX_PATH;
5032     type = 0xdeadbeef;
5033     memset(path, 'a', MAX_PATH);
5034     res = RegQueryValueExA(hkey, "Value1", NULL, &type, (LPBYTE)path, &size);
5035     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5036     ok(!memcmp(path, "one\0", size), "Wrong multi-sz data\n");
5037     ok(size == 5, "Expected 5, got %d\n", size);
5038     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5039 
5040     size = MAX_PATH;
5041     type = 0xdeadbeef;
5042     memset(path, 'a', MAX_PATH);
5043     res = RegQueryValueExA(hkey, "Value2", NULL, &type, (LPBYTE)path, &size);
5044     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5045     ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
5046     ok(size == 9, "Expected 9, got %d\n", size);
5047     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5048 
5049     size = MAX_PATH;
5050     type = 0xdeadbeef;
5051     memset(path, 'a', MAX_PATH);
5052     res = RegQueryValueExA(hkey, "Value3", NULL, &type, (LPBYTE)path, &size);
5053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5054     ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
5055     ok(size == 9, "Expected 9, got %d\n", size);
5056     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5057 
5058     size = MAX_PATH;
5059     type = 0xdeadbeef;
5060     memset(path, 'a', MAX_PATH);
5061     res = RegQueryValueExA(hkey, "Value4", NULL, &type, (LPBYTE)path, &size);
5062     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5063     ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
5064     ok(size == 9, "Expected 9, got %d\n", size);
5065     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5066 
5067     size = MAX_PATH;
5068     type = 0xdeadbeef;
5069     memset(path, 'a', MAX_PATH);
5070     res = RegQueryValueExA(hkey, "Value5", NULL, &type, (LPBYTE)path, &size);
5071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5072     ok(!memcmp(path, "one\0two\0three\0", size), "Wrong multi-sz data\n");
5073     ok(size == 15, "Expected 15, got %d\n", size);
5074     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5075 
5076     size = MAX_PATH;
5077     type = 0xdeadbeef;
5078     memset(path, 'a', MAX_PATH);
5079     res = RegQueryValueExA(hkey, "Value6", NULL, &type, (LPBYTE)path, &size);
5080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5081     ok(!memcmp(path, "", size), "Wrong multi-sz data\n");
5082     ok(size == 1, "Expected 1, got %d\n", size);
5083     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5084 
5085     size = MAX_PATH;
5086     type = 0xdeadbeef;
5087     memset(path, 'a', MAX_PATH);
5088     res = RegQueryValueExA(hkey, "Value7", NULL, &type, (LPBYTE)path, &size);
5089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5090     ok(!memcmp(path, "two\0", size), "Wrong multi-sz data\n");
5091     ok(size == 5, "Expected 5, got %d\n", size);
5092     ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
5093 
5094     size = sizeof(buf);
5095     type = 0xdeadbeef;
5096     memset(buf, 0, size);
5097     res = RegQueryValueExA(hkey, "Value8", NULL, &type, buf, &size);
5098     ok(res == ERROR_SUCCESS, "got %u\n", res);
5099     ok(*(DWORD *)buf == 1, "got %u\n", *(DWORD *)buf);
5100     ok(size == 4, "got %u\n", size);
5101     ok(type == REG_DWORD, "got %u\n", type);
5102 
5103     size = sizeof(buf);
5104     type = 0xdeadbeef;
5105     memset(buf, 0, size);
5106     res = RegQueryValueExA(hkey, "Value9", NULL, &type, buf, &size);
5107     ok(res == ERROR_SUCCESS, "got %u\n", res);
5108     ok(buf[0] == 1, "got %u\n", buf[0]);
5109     ok(size == 1, "got %u\n", size);
5110     ok(type == REG_BINARY, "got %u\n", type);
5111 
5112     size = sizeof(buf);
5113     type = 0xdeadbeef;
5114     memset(buf, 0, size);
5115     res = RegQueryValueExA(hkey, "Value10", NULL, &type, buf, &size);
5116     ok(res == ERROR_SUCCESS, "got %u\n", res);
5117     ok(buf[0] == 1, "got %u\n", buf[0]);
5118     ok(size == 1, "got %u\n", size);
5119     ok(type == REG_BINARY, "got %u\n", type);
5120 
5121     size = sizeof(buf);
5122     type = 0xdeadbeef;
5123     memset(buf, 0, size);
5124     res = RegQueryValueExA(hkey, "Value11", NULL, &type, buf, &size);
5125     ok(res == ERROR_SUCCESS, "got %u\n", res);
5126     ok(buf[0] == 1, "got %u\n", buf[0]);
5127     ok(size == 1, "got %u\n", size);
5128     ok(type == REG_BINARY, "got %u\n", type);
5129 
5130     size = sizeof(buf);
5131     type = 0xdeadbeef;
5132     memset(buf, 0, size);
5133     res = RegQueryValueExA(hkey, "Value12", NULL, &type, buf, &size);
5134     ok(res == ERROR_SUCCESS, "got %u\n", res);
5135     ok(*(DWORD *)buf == 1, "got %u\n", *(DWORD *)buf);
5136     ok(size == 4, "got %u\n", size);
5137     ok(type == REG_DWORD, "got %u\n", type);
5138 
5139     RegDeleteValueA(hkey, "Value");
5140     RegDeleteValueA(hkey, "Value1");
5141     RegDeleteValueA(hkey, "Value2");
5142     RegDeleteValueA(hkey, "Value3");
5143     RegDeleteValueA(hkey, "Value4");
5144     RegDeleteValueA(hkey, "Value5");
5145     RegDeleteValueA(hkey, "Value6");
5146     RegDeleteValueA(hkey, "Value7");
5147     RegDeleteValueA(hkey, "Value8");
5148     RegDeleteValueA(hkey, "Value9");
5149     RegDeleteValueA(hkey, "Value10");
5150     RegDeleteValueA(hkey, "Value11");
5151     RegDeleteValueA(hkey, "Value12");
5152     RegCloseKey(hkey);
5153     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
5154 
5155 error:
5156     DeleteFileA(msifile);
5157     DeleteFileA("msitest\\augustus");
5158     RemoveDirectoryA("msitest");
5159 }
5160 
5161 static void test_envvar(void)
5162 {
5163     static const char *results[] =
5164     {
5165         "1;2",    /* MSITESTVAR11 */
5166         "1",      /* MSITESTVAR12 */
5167         "1;2",    /* MSITESTVAR13 */
5168         ";1;",    /* MSITESTVAR14 */
5169         ";;1;;",  /* MSITESTVAR15 */
5170         " 1 ",    /* MSITESTVAR16 */
5171         ";;2;;1", /* MSITESTVAR17 */
5172         "1;;2;;", /* MSITESTVAR18 */
5173         "1",      /* MSITESTVAR19 */
5174         "1",      /* MSITESTVAR20 */
5175         "1",      /* MSITESTVAR21 */
5176         NULL
5177     };
5178     UINT r;
5179     HKEY env;
5180     LONG res;
5181     DWORD type, size;
5182     char buffer[16];
5183     UINT i;
5184 
5185     if (is_process_limited())
5186     {
5187         skip("process is limited\n");
5188         return;
5189     }
5190 
5191     create_test_files();
5192     create_database(msifile, env_tables, sizeof(env_tables) / sizeof(msi_table));
5193 
5194     res = RegCreateKeyExA(HKEY_CURRENT_USER, "Environment", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &env, NULL);
5195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5196 
5197     res = RegSetValueExA(env, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"0", 2);
5198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5199 
5200     res = RegSetValueExA(env, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"0", 2);
5201     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5202 
5203     res = RegSetValueExA(env, "MSITESTVAR21", 0, REG_SZ, (const BYTE *)"1", 2);
5204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5205 
5206     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5207 
5208     r = MsiInstallProductA(msifile, NULL);
5209     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5210     {
5211         skip("Not enough rights to perform tests\n");
5212         goto error;
5213     }
5214     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5215 
5216     type = REG_NONE;
5217     size = sizeof(buffer);
5218     buffer[0] = 0;
5219     res = RegQueryValueExA(env, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
5220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5221     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
5222     ok(!lstrcmpA(buffer, "1"), "Expected \"1\", got %s\n", buffer);
5223 
5224     res = RegDeleteValueA(env, "MSITESTVAR1");
5225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5226 
5227     type = REG_NONE;
5228     size = sizeof(buffer);
5229     buffer[0] = 0;
5230     res = RegQueryValueExA(env, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
5231     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5232     ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
5233     ok(!lstrcmpA(buffer, "1"), "Expected \"1\", got %s\n", buffer);
5234 
5235     res = RegDeleteValueA(env, "MSITESTVAR2");
5236     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5237 
5238     res = RegDeleteValueA(env, "MSITESTVAR3");
5239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5240 
5241     res = RegDeleteValueA(env, "MSITESTVAR4");
5242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5243 
5244     res = RegDeleteValueA(env, "MSITESTVAR5");
5245     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5246 
5247     res = RegDeleteValueA(env, "MSITESTVAR6");
5248     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5249 
5250     res = RegDeleteValueA(env, "MSITESTVAR7");
5251     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5252 
5253     res = RegDeleteValueA(env, "MSITESTVAR8");
5254     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5255 
5256     res = RegDeleteValueA(env, "MSITESTVAR9");
5257     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5258 
5259     res = RegDeleteValueA(env, "MSITESTVAR10");
5260     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
5261 
5262     i = 11;
5263     while (results[i - 11])
5264     {
5265         char name[20];
5266         sprintf(name, "MSITESTVAR%d", i);
5267 
5268         type = REG_NONE;
5269         size = sizeof(buffer);
5270         buffer[0] = 0;
5271         res = RegQueryValueExA(env, name, NULL, &type, (LPBYTE)buffer, &size);
5272         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
5273         ok(type == REG_SZ, "%d: Expected REG_SZ, got %u\n", i, type);
5274         ok(!lstrcmpA(buffer, results[i - 11]), "%d: Expected %s, got %s\n", i, results[i - 11], buffer);
5275 
5276         res = RegDeleteValueA(env, name);
5277         ok(res == ERROR_SUCCESS, "%d: Expected ERROR_SUCCESS, got %d\n", i, res);
5278         i++;
5279     }
5280 
5281     delete_pf("msitest\\cabout\\new\\five.txt", TRUE);
5282     delete_pf("msitest\\cabout\\new", FALSE);
5283     delete_pf("msitest\\cabout\\four.txt", TRUE);
5284     delete_pf("msitest\\cabout", FALSE);
5285     delete_pf("msitest\\changed\\three.txt", TRUE);
5286     delete_pf("msitest\\changed", FALSE);
5287     delete_pf("msitest\\first\\two.txt", TRUE);
5288     delete_pf("msitest\\first", FALSE);
5289     delete_pf("msitest\\filename", TRUE);
5290     delete_pf("msitest\\one.txt", TRUE);
5291     delete_pf("msitest\\service.exe", TRUE);
5292     delete_pf("msitest\\service2.exe", TRUE);
5293     delete_pf("msitest", FALSE);
5294 
5295 error:
5296     RegDeleteValueA(env, "MSITESTVAR1");
5297     RegDeleteValueA(env, "MSITESTVAR2");
5298     RegDeleteValueA(env, "MSITESTVAR21");
5299     RegCloseKey(env);
5300 
5301     delete_test_files();
5302     DeleteFileA(msifile);
5303 }
5304 
5305 static void test_create_remove_folder(void)
5306 {
5307     UINT r;
5308 
5309     if (is_process_limited())
5310     {
5311         skip("process is limited\n");
5312         return;
5313     }
5314 
5315     CreateDirectoryA("msitest", NULL);
5316     CreateDirectoryA("msitest\\first", NULL);
5317     CreateDirectoryA("msitest\\second", NULL);
5318     create_file("msitest\\first\\one.txt", 1000);
5319     create_file("msitest\\second\\two.txt", 1000);
5320     create_database(msifile, cf_tables, sizeof(cf_tables) / sizeof(msi_table));
5321 
5322     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5323 
5324     r = MsiInstallProductA(msifile, NULL);
5325     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5326     {
5327         skip("Not enough rights to perform tests\n");
5328         goto error;
5329     }
5330     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5331 
5332     ok(pf_exists("msitest\\first\\one.txt"), "file not installed\n");
5333     ok(pf_exists("msitest\\first"), "directory not created\n");
5334     ok(pf_exists("msitest\\second\\two.txt"), "file not installed\n");
5335     ok(pf_exists("msitest\\second"), "directory not created\n");
5336     ok(pf_exists("msitest\\third"), "directory not created\n");
5337     ok(pf_exists("msitest"), "directory not created\n");
5338 
5339     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5341 
5342     ok(!pf_exists("msitest\\first\\one.txt"), "file not removed\n");
5343     ok(!pf_exists("msitest\\first"), "directory not removed\n");
5344     ok(!pf_exists("msitest\\second\\two.txt"), "file not removed\n");
5345     ok(!pf_exists("msitest\\second"), "directory not removed\n");
5346     ok(!pf_exists("msitest\\third"), "directory not removed\n");
5347     todo_wine ok(!pf_exists("msitest"), "directory not removed\n");
5348 
5349 error:
5350     DeleteFileA("msitest\\first\\one.txt");
5351     DeleteFileA("msitest\\second\\two.txt");
5352     RemoveDirectoryA("msitest\\first");
5353     RemoveDirectoryA("msitest\\second");
5354     RemoveDirectoryA("msitest");
5355     DeleteFileA(msifile);
5356 }
5357 
5358 static void test_start_stop_services(void)
5359 {
5360     UINT r;
5361     SC_HANDLE scm, service;
5362     BOOL ret;
5363     DWORD error = ERROR_SUCCESS;
5364 
5365     scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5366     if (!scm && GetLastError() == ERROR_ACCESS_DENIED)
5367     {
5368         skip("Not enough rights to perform tests\n");
5369         return;
5370     }
5371     ok(scm != NULL, "Failed to open the SC Manager\n");
5372     if (!scm) return;
5373 
5374     service = OpenServiceA(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
5375     if (!service && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
5376     {
5377         win_skip("The 'Spooler' service does not exist\n");
5378         CloseServiceHandle(scm);
5379         return;
5380     }
5381     ok(service != NULL, "Failed to open Spooler, error %d\n", GetLastError());
5382     if (!service) {
5383         CloseServiceHandle(scm);
5384         return;
5385     }
5386 
5387     ret = StartServiceA(service, 0, NULL);
5388     if (!ret && (error = GetLastError()) != ERROR_SERVICE_ALREADY_RUNNING)
5389     {
5390         skip("Spooler service not available, skipping test\n");
5391         CloseServiceHandle(service);
5392         CloseServiceHandle(scm);
5393         return;
5394     }
5395 
5396     CloseServiceHandle(service);
5397     CloseServiceHandle(scm);
5398 
5399     create_test_files();
5400     create_database(msifile, sss_tables, sizeof(sss_tables) / sizeof(msi_table));
5401 
5402     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5403 
5404     r = MsiInstallProductA(msifile, NULL);
5405     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5406 
5407     if (error == ERROR_SUCCESS)
5408     {
5409         SERVICE_STATUS status;
5410 
5411         scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5412         service = OpenServiceA(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
5413 
5414         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
5415         ok(ret, "ControlService failed %u\n", GetLastError());
5416 
5417         CloseServiceHandle(service);
5418         CloseServiceHandle(scm);
5419     }
5420 
5421     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5423 
5424     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5425     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5426     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5427     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5428     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5429     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5430     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5431     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5432     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5433     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5434     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5435     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5436     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5437 
5438     if (error == ERROR_SUCCESS)
5439     {
5440         SERVICE_STATUS status;
5441 
5442         scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5443         service = OpenServiceA(scm, "Spooler", SC_MANAGER_ALL_ACCESS);
5444 
5445         ret = ControlService(service, SERVICE_CONTROL_STOP, &status);
5446         ok(ret, "ControlService failed %u\n", GetLastError());
5447 
5448         CloseServiceHandle(service);
5449         CloseServiceHandle(scm);
5450     }
5451 
5452     delete_test_files();
5453     DeleteFileA(msifile);
5454 }
5455 
5456 static void delete_test_service(const char *name)
5457 {
5458     BOOL ret;
5459     SC_HANDLE manager, service;
5460 
5461     manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5462     ok(manager != NULL, "can't open service manager\n");
5463     if (!manager) return;
5464 
5465     service = OpenServiceA(manager, name, GENERIC_ALL);
5466     if (service)
5467     {
5468         ret = DeleteService( service );
5469         ok( ret, "failed to delete service %u\n", GetLastError() );
5470         CloseServiceHandle(service);
5471     }
5472     CloseServiceHandle(manager);
5473 }
5474 
5475 static void test_delete_services(void)
5476 {
5477     UINT r;
5478     SC_HANDLE manager, service;
5479     DWORD error;
5480 
5481     if (is_process_limited())
5482     {
5483         skip("process is limited\n");
5484         return;
5485     }
5486 
5487     manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5488     ok(manager != NULL, "can't open service manager %u\n", GetLastError());
5489     if (!manager) return;
5490 
5491     service = CreateServiceA(manager, "TestService3", "TestService3",
5492         SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
5493         SERVICE_ERROR_NORMAL, "C:\\doesnt_exist.exe", NULL, NULL, NULL, NULL, NULL);
5494     ok(service != NULL, "can't create service %u\n", GetLastError());
5495     CloseServiceHandle(service);
5496     CloseServiceHandle(manager);
5497     if (!service) return;
5498 
5499     create_test_files();
5500     create_database(msifile, sds_tables, sizeof(sds_tables) / sizeof(msi_table));
5501 
5502     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5503 
5504     r = MsiInstallProductA(msifile, NULL);
5505     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5506     {
5507         skip("Not enough rights to perform tests\n");
5508         goto error;
5509     }
5510     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5511 
5512     manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5513     ok(manager != NULL, "can't open service manager\n");
5514     if (!manager) goto error;
5515 
5516     service = OpenServiceA(manager, "TestService3", GENERIC_ALL);
5517     error = GetLastError();
5518     ok(service == NULL, "TestService3 not deleted\n");
5519     ok(error == ERROR_SERVICE_DOES_NOT_EXIST, "wrong error %u\n", error);
5520     CloseServiceHandle(manager);
5521 
5522     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5524 
5525     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5526     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5527     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5528     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5529     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5530     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5531     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5532     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5533     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5534     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5535     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5536     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5537     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5538 
5539 error:
5540     delete_test_service("TestService");
5541     delete_test_service("TestService2");
5542     delete_test_service("TestService3");
5543     delete_test_files();
5544     DeleteFileA(msifile);
5545 }
5546 
5547 static void test_install_services(void)
5548 {
5549     UINT r;
5550     SC_HANDLE manager, service;
5551     LONG res;
5552     HKEY hKey;
5553     DWORD err_control, err_controlsize, err_controltype;
5554 
5555     if (is_process_limited())
5556     {
5557         skip("process is limited\n");
5558         return;
5559     }
5560 
5561     create_test_files();
5562     create_database(msifile, sis_tables, sizeof(sis_tables) / sizeof(msi_table));
5563 
5564     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5565 
5566     r = MsiInstallProductA(msifile, NULL);
5567     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5568     {
5569         skip("Not enough rights to perform tests\n");
5570         goto error;
5571     }
5572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5573 
5574     manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
5575     ok(manager != NULL, "can't open service manager\n");
5576     if (!manager) goto error;
5577 
5578     service = OpenServiceA(manager, "TestService", GENERIC_ALL);
5579     ok(service != NULL, "TestService not installed\n");
5580     CloseServiceHandle(service);
5581 
5582     service = OpenServiceA(manager, "TestService4", GENERIC_ALL);
5583     ok(service == NULL, "TestService4 installed\n");
5584 
5585     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\TestService", &hKey);
5586     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5587 
5588     if (res == ERROR_SUCCESS)
5589     {
5590         err_control = 0xBEEF;
5591         err_controltype = REG_DWORD;
5592         err_controlsize = sizeof(err_control);
5593         res = RegQueryValueExA(hKey, "ErrorControl", NULL, &err_controltype, (LPBYTE)&err_control, &err_controlsize);
5594         ok(err_control == 0, "TestService.ErrorControl wrong, expected 0, got %u\n", err_control);
5595         RegCloseKey(hKey);
5596     }
5597 
5598     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5599     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5600 
5601     service = OpenServiceA(manager, "TestService", GENERIC_ALL);
5602     ok(service != NULL, "TestService deleted\n");
5603     CloseServiceHandle(service);
5604     CloseServiceHandle(manager);
5605 
5606     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5607     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5608     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5609     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5610     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5611     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5612     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5613     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5614     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5615     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5616     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5617     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5618     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5619 
5620 error:
5621     delete_test_service("TestService");
5622     delete_test_files();
5623     DeleteFileA(msifile);
5624 }
5625 
5626 static void test_self_registration(void)
5627 {
5628     UINT r;
5629 
5630     if (is_process_limited())
5631     {
5632         skip("process is limited\n");
5633         return;
5634     }
5635 
5636     create_test_files();
5637     create_database(msifile, sr_tables, sizeof(sr_tables) / sizeof(msi_table));
5638 
5639     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5640 
5641     r = MsiInstallProductA(msifile, NULL);
5642     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5643     {
5644         skip("Not enough rights to perform tests\n");
5645         goto error;
5646     }
5647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5648 
5649     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5650     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5651     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5652     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5653     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5654     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5655     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5656     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5657     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5658     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5659     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5660     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5661     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5662 
5663 error:
5664     delete_test_files();
5665     DeleteFileA(msifile);
5666 }
5667 
5668 static void test_register_font(void)
5669 {
5670     static const char regfont1[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
5671     static const char regfont2[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts";
5672     LONG ret;
5673     HKEY key;
5674     UINT r;
5675     REGSAM access = KEY_ALL_ACCESS;
5676 
5677     if (is_process_limited())
5678     {
5679         skip("process is limited\n");
5680         return;
5681     }
5682 
5683     create_test_files();
5684     create_file("msitest\\font.ttf", 1000);
5685     create_database(msifile, font_tables, sizeof(font_tables) / sizeof(msi_table));
5686 
5687     if (is_wow64)
5688         access |= KEY_WOW64_64KEY;
5689 
5690     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5691 
5692     r = MsiInstallProductA(msifile, NULL);
5693     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5694     {
5695         skip("Not enough rights to perform tests\n");
5696         goto error;
5697     }
5698     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5699 
5700     ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont1, 0, access, &key);
5701     if (ret)
5702         RegOpenKeyExA(HKEY_LOCAL_MACHINE, regfont2, 0, access, &key);
5703 
5704     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
5705     ok(ret != ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
5706 
5707     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5708     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5709 
5710     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5711 
5712     ret = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
5713     ok(ret == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", ret);
5714 
5715     RegDeleteValueA(key, "msi test font");
5716     RegCloseKey(key);
5717 
5718 error:
5719     DeleteFileA("msitest\\font.ttf");
5720     delete_test_files();
5721     DeleteFileA(msifile);
5722 }
5723 
5724 static void test_validate_product_id(void)
5725 {
5726     UINT r;
5727 
5728     if (is_process_limited())
5729     {
5730         skip("process is limited\n");
5731         return;
5732     }
5733 
5734     create_test_files();
5735     create_database(msifile, vp_tables, sizeof(vp_tables) / sizeof(msi_table));
5736 
5737     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5738 
5739     r = MsiInstallProductA(msifile, NULL);
5740     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5741     {
5742         skip("Not enough rights to perform tests\n");
5743         goto error;
5744     }
5745     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5746 
5747     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=1");
5748     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5749 
5750     r = MsiInstallProductA(msifile, "SET_PRODUCT_ID=2");
5751     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5752 
5753     r = MsiInstallProductA(msifile, "PIDKEY=123-1234567");
5754     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5755 
5756     ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
5757     ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
5758     ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
5759     ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
5760     ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
5761     ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
5762     ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
5763     ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
5764     ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
5765     ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
5766     ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
5767     ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n");
5768     ok(delete_pf("msitest", FALSE), "Directory not created\n");
5769 
5770 error:
5771     delete_test_files();
5772     DeleteFileA(msifile);
5773 }
5774 
5775 static void test_install_remove_odbc(void)
5776 {
5777     UINT r;
5778 
5779     if (is_process_limited())
5780     {
5781         skip("process is limited\n");
5782         return;
5783     }
5784 
5785     create_test_files();
5786     create_file("msitest\\ODBCdriver.dll", 1000);
5787     create_file("msitest\\ODBCdriver2.dll", 1000);
5788     create_file("msitest\\ODBCtranslator.dll", 1000);
5789     create_file("msitest\\ODBCtranslator2.dll", 1000);
5790     create_file("msitest\\ODBCsetup.dll", 1000);
5791     create_database(msifile, odbc_tables, sizeof(odbc_tables) / sizeof(msi_table));
5792 
5793     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5794 
5795     r = MsiInstallProductA(msifile, NULL);
5796     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5797     {
5798         skip("Not enough rights to perform tests\n");
5799         goto error;
5800     }
5801     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5802 
5803     ok(pf_exists("msitest\\ODBCdriver.dll"), "file not created\n");
5804     ok(pf_exists("msitest\\ODBCdriver2.dll"), "file not created\n");
5805     ok(pf_exists("msitest\\ODBCtranslator.dll"), "file not created\n");
5806     ok(pf_exists("msitest\\ODBCtranslator2.dll"), "file not created\n");
5807     ok(pf_exists("msitest\\ODBCsetup.dll"), "file not created\n");
5808 
5809     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5811 
5812     ok(!delete_pf("msitest\\ODBCdriver.dll", TRUE), "file not removed\n");
5813     ok(!delete_pf("msitest\\ODBCdriver2.dll", TRUE), "file not removed\n");
5814     ok(!delete_pf("msitest\\ODBCtranslator.dll", TRUE), "file not removed\n");
5815     ok(!delete_pf("msitest\\ODBCtranslator2.dll", TRUE), "file not removed\n");
5816     ok(!delete_pf("msitest\\ODBCsetup.dll", TRUE), "file not removed\n");
5817     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5818 
5819 error:
5820     DeleteFileA("msitest\\ODBCdriver.dll");
5821     DeleteFileA("msitest\\ODBCdriver2.dll");
5822     DeleteFileA("msitest\\ODBCtranslator.dll");
5823     DeleteFileA("msitest\\ODBCtranslator2.dll");
5824     DeleteFileA("msitest\\ODBCsetup.dll");
5825     delete_test_files();
5826     DeleteFileA(msifile);
5827 }
5828 
5829 static void test_register_typelib(void)
5830 {
5831     UINT r;
5832 
5833     if (is_process_limited())
5834     {
5835         skip("process is limited\n");
5836         return;
5837     }
5838 
5839     create_test_files();
5840     create_file("msitest\\typelib.dll", 1000);
5841     create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
5842 
5843     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5844 
5845     r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
5846     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5847     {
5848         skip("Not enough rights to perform tests\n");
5849         goto error;
5850     }
5851     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
5852 
5853     r = MsiInstallProductA(msifile, NULL);
5854     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5855 
5856     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5857     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5858 
5859     ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
5860     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5861 
5862 error:
5863     DeleteFileA("msitest\\typelib.dll");
5864     delete_test_files();
5865     DeleteFileA(msifile);
5866 }
5867 
5868 static void test_create_remove_shortcut(void)
5869 {
5870     UINT r;
5871 
5872     if (is_process_limited())
5873     {
5874         skip("process is limited\n");
5875         return;
5876     }
5877 
5878     create_test_files();
5879     create_file("msitest\\target.txt", 1000);
5880     create_database(msifile, crs_tables, sizeof(crs_tables) / sizeof(msi_table));
5881 
5882     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5883 
5884     r = MsiInstallProductA(msifile, NULL);
5885     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5886     {
5887         skip("Not enough rights to perform tests\n");
5888         goto error;
5889     }
5890     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5891 
5892     ok(pf_exists("msitest\\target.txt"), "file not created\n");
5893     ok(pf_exists("msitest\\shortcut.lnk"), "file not created\n");
5894 
5895     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5897 
5898     ok(!delete_pf("msitest\\shortcut.lnk", TRUE), "file not removed\n");
5899     ok(!delete_pf("msitest\\target.txt", TRUE), "file not removed\n");
5900     todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5901 
5902 error:
5903     DeleteFileA("msitest\\target.txt");
5904     delete_test_files();
5905     DeleteFileA(msifile);
5906 }
5907 
5908 static void test_publish_components(void)
5909 {
5910     static const char keypath[] =
5911         "Software\\Microsoft\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
5912     static const char keypath2[] =
5913         "Software\\Classes\\Installer\\Components\\0CBCFA296AC907244845745CEEB2F8AA";
5914 
5915     UINT r;
5916     LONG res;
5917     HKEY key;
5918     BYTE *data;
5919     DWORD size;
5920 
5921     if (is_process_limited())
5922     {
5923         skip("process is limited\n");
5924         return;
5925     }
5926 
5927     create_test_files();
5928     create_file("msitest\\english.txt", 1000);
5929     create_database(msifile, pub_tables, sizeof(pub_tables) / sizeof(msi_table));
5930 
5931     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
5932 
5933     r = MsiInstallProductA(msifile, NULL);
5934     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
5935     {
5936         skip("Not enough rights to perform tests\n");
5937         goto error;
5938     }
5939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5940 
5941     size = 0;
5942     r = MsiProvideQualifiedComponentA("{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}",
5943             "english.txt", INSTALLMODE_DEFAULT, NULL, &size);
5944     ok(r == ERROR_SUCCESS, "MsiProvideQualifiedComponent returned %d\n", r);
5945 
5946     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
5947     ok(res == ERROR_SUCCESS, "components key not created %d\n", res);
5948 
5949     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, &size);
5950     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
5951 
5952     data = HeapAlloc(GetProcessHeap(), 0, size);
5953     res = RegQueryValueExA(key, "english.txt", NULL, NULL, data, &size);
5954     ok(res == ERROR_SUCCESS, "value not found %d\n", res);
5955     RegCloseKey(key);
5956 
5957     res = RegDeleteKeyA(HKEY_CURRENT_USER, keypath);
5958     ok(res == ERROR_SUCCESS, "RegDeleteKey failed %d\n", res);
5959 
5960     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, REG_OPTION_NON_VOLATILE,
5961             MAXIMUM_ALLOWED | KEY_WOW64_64KEY, NULL, &key, NULL );
5962     ok(res == ERROR_SUCCESS, "RegCreateKeyEx failed %d\n", res);
5963     res = RegSetValueExA(key, "english.txt", 0, REG_MULTI_SZ, data, size);
5964     ok(res == ERROR_SUCCESS, "RegSetValueEx failed %d\n", res);
5965     RegCloseKey(key);
5966 
5967     size = 0;
5968     r = MsiProvideQualifiedComponentA("{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}",
5969             "english.txt", INSTALLMODE_DEFAULT, NULL, &size);
5970     ok(r == ERROR_SUCCESS, "MsiProvideQualifiedComponent returned %d\n", r);
5971 
5972     if (pRegDeleteKeyExA)
5973         res = pRegDeleteKeyExA(HKEY_LOCAL_MACHINE, keypath2, KEY_WOW64_64KEY, 0);
5974     else
5975         res = RegDeleteKeyA(HKEY_LOCAL_MACHINE, keypath2);
5976     ok(res == ERROR_SUCCESS, "RegDeleteKey failed %d\n", res);
5977 
5978     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &key);
5979     ok(res == ERROR_SUCCESS, "RegCreateKey failed %d\n", res);
5980 
5981     res = RegSetValueExA(key, "english.txt", 0, REG_MULTI_SZ, data, size);
5982     ok(res == ERROR_SUCCESS, "RegSetValueEx failed %d\n", res);
5983     HeapFree(GetProcessHeap(), 0, data);
5984     RegCloseKey(key);
5985 
5986     r = MsiInstallProductA(msifile, "REMOVE=ALL");
5987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
5988 
5989     res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key);
5990     ok(res == ERROR_FILE_NOT_FOUND, "unexpected result %d\n", res);
5991 
5992     ok(!delete_pf("msitest\\english.txt", TRUE), "file not removed\n");
5993     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
5994 
5995 error:
5996     DeleteFileA("msitest\\english.txt");
5997     delete_test_files();
5998     DeleteFileA(msifile);
5999 }
6000 
6001 static void test_remove_duplicate_files(void)
6002 {
6003     UINT r;
6004 
6005     if (is_process_limited())
6006     {
6007         skip("process is limited\n");
6008         return;
6009     }
6010 
6011     create_test_files();
6012     create_file("msitest\\original.txt", 1000);
6013     create_file("msitest\\original2.txt", 1000);
6014     create_file("msitest\\original3.txt", 1000);
6015     create_database(msifile, rd_tables, sizeof(rd_tables) / sizeof(msi_table));
6016 
6017     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6018 
6019     r = MsiInstallProductA(msifile, NULL);
6020     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6021     {
6022         skip("Not enough rights to perform tests\n");
6023         goto error;
6024     }
6025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6026 
6027     ok(pf_exists("msitest\\original.txt"), "file not created\n");
6028     ok(pf_exists("msitest\\original2.txt"), "file not created\n");
6029     ok(!pf_exists("msitest\\original3.txt"), "file created\n");
6030     ok(pf_exists("msitest\\duplicate.txt"), "file not created\n");
6031     ok(!pf_exists("msitest\\duplicate2.txt"), "file created\n");
6032 
6033     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6034     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6035 
6036     ok(delete_pf("msitest\\original.txt", TRUE), "file removed\n");
6037     ok(!delete_pf("msitest\\original2.txt", TRUE), "file not removed\n");
6038     ok(!delete_pf("msitest\\original3.txt", TRUE), "file not removed\n");
6039     ok(!delete_pf("msitest\\duplicate.txt", TRUE), "file not removed\n");
6040     ok(!delete_pf("msitest\\duplicate2.txt", TRUE), "file not removed\n");
6041     ok(delete_pf("msitest", FALSE), "directory removed\n");
6042 
6043 error:
6044     DeleteFileA("msitest\\original.txt");
6045     DeleteFileA("msitest\\original2.txt");
6046     DeleteFileA("msitest\\original3.txt");
6047     delete_test_files();
6048     DeleteFileA(msifile);
6049 }
6050 
6051 static void test_remove_registry_values(void)
6052 {
6053     UINT r;
6054     LONG res;
6055     HKEY key;
6056     REGSAM access = KEY_ALL_ACCESS;
6057 
6058     if (is_process_limited())
6059     {
6060         skip("process is limited\n");
6061         return;
6062     }
6063 
6064     create_test_files();
6065     create_file("msitest\\registry.txt", 1000);
6066     create_database(msifile, rrv_tables, sizeof(rrv_tables) / sizeof(msi_table));
6067 
6068     if (is_wow64)
6069         access |= KEY_WOW64_64KEY;
6070 
6071     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6072 
6073     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, NULL, 0, access, NULL, &key, NULL);
6074     RegSetValueExA(key, "value1", 0, REG_SZ, (const BYTE *)"1", 2);
6075     RegCloseKey(key);
6076 
6077     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL);
6078     RegSetValueExA(key, "value2", 0, REG_SZ, (const BYTE *)"2", 2);
6079     RegCloseKey(key);
6080 
6081     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, NULL, 0, access, NULL, &key, NULL);
6082     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
6083     RegSetValueExA(key, "valueA", 0, REG_SZ, (const BYTE *)"A", 2);
6084     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
6085     RegCloseKey(key);
6086 
6087     RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, NULL, 0, access, NULL, &key, NULL);
6088     RegSetValueExA(key, "", 0, REG_SZ, (const BYTE *)"default", 8);
6089     RegSetValueExA(key, "valueB", 0, REG_SZ, (const BYTE *)"B", 2);
6090     RegCloseKey(key);
6091 
6092     r = MsiInstallProductA(msifile, NULL);
6093     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6094     {
6095         skip("Not enough rights to perform tests\n");
6096         goto error;
6097     }
6098     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6099 
6100     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, access, &key);
6101     ok(res == ERROR_SUCCESS, "key removed\n");
6102     RegCloseKey(key);
6103 
6104     if (is_64bit)
6105     {
6106         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key2", 0, KEY_ALL_ACCESS, &key);
6107         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6108     }
6109     else
6110     {
6111         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, KEY_ALL_ACCESS, &key);
6112         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6113     }
6114 
6115     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, NULL, 0, access, NULL, &key, NULL);
6116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6117     RegCloseKey(key);
6118 
6119     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6121 
6122     if (is_64bit)
6123     {
6124         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\key1", 0, KEY_ALL_ACCESS, &key);
6125         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6126     }
6127     else
6128     {
6129         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", 0, KEY_ALL_ACCESS, &key);
6130         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6131     }
6132 
6133     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", 0, access, &key);
6134     ok(res == ERROR_SUCCESS, "key removed\n");
6135     RegCloseKey(key);
6136 
6137     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", 0, access, &key);
6138     ok(res == ERROR_SUCCESS, "key removed\n");
6139     RegCloseKey(key);
6140 
6141     if (is_64bit)
6142     {
6143         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key);
6144         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6145     }
6146     else
6147     {
6148         res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", 0, KEY_ALL_ACCESS, &key);
6149         ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6150     }
6151 
6152     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access);
6153     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access);
6154     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine", access);
6155 
6156     ok(!delete_pf("msitest\\registry.txt", TRUE), "file not removed\n");
6157     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6158 
6159 error:
6160     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key1", access);
6161     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\key2", access);
6162     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyA", access);
6163     delete_key(HKEY_LOCAL_MACHINE, "Software\\Wine\\keyB", access);
6164 
6165     DeleteFileA("msitest\\registry.txt");
6166     delete_test_files();
6167     DeleteFileA(msifile);
6168 }
6169 
6170 static void test_find_related_products(void)
6171 {
6172     UINT r;
6173 
6174     if (is_process_limited())
6175     {
6176         skip("process is limited\n");
6177         return;
6178     }
6179 
6180     create_test_files();
6181     create_file("msitest\\product.txt", 1000);
6182     create_database(msifile, frp_tables, sizeof(frp_tables) / sizeof(msi_table));
6183 
6184     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6185 
6186     r = MsiInstallProductA(msifile, NULL);
6187     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6188     {
6189         skip("Not enough rights to perform tests\n");
6190         goto error;
6191     }
6192     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6193 
6194     /* install again, so it finds the upgrade code */
6195     r = MsiInstallProductA(msifile, NULL);
6196     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6197 
6198     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6200 
6201     ok(!delete_pf("msitest\\product.txt", TRUE), "file not removed\n");
6202     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6203 
6204 error:
6205     DeleteFileA("msitest\\product.txt");
6206     delete_test_files();
6207     DeleteFileA(msifile);
6208 }
6209 
6210 static void test_remove_ini_values(void)
6211 {
6212     UINT r;
6213     DWORD len;
6214     char inifile[MAX_PATH], buf[0x10];
6215     HANDLE file;
6216     BOOL ret;
6217 
6218     if (is_process_limited())
6219     {
6220         skip("process is limited\n");
6221         return;
6222     }
6223 
6224     create_test_files();
6225     create_file("msitest\\inifile.txt", 1000);
6226     create_database(msifile, riv_tables, sizeof(riv_tables) / sizeof(msi_table));
6227 
6228     lstrcpyA(inifile, PROG_FILES_DIR);
6229     lstrcatA(inifile, "\\msitest");
6230     ret = CreateDirectoryA(inifile, NULL);
6231     if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
6232     {
6233         skip("Not enough rights to perform tests\n");
6234         goto error;
6235     }
6236     lstrcatA(inifile, "\\test.ini");
6237     file = CreateFileA(inifile, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, 0, NULL);
6238     CloseHandle(file);
6239 
6240     ret = WritePrivateProfileStringA("section1", "key1", "value1", inifile);
6241     ok(ret, "failed to write profile string %u\n", GetLastError());
6242 
6243     ret = WritePrivateProfileStringA("sectionA", "keyA", "valueA", inifile);
6244     ok(ret, "failed to write profile string %u\n", GetLastError());
6245 
6246     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6247 
6248     r = MsiInstallProductA(msifile, NULL);
6249     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6250 
6251     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
6252     ok(len == 6, "got %u expected 6\n", len);
6253 
6254     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
6255     ok(!len, "got %u expected 0\n", len);
6256 
6257     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6259 
6260     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), inifile);
6261     ok(!len, "got %u expected 0\n", len);
6262 
6263     len = GetPrivateProfileStringA("sectionA", "keyA", NULL, buf, sizeof(buf), inifile);
6264     ok(!len, "got %u expected 0\n", len);
6265 
6266     todo_wine ok(!delete_pf("msitest\\test.ini", TRUE), "file removed\n");
6267     ok(!delete_pf("msitest\\inifile.txt", TRUE), "file not removed\n");
6268     ok(delete_pf("msitest", FALSE), "directory removed\n");
6269 
6270 error:
6271     DeleteFileA("msitest\\inifile.txt");
6272     delete_test_files();
6273     DeleteFileA(msifile);
6274 }
6275 
6276 static void test_remove_env_strings(void)
6277 {
6278     UINT r;
6279     LONG res;
6280     HKEY key;
6281     DWORD type, size;
6282     char buffer[0x10];
6283 
6284     if (is_process_limited())
6285     {
6286         skip("process is limited\n");
6287         return;
6288     }
6289 
6290     create_test_files();
6291     create_file("msitest\\envvar.txt", 1000);
6292     create_database(msifile, res_tables, sizeof(res_tables) / sizeof(msi_table));
6293 
6294     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6295 
6296     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
6297     ok(!res, "failed to open environment key %d\n", res);
6298 
6299     RegSetValueExA(key, "MSITESTVAR1", 0, REG_SZ, (const BYTE *)"1", 2);
6300     RegSetValueExA(key, "MSITESTVAR2", 0, REG_SZ, (const BYTE *)"1", 2);
6301     RegSetValueExA(key, "MSITESTVAR3", 0, REG_SZ, (const BYTE *)"1", 2);
6302     RegSetValueExA(key, "MSITESTVAR4", 0, REG_SZ, (const BYTE *)"1", 2);
6303     RegSetValueExA(key, "MSITESTVAR5", 0, REG_SZ, (const BYTE *)"1", 2);
6304     RegSetValueExA(key, "MSITESTVAR6", 0, REG_SZ, (const BYTE *)"1;2", 4);
6305     RegSetValueExA(key, "MSITESTVAR7", 0, REG_SZ, (const BYTE *)"1;2", 4);
6306     RegSetValueExA(key, "MSITESTVAR8", 0, REG_SZ, (const BYTE *)"2;1;0", 6);
6307     RegSetValueExA(key, "MSITESTVAR9", 0, REG_SZ, (const BYTE *)"0;1;2", 6);
6308     RegSetValueExA(key, "MSITESTVAR10", 0, REG_SZ, (const BYTE *)"1", 2);
6309     RegSetValueExA(key, "MSITESTVAR11", 0, REG_SZ, (const BYTE *)"1", 2);
6310 
6311     RegCloseKey(key);
6312 
6313     r = MsiInstallProductA(msifile, NULL);
6314     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6315     {
6316         skip("Not enough rights to perform tests\n");
6317         goto error;
6318     }
6319     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6320 
6321     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
6322     ok(!res, "failed to open environment key %d\n", res);
6323 
6324     type = REG_NONE;
6325     buffer[0] = 0;
6326     size = sizeof(buffer);
6327     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, &type, (LPBYTE)buffer, &size);
6328     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6329     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6330     ok(!lstrcmpA(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
6331 
6332     type = REG_NONE;
6333     buffer[0] = 0;
6334     size = sizeof(buffer);
6335     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, &type, (LPBYTE)buffer, &size);
6336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6337     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6338     ok(!lstrcmpA(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
6339 
6340     type = REG_NONE;
6341     buffer[0] = 0;
6342     size = sizeof(buffer);
6343     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
6344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6345     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6346     ok(!lstrcmpA(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
6347 
6348     type = REG_NONE;
6349     buffer[0] = 0;
6350     size = sizeof(buffer);
6351     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, &type, (LPBYTE)buffer, &size);
6352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6353     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6354     ok(!lstrcmpA(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
6355 
6356     type = REG_NONE;
6357     buffer[0] = 0;
6358     size = sizeof(buffer);
6359     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
6360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6361     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6362     ok(!lstrcmpA(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
6363 
6364     RegCloseKey(key);
6365 
6366     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6367     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6368 
6369     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
6370     ok(!res, "failed to open environment key %d\n", res);
6371 
6372     res = RegQueryValueExA(key, "MSITESTVAR1", NULL, NULL, NULL, NULL);
6373     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6374 
6375     res = RegQueryValueExA(key, "MSITESTVAR2", NULL, NULL, NULL, NULL);
6376     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6377 
6378     type = REG_NONE;
6379     buffer[0] = 0;
6380     size = sizeof(buffer);
6381     res = RegQueryValueExA(key, "MSITESTVAR3", NULL, &type, (LPBYTE)buffer, &size);
6382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6383     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6384     ok(!lstrcmpA(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
6385     RegDeleteValueA(key, "MSITESTVAR3");
6386 
6387     res = RegQueryValueExA(key, "MSITESTVAR4", NULL, NULL, NULL, NULL);
6388     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6389 
6390     type = REG_NONE;
6391     buffer[0] = 0;
6392     size = sizeof(buffer);
6393     res = RegQueryValueExA(key, "MSITESTVAR5", NULL, &type, (LPBYTE)buffer, &size);
6394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6395     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6396     ok(!lstrcmpA(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
6397     RegDeleteValueA(key, "MSITESTVAR5");
6398 
6399     type = REG_NONE;
6400     buffer[0] = 0;
6401     size = sizeof(buffer);
6402     res = RegQueryValueExA(key, "MSITESTVAR6", NULL, &type, (LPBYTE)buffer, &size);
6403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6404     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6405     ok(!lstrcmpA(buffer, "2"), "expected \"2\", got \"%s\"\n", buffer);
6406     RegDeleteValueA(key, "MSITESTVAR6");
6407 
6408     type = REG_NONE;
6409     buffer[0] = 0;
6410     size = sizeof(buffer);
6411     res = RegQueryValueExA(key, "MSITESTVAR7", NULL, &type, (LPBYTE)buffer, &size);
6412     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6413     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6414     ok(!lstrcmpA(buffer, "2"), "expected \"2\", got \"%s\"\n", buffer);
6415     RegDeleteValueA(key, "MSITESTVAR7");
6416 
6417     type = REG_NONE;
6418     buffer[0] = 0;
6419     size = sizeof(buffer);
6420     res = RegQueryValueExA(key, "MSITESTVAR8", NULL, &type, (LPBYTE)buffer, &size);
6421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6422     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6423     ok(!lstrcmpA(buffer, "2;0"), "expected \"2;0\", got \"%s\"\n", buffer);
6424     RegDeleteValueA(key, "MSITESTVAR8");
6425 
6426     type = REG_NONE;
6427     buffer[0] = 0;
6428     size = sizeof(buffer);
6429     res = RegQueryValueExA(key, "MSITESTVAR9", NULL, &type, (LPBYTE)buffer, &size);
6430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6431     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6432     ok(!lstrcmpA(buffer, "0;2"), "expected \"0;2\", got \"%s\"\n", buffer);
6433     RegDeleteValueA(key, "MSITESTVAR9");
6434 
6435     type = REG_NONE;
6436     buffer[0] = 0;
6437     size = sizeof(buffer);
6438     res = RegQueryValueExA(key, "MSITESTVAR10", NULL, &type, (LPBYTE)buffer, &size);
6439     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6440 
6441     type = REG_NONE;
6442     buffer[0] = 0;
6443     size = sizeof(buffer);
6444     res = RegQueryValueExA(key, "MSITESTVAR11", NULL, &type, (LPBYTE)buffer, &size);
6445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6446     ok(type == REG_SZ, "expected REG_SZ, got %u\n", type);
6447     ok(!lstrcmpA(buffer, "1"), "expected \"1\", got \"%s\"\n", buffer);
6448     RegDeleteValueA(key, "MSITESTVAR11");
6449 
6450     ok(!delete_pf("msitest\\envvar.txt", TRUE), "file not removed\n");
6451     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6452 
6453 error:
6454     RegDeleteValueA(key, "MSITESTVAR1");
6455     RegDeleteValueA(key, "MSITESTVAR2");
6456     RegDeleteValueA(key, "MSITESTVAR3");
6457     RegDeleteValueA(key, "MSITESTVAR4");
6458     RegDeleteValueA(key, "MSITESTVAR5");
6459     RegDeleteValueA(key, "MSITESTVAR6");
6460     RegDeleteValueA(key, "MSITESTVAR7");
6461     RegDeleteValueA(key, "MSITESTVAR8");
6462     RegDeleteValueA(key, "MSITESTVAR9");
6463     RegDeleteValueA(key, "MSITESTVAR10");
6464     RegDeleteValueA(key, "MSITESTVAR11");
6465     RegCloseKey(key);
6466 
6467     DeleteFileA("msitest\\envvar.txt");
6468     delete_test_files();
6469     DeleteFileA(msifile);
6470 }
6471 
6472 static void test_register_class_info(void)
6473 {
6474     UINT r;
6475     LONG res;
6476     HKEY hkey;
6477 
6478     if (is_process_limited())
6479     {
6480         skip("process is limited\n");
6481         return;
6482     }
6483 
6484     create_test_files();
6485     create_file("msitest\\class.txt", 1000);
6486     create_database(msifile, rci_tables, sizeof(rci_tables) / sizeof(msi_table));
6487 
6488     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6489 
6490     r = MsiInstallProductA(msifile, NULL);
6491     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6492     {
6493         skip("Not enough rights to perform tests\n");
6494         goto error;
6495     }
6496     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6497 
6498     if (is_64bit)
6499         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6500     else
6501         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6502     ok(res == ERROR_SUCCESS, "key not created\n");
6503     RegCloseKey(hkey);
6504 
6505     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6506     ok(res == ERROR_SUCCESS, "key not created\n");
6507     RegCloseKey(hkey);
6508 
6509     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
6510     ok(res == ERROR_SUCCESS, "key not created\n");
6511     RegCloseKey(hkey);
6512 
6513     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6514     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6515 
6516     if (is_64bit)
6517         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6518     else
6519         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6520     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6521 
6522     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "FileType\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6523     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6524 
6525     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &hkey);
6526     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6527 
6528     ok(!delete_pf("msitest\\class.txt", TRUE), "file not removed\n");
6529     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6530 
6531 error:
6532     DeleteFileA("msitest\\class.txt");
6533     delete_test_files();
6534     DeleteFileA(msifile);
6535 }
6536 
6537 static void test_register_extension_info(void)
6538 {
6539     UINT r;
6540     LONG res;
6541     HKEY hkey;
6542 
6543     if (is_process_limited())
6544     {
6545         skip("process is limited\n");
6546         return;
6547     }
6548 
6549     create_test_files();
6550     create_file("msitest\\extension.txt", 1000);
6551     create_database(msifile, rei_tables, sizeof(rei_tables) / sizeof(msi_table));
6552 
6553     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6554 
6555     r = MsiInstallProductA(msifile, NULL);
6556     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6557     {
6558         skip("Not enough rights to perform tests\n");
6559         goto error;
6560     }
6561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6562 
6563     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
6564     ok(res == ERROR_SUCCESS, "key not created\n");
6565     RegCloseKey(hkey);
6566 
6567     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &hkey);
6568     ok(res == ERROR_SUCCESS, "key not created\n");
6569     RegCloseKey(hkey);
6570 
6571     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6573 
6574     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &hkey);
6575     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6576 
6577     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1", &hkey);
6578     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6579 
6580     ok(!delete_pf("msitest\\extension.txt", TRUE), "file not removed\n");
6581     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6582 
6583 error:
6584     DeleteFileA("msitest\\extension.txt");
6585     delete_test_files();
6586     DeleteFileA(msifile);
6587 }
6588 
6589 static void test_register_progid_info(void)
6590 {
6591     UINT r;
6592     LONG res;
6593     HKEY hkey;
6594 
6595     if (is_process_limited())
6596     {
6597         skip("process is limited\n");
6598         return;
6599     }
6600 
6601     create_test_files();
6602     create_file("msitest\\progid.txt", 1000);
6603     create_database(msifile, rpi_tables, sizeof(rpi_tables) / sizeof(msi_table));
6604 
6605     res = RegCreateKeyExA(HKEY_CLASSES_ROOT, "Winetest.Orphaned", 0, NULL, 0,
6606                           KEY_ALL_ACCESS, NULL, &hkey, NULL);
6607     ok(res == ERROR_SUCCESS, "key not created\n");
6608     RegCloseKey(hkey);
6609 
6610     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6611 
6612     r = MsiInstallProductA(msifile, NULL);
6613     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6614     {
6615         skip("Not enough rights to perform tests\n");
6616         goto error;
6617     }
6618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6619 
6620     if (is_64bit)
6621         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6622     else
6623         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6624     ok(res == ERROR_SUCCESS, "key not created\n");
6625     RegCloseKey(hkey);
6626 
6627     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.1", &hkey);
6628     ok(res == ERROR_SUCCESS, "key not created\n");
6629     RegCloseKey(hkey);
6630 
6631     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class", &hkey);
6632     ok(res == ERROR_SUCCESS, "key not created\n");
6633     RegCloseKey(hkey);
6634 
6635     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.2", &hkey);
6636     ok(res == ERROR_SUCCESS, "key not created\n");
6637     RegCloseKey(hkey);
6638 
6639     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.VerClass.1", &hkey);
6640     ok(res == ERROR_SUCCESS, "key not created\n");
6641     RegCloseKey(hkey);
6642 
6643     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.VerClass", &hkey);
6644     ok(res == ERROR_SUCCESS, "key not created\n");
6645     RegCloseKey(hkey);
6646 
6647     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.NoProgIdClass.1", &hkey);
6648     ok(res == ERROR_FILE_NOT_FOUND, "key created\n");
6649     if (res == ERROR_SUCCESS) RegCloseKey(hkey);
6650 
6651     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.NoProgIdClass", &hkey);
6652     ok(res == ERROR_FILE_NOT_FOUND, "key created\n");
6653 
6654     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Orphaned", &hkey);
6655     ok(res == ERROR_SUCCESS, "key deleted\n");
6656     if (res == ERROR_SUCCESS) RegCloseKey(hkey);
6657 
6658     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Orphaned2", &hkey);
6659     ok(res == ERROR_FILE_NOT_FOUND, "key created\n");
6660 
6661     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Extension", &hkey);
6662     ok(res == ERROR_SUCCESS, "key not created\n");
6663     RegCloseKey(hkey);
6664 
6665     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6666     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6667 
6668     if (is_64bit)
6669         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Wow6432Node\\CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6670     else
6671         res = RegOpenKeyA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}", &hkey);
6672     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6673 
6674     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.1", &hkey);
6675     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6676 
6677     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class", &hkey);
6678     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6679 
6680     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.2", &hkey);
6681     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6682 
6683     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.VerClass.1", &hkey);
6684     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6685 
6686     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.VerClass", &hkey);
6687     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6688 
6689     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.NoProgIdClass.1", &hkey);
6690     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6691 
6692     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.NoProgIdClass", &hkey);
6693     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6694 
6695     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Orphaned", &hkey);
6696     ok(res == ERROR_SUCCESS, "key deleted\n");
6697     if (res == ERROR_SUCCESS) RegCloseKey(hkey);
6698 
6699     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Orphaned2", &hkey);
6700     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6701 
6702     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Extension", &hkey);
6703     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6704 
6705     ok(!delete_pf("msitest\\progid.txt", TRUE), "file not removed\n");
6706     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6707 
6708 error:
6709     DeleteFileA("msitest\\progid.txt");
6710     delete_test_files();
6711     DeleteFileA(msifile);
6712     RegDeleteKeyA(HKEY_CLASSES_ROOT, "Winetest.Orphaned");
6713 }
6714 
6715 static void test_register_mime_info(void)
6716 {
6717     UINT r;
6718     LONG res;
6719     HKEY hkey;
6720 
6721     if (is_process_limited())
6722     {
6723         skip("process is limited\n");
6724         return;
6725     }
6726 
6727     create_test_files();
6728     create_file("msitest\\mime.txt", 1000);
6729     create_database(msifile, rmi_tables, sizeof(rmi_tables) / sizeof(msi_table));
6730 
6731     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6732 
6733     r = MsiInstallProductA(msifile, NULL);
6734     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6735     {
6736         skip("Not enough rights to perform tests\n");
6737         goto error;
6738     }
6739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6740 
6741     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
6742     ok(res == ERROR_SUCCESS, "key not created\n");
6743     RegCloseKey(hkey);
6744 
6745     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6747 
6748     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &hkey);
6749     ok(res == ERROR_FILE_NOT_FOUND, "key not removed\n");
6750 
6751     ok(!delete_pf("msitest\\mime.txt", TRUE), "file not removed\n");
6752     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
6753 
6754 error:
6755     DeleteFileA("msitest\\mime.txt");
6756     delete_test_files();
6757     DeleteFileA(msifile);
6758 }
6759 
6760 static void test_publish_assemblies(void)
6761 {
6762     static const char manifest[] =
6763         "<assemblyIdentity type=\"win32\" name=\"Wine.Win32.Assembly\" "
6764         "version=\"1.0.0.0\" publicKeyToken=\"abcdef0123456789\" "
6765         "processorArchitecture=\"x86\"/>";
6766     static const char manifest_local[] =
6767         "<assemblyIdentity type=\"win32\" name=\"Wine.Win32.Local.Assembly\" "
6768         "version=\"1.0.0.0\" publicKeyToken=\"abcdef0123456789\" "
6769         "processorArchitecture=\"x86\"/>";
6770     static const char classes_path_dotnet[] =
6771         "Installer\\Assemblies\\Global";
6772     static const char classes_path_dotnet_local[] =
6773         "Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt";
6774     static const char classes_path_dotnet_local_wow64[] =
6775         "Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt";
6776     static const char classes_path_win32[] =
6777         "Installer\\Win32Assemblies\\Global";
6778     static const char classes_path_win32_local[] =
6779         "Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt";
6780     static const char classes_path_win32_local_wow64[] =
6781         "Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt";
6782     static const char path_dotnet[] =
6783         "Software\\Microsoft\\Installer\\Assemblies\\Global";
6784     static const char path_dotnet_local[] =
6785         "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files|msitest|application_dotnet.txt";
6786     static const char path_dotnet_local_wow64[] =
6787         "Software\\Microsoft\\Installer\\Assemblies\\C:|Program Files (x86)|msitest|application_dotnet.txt";
6788     static const char path_win32[] =
6789         "Software\\Microsoft\\Installer\\Win32Assemblies\\Global";
6790     static const char path_win32_local[] =
6791         "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files|msitest|application_win32.txt";
6792     static const char path_win32_local_wow64[] =
6793         "Software\\Microsoft\\Installer\\Win32Assemblies\\C:|Program Files (x86)|msitest|application_win32.txt";
6794     static const char name_dotnet[] =
6795         "Wine.Dotnet.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\","
6796         "version=\"1.0.0.0\",culture=\"neutral\"";
6797     static const char name_dotnet_local[] =
6798         "Wine.Dotnet.Local.Assembly,processorArchitecture=\"MSIL\",publicKeyToken=\"abcdef0123456789\","
6799         "version=\"1.0.0.0\",culture=\"neutral\"";
6800     static const char name_win32[] =
6801         "Wine.Win32.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\","
6802         "type=\"win32\",version=\"1.0.0.0\"";
6803     static const char name_win32_local[] =
6804         "Wine.Win32.Local.Assembly,processorArchitecture=\"x86\",publicKeyToken=\"abcdef0123456789\","
6805         "type=\"win32\",version=\"1.0.0.0\"";
6806     UINT r;
6807     LONG res;
6808     HKEY hkey;
6809     const char *path;
6810     int access;
6811 
6812     if (is_process_limited())
6813     {
6814         skip("process is limited\n");
6815         return;
6816     }
6817 
6818     create_test_files();
6819     create_file("msitest\\win32.txt", 1000);
6820     create_file("msitest\\win32_local.txt", 1000);
6821     create_file("msitest\\dotnet.txt", 1000);
6822     create_file("msitest\\dotnet_local.txt", 1000);
6823     create_file_data("msitest\\manifest.txt", manifest, 0);
6824     create_file_data("msitest\\manifest_local.txt", manifest_local, 0);
6825     create_file("msitest\\application_win32.txt", 1000);
6826     create_file("msitest\\application_dotnet.txt", 1000);
6827     create_database(msifile, pa_tables, sizeof(pa_tables) / sizeof(msi_table));
6828 
6829     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6830 
6831     r = MsiInstallProductA(msifile, NULL);
6832     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6833     {
6834         skip("Not enough rights to perform tests\n");
6835         goto done;
6836     }
6837     if (r == ERROR_INSTALL_FAILURE)
6838     {
6839         skip("No support for installing side-by-side assemblies\n");
6840         goto done;
6841     }
6842     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6843 
6844     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey);
6845     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6846     CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
6847     RegCloseKey(hkey);
6848 
6849     path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local;
6850     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
6851     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6852     CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox");
6853     RegCloseKey(hkey);
6854 
6855     res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey);
6856     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
6857        "Expected ERROR_SUCCESS, got %d\n", res);
6858     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%");
6859     RegCloseKey(hkey);
6860 
6861     path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local;
6862     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
6863     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
6864        "Expected ERROR_SUCCESS, got %d\n", res);
6865     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!");
6866     RegCloseKey(hkey);
6867 
6868     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6870 
6871     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &hkey);
6872     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
6873     if (res == ERROR_SUCCESS)
6874     {
6875         res = RegDeleteValueA(hkey, name_dotnet);
6876         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6877         RegCloseKey(hkey);
6878     }
6879 
6880     path = (is_wow64 || is_64bit) ? path_dotnet_local_wow64 : path_dotnet_local;
6881     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
6882     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6883 
6884     res = RegOpenKeyA(HKEY_CURRENT_USER, path_win32, &hkey);
6885     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
6886     if (res == ERROR_SUCCESS)
6887     {
6888         res = RegDeleteValueA(hkey, name_win32);
6889         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6890         RegCloseKey(hkey);
6891     }
6892 
6893     path = (is_wow64 || is_64bit) ? path_win32_local_wow64 : path_win32_local;
6894     res = RegOpenKeyA(HKEY_CURRENT_USER, path, &hkey);
6895     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6896 
6897     r = MsiInstallProductA(msifile, "ALLUSERS=1");
6898     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6899 
6900     access = KEY_QUERY_VALUE;
6901     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey);
6902     if (res == ERROR_FILE_NOT_FOUND && is_wow64) /* Vista WOW64 */
6903     {
6904         trace("Using 64-bit registry view for HKCR\\Installer\n");
6905         access = KEY_QUERY_VALUE | KEY_WOW64_64KEY;
6906         res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_dotnet, 0, access, &hkey);
6907     }
6908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6909     CHECK_REG_STR(hkey, name_dotnet, "rcHQPHq?CA@Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
6910     RegCloseKey(hkey);
6911 
6912     path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local;
6913     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey);
6914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6915     CHECK_REG_STR(hkey, name_dotnet_local, "rcHQPHq?CA@Uv-XqMI1e>LF,8A?0d.AW@vcZ$Cgox");
6916     RegCloseKey(hkey);
6917 
6918     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, classes_path_win32, 0, access, &hkey);
6919     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
6920        "Expected ERROR_SUCCESS, got %d\n", res);
6921     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32, "rcHQPHq?CA@Uv-XqMI1e>}NJjwR'%D9v1p!v{WV(%");
6922     RegCloseKey(hkey);
6923 
6924     path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local;
6925     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, path, 0, access, &hkey);
6926     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND /* win2k without sxs support */,
6927        "Expected ERROR_SUCCESS, got %d\n", res);
6928     if (res == ERROR_SUCCESS) CHECK_REG_STR(hkey, name_win32_local, "rcHQPHq?CA@Uv-XqMI1e>C)Uvlj*53A)u(QQ9=)X!");
6929     RegCloseKey(hkey);
6930 
6931     r = MsiInstallProductA(msifile, "REMOVE=ALL ALLUSERS=1");
6932     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6933 
6934     res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_dotnet, &hkey);
6935     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
6936     if (res == ERROR_SUCCESS)
6937     {
6938         res = RegDeleteValueA(hkey, name_dotnet);
6939         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6940         RegCloseKey(hkey);
6941     }
6942 
6943     path = (is_wow64 || is_64bit) ? classes_path_dotnet_local_wow64 : classes_path_dotnet_local;
6944     res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey);
6945     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6946 
6947     res = RegOpenKeyA(HKEY_CLASSES_ROOT, classes_path_win32, &hkey);
6948     ok(res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
6949     if (res == ERROR_SUCCESS)
6950     {
6951         res = RegDeleteValueA(hkey, name_win32);
6952         ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6953         RegCloseKey(hkey);
6954     }
6955 
6956     path = (is_wow64 || is_64bit) ? classes_path_win32_local_wow64 : classes_path_win32_local;
6957     res = RegOpenKeyA(HKEY_CLASSES_ROOT, path, &hkey);
6958     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
6959 
6960 done:
6961     DeleteFileA("msitest\\win32.txt");
6962     DeleteFileA("msitest\\win32_local.txt");
6963     DeleteFileA("msitest\\dotnet.txt");
6964     DeleteFileA("msitest\\dotnet_local.txt");
6965     DeleteFileA("msitest\\manifest.txt");
6966     DeleteFileA("msitest\\manifest_local.txt");
6967     DeleteFileA("msitest\\application_win32.txt");
6968     DeleteFileA("msitest\\application_dotnet.txt");
6969     delete_test_files();
6970     DeleteFileA(msifile);
6971 }
6972 
6973 static void test_remove_existing_products(void)
6974 {
6975     UINT r;
6976 
6977     if (is_process_limited())
6978     {
6979         skip("process is limited\n");
6980         return;
6981     }
6982 
6983     create_test_files();
6984     create_file("msitest\\rep.txt", 1000);
6985     create_database(msifile, rep_tables, sizeof(rep_tables) / sizeof(msi_table));
6986 
6987     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
6988 
6989     r = MsiInstallProductA(msifile, NULL);
6990     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
6991     {
6992         skip("Not enough rights to perform tests\n");
6993         goto error;
6994     }
6995     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6996 
6997     r = MsiInstallProductA(msifile, "REMOVE=ALL");
6998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
6999 
7000     ok(!delete_pf("msitest\\rep.txt", TRUE), "file not removed\n");
7001     ok(!delete_pf("msitest", FALSE), "directory not removed\n");
7002 
7003 error:
7004     DeleteFileA("msitest\\rep.txt");
7005     delete_test_files();
7006     DeleteFileA(msifile);
7007 }
7008 
7009 START_TEST(action)
7010 {
7011     DWORD len;
7012     char temp_path[MAX_PATH], prev_path[MAX_PATH], log_file[MAX_PATH];
7013     STATEMGRSTATUS status;
7014     BOOL ret = FALSE;
7015 
7016     init_functionpointers();
7017 
7018     if (pIsWow64Process)
7019         pIsWow64Process(GetCurrentProcess(), &is_wow64);
7020 
7021     GetCurrentDirectoryA(MAX_PATH, prev_path);
7022     GetTempPathA(MAX_PATH, temp_path);
7023     SetCurrentDirectoryA(temp_path);
7024 
7025     lstrcpyA(CURR_DIR, temp_path);
7026     len = lstrlenA(CURR_DIR);
7027 
7028     if(len && (CURR_DIR[len - 1] == '\\'))
7029         CURR_DIR[len - 1] = 0;
7030 
7031     ok(get_system_dirs(), "failed to retrieve system dirs\n");
7032     ok(get_user_dirs(), "failed to retrieve user dirs\n");
7033 
7034     /* Create a restore point ourselves so we circumvent the multitude of restore points
7035      * that would have been created by all the installation and removal tests.
7036      *
7037      * This is not needed on version 5.0 where setting MSIFASTINSTALL prevents the
7038      * creation of restore points.
7039      */
7040     if (pSRSetRestorePointA && !pMsiGetComponentPathExA)
7041     {
7042         memset(&status, 0, sizeof(status));
7043         ret = notify_system_change(BEGIN_NESTED_SYSTEM_CHANGE, &status);
7044     }
7045 
7046     /* Create only one log file and don't append. We have to pass something
7047      * for the log mode for this to work. The logfile needs to have an absolute
7048      * path otherwise we still end up with some extra logfiles as some tests
7049      * change the current directory.
7050      */
7051     lstrcpyA(log_file, temp_path);
7052     lstrcatA(log_file, "\\msitest.log");
7053     MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0);
7054 
7055     test_register_product();
7056     test_publish_product();
7057     test_publish_features();
7058     test_register_user();
7059     test_process_components();
7060     test_publish();
7061     test_publish_sourcelist();
7062     test_remove_files();
7063     test_move_files();
7064     test_duplicate_files();
7065     test_write_registry_values();
7066     test_envvar();
7067     test_create_remove_folder();
7068     test_start_stop_services();
7069     test_delete_services();
7070     test_install_services();
7071     test_self_registration();
7072     test_register_font();
7073     test_validate_product_id();
7074     test_install_remove_odbc();
7075     test_register_typelib();
7076     test_create_remove_shortcut();
7077     test_publish_components();
7078     test_remove_duplicate_files();
7079     test_remove_registry_values();
7080     test_find_related_products();
7081     test_remove_ini_values();
7082     test_remove_env_strings();
7083     test_register_class_info();
7084     test_register_extension_info();
7085     test_register_progid_info();
7086     test_register_mime_info();
7087     test_publish_assemblies();
7088     test_remove_existing_products();
7089 
7090     DeleteFileA(log_file);
7091 
7092     if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret)
7093     {
7094         ret = notify_system_change(END_NESTED_SYSTEM_CHANGE, &status);
7095         if (ret)
7096             remove_restore_point(status.llSequenceNumber);
7097     }
7098     FreeLibrary(hsrclient);
7099 
7100     SetCurrentDirectoryA(prev_path);
7101 }
7102