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