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