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