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