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