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